aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c2
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c4897
-rw-r--r--drivers/net/bnx2x/bnx2x_link.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c2
4 files changed, 2475 insertions, 2428 deletions
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index becfd9eb8905..dbcfa7a5618f 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -1282,7 +1282,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
1282 /* check the loopback mode */ 1282 /* check the loopback mode */
1283 switch (loopback_mode) { 1283 switch (loopback_mode) {
1284 case BNX2X_PHY_LOOPBACK: 1284 case BNX2X_PHY_LOOPBACK:
1285 if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10) 1285 if (bp->link_params.loopback_mode != LOOPBACK_XGXS)
1286 return -EINVAL; 1286 return -EINVAL;
1287 break; 1287 break;
1288 case BNX2X_MAC_LOOPBACK: 1288 case BNX2X_MAC_LOOPBACK:
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index fcf99bf62fa1..e2509aab9f0d 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -181,20 +181,6 @@
181 (_bank + (_addr & 0xf)), \ 181 (_bank + (_addr & 0xf)), \
182 _val) 182 _val)
183 183
184static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
185{
186 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
187
188 /* Set Clause 22 */
189 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
190 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
191 udelay(500);
192 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
193 udelay(500);
194 /* Set Clause 45 */
195 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
196}
197
198static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) 184static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
199{ 185{
200 u32 val = REG_RD(bp, reg); 186 u32 val = REG_RD(bp, reg);
@@ -510,175 +496,6 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
510 return 0; 496 return 0;
511} 497}
512 498
513static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
514{
515 u32 val;
516
517 DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
518
519 val = SERDES_RESET_BITS << (port*16);
520
521 /* reset and unreset the SerDes/XGXS */
522 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
523 udelay(500);
524 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
525
526 bnx2x_set_serdes_access(bp, port);
527
528 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
529 port*0x10,
530 DEFAULT_PHY_DEV_ADDR);
531}
532
533static void bnx2x_xgxs_deassert(struct link_params *params)
534{
535 struct bnx2x *bp = params->bp;
536 u8 port;
537 u32 val;
538 DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
539 port = params->port;
540
541 val = XGXS_RESET_BITS << (port*16);
542
543 /* reset and unreset the SerDes/XGXS */
544 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
545 udelay(500);
546 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
547
548 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
549 port*0x18, 0);
550 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
551 params->phy[INT_PHY].def_md_devad);
552}
553void bnx2x_link_status_update(struct link_params *params,
554 struct link_vars *vars)
555{
556 struct bnx2x *bp = params->bp;
557 u8 link_10g;
558 u8 port = params->port;
559
560 if (params->switch_cfg == SWITCH_CFG_1G)
561 vars->phy_flags = PHY_SERDES_FLAG;
562 else
563 vars->phy_flags = PHY_XGXS_FLAG;
564 vars->link_status = REG_RD(bp, params->shmem_base +
565 offsetof(struct shmem_region,
566 port_mb[port].link_status));
567
568 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
569
570 if (vars->link_up) {
571 DP(NETIF_MSG_LINK, "phy link up\n");
572
573 vars->phy_link_up = 1;
574 vars->duplex = DUPLEX_FULL;
575 switch (vars->link_status &
576 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
577 case LINK_10THD:
578 vars->duplex = DUPLEX_HALF;
579 /* fall thru */
580 case LINK_10TFD:
581 vars->line_speed = SPEED_10;
582 break;
583
584 case LINK_100TXHD:
585 vars->duplex = DUPLEX_HALF;
586 /* fall thru */
587 case LINK_100T4:
588 case LINK_100TXFD:
589 vars->line_speed = SPEED_100;
590 break;
591
592 case LINK_1000THD:
593 vars->duplex = DUPLEX_HALF;
594 /* fall thru */
595 case LINK_1000TFD:
596 vars->line_speed = SPEED_1000;
597 break;
598
599 case LINK_2500THD:
600 vars->duplex = DUPLEX_HALF;
601 /* fall thru */
602 case LINK_2500TFD:
603 vars->line_speed = SPEED_2500;
604 break;
605
606 case LINK_10GTFD:
607 vars->line_speed = SPEED_10000;
608 break;
609
610 case LINK_12GTFD:
611 vars->line_speed = SPEED_12000;
612 break;
613
614 case LINK_12_5GTFD:
615 vars->line_speed = SPEED_12500;
616 break;
617
618 case LINK_13GTFD:
619 vars->line_speed = SPEED_13000;
620 break;
621
622 case LINK_15GTFD:
623 vars->line_speed = SPEED_15000;
624 break;
625
626 case LINK_16GTFD:
627 vars->line_speed = SPEED_16000;
628 break;
629
630 default:
631 break;
632 }
633
634 vars->flow_ctrl = 0;
635 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
636 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
637
638 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
639 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
640
641 if (!vars->flow_ctrl)
642 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
643
644 if (vars->line_speed &&
645 ((vars->line_speed == SPEED_10) ||
646 (vars->line_speed == SPEED_100))) {
647 vars->phy_flags |= PHY_SGMII_FLAG;
648 } else {
649 vars->phy_flags &= ~PHY_SGMII_FLAG;
650 }
651
652 /* anything 10 and over uses the bmac */
653 link_10g = ((vars->line_speed == SPEED_10000) ||
654 (vars->line_speed == SPEED_12000) ||
655 (vars->line_speed == SPEED_12500) ||
656 (vars->line_speed == SPEED_13000) ||
657 (vars->line_speed == SPEED_15000) ||
658 (vars->line_speed == SPEED_16000));
659 if (link_10g)
660 vars->mac_type = MAC_TYPE_BMAC;
661 else
662 vars->mac_type = MAC_TYPE_EMAC;
663
664 } else { /* link down */
665 DP(NETIF_MSG_LINK, "phy link down\n");
666
667 vars->phy_link_up = 0;
668
669 vars->line_speed = 0;
670 vars->duplex = DUPLEX_FULL;
671 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
672
673 /* indicate no mac active */
674 vars->mac_type = MAC_TYPE_NONE;
675 }
676
677 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
678 vars->link_status, vars->phy_link_up);
679 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
680 vars->line_speed, vars->duplex, vars->flow_ctrl);
681}
682 499
683static void bnx2x_update_mng(struct link_params *params, u32 link_status) 500static void bnx2x_update_mng(struct link_params *params, u32 link_status)
684{ 501{
@@ -1023,6 +840,196 @@ static void bnx2x_set_aer_mmd(struct link_params *params,
1023 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset); 840 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
1024} 841}
1025 842
843/******************************************************************/
844/* Internal phy section */
845/******************************************************************/
846
847static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
848{
849 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
850
851 /* Set Clause 22 */
852 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
853 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
854 udelay(500);
855 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
856 udelay(500);
857 /* Set Clause 45 */
858 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
859}
860
861static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
862{
863 u32 val;
864
865 DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
866
867 val = SERDES_RESET_BITS << (port*16);
868
869 /* reset and unreset the SerDes/XGXS */
870 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
871 udelay(500);
872 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
873
874 bnx2x_set_serdes_access(bp, port);
875
876 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
877 port*0x10,
878 DEFAULT_PHY_DEV_ADDR);
879}
880
881static void bnx2x_xgxs_deassert(struct link_params *params)
882{
883 struct bnx2x *bp = params->bp;
884 u8 port;
885 u32 val;
886 DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
887 port = params->port;
888
889 val = XGXS_RESET_BITS << (port*16);
890
891 /* reset and unreset the SerDes/XGXS */
892 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
893 udelay(500);
894 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
895
896 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
897 port*0x18, 0);
898 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
899 params->phy[INT_PHY].def_md_devad);
900}
901
902void bnx2x_link_status_update(struct link_params *params,
903 struct link_vars *vars)
904{
905 struct bnx2x *bp = params->bp;
906 u8 link_10g;
907 u8 port = params->port;
908
909 if (params->switch_cfg == SWITCH_CFG_1G)
910 vars->phy_flags = PHY_SERDES_FLAG;
911 else
912 vars->phy_flags = PHY_XGXS_FLAG;
913 vars->link_status = REG_RD(bp, params->shmem_base +
914 offsetof(struct shmem_region,
915 port_mb[port].link_status));
916
917 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
918
919 if (vars->link_up) {
920 DP(NETIF_MSG_LINK, "phy link up\n");
921
922 vars->phy_link_up = 1;
923 vars->duplex = DUPLEX_FULL;
924 switch (vars->link_status &
925 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
926 case LINK_10THD:
927 vars->duplex = DUPLEX_HALF;
928 /* fall thru */
929 case LINK_10TFD:
930 vars->line_speed = SPEED_10;
931 break;
932
933 case LINK_100TXHD:
934 vars->duplex = DUPLEX_HALF;
935 /* fall thru */
936 case LINK_100T4:
937 case LINK_100TXFD:
938 vars->line_speed = SPEED_100;
939 break;
940
941 case LINK_1000THD:
942 vars->duplex = DUPLEX_HALF;
943 /* fall thru */
944 case LINK_1000TFD:
945 vars->line_speed = SPEED_1000;
946 break;
947
948 case LINK_2500THD:
949 vars->duplex = DUPLEX_HALF;
950 /* fall thru */
951 case LINK_2500TFD:
952 vars->line_speed = SPEED_2500;
953 break;
954
955 case LINK_10GTFD:
956 vars->line_speed = SPEED_10000;
957 break;
958
959 case LINK_12GTFD:
960 vars->line_speed = SPEED_12000;
961 break;
962
963 case LINK_12_5GTFD:
964 vars->line_speed = SPEED_12500;
965 break;
966
967 case LINK_13GTFD:
968 vars->line_speed = SPEED_13000;
969 break;
970
971 case LINK_15GTFD:
972 vars->line_speed = SPEED_15000;
973 break;
974
975 case LINK_16GTFD:
976 vars->line_speed = SPEED_16000;
977 break;
978
979 default:
980 break;
981 }
982
983 vars->flow_ctrl = 0;
984 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
985 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
986
987 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
988 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
989
990 if (!vars->flow_ctrl)
991 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
992
993 if (vars->line_speed &&
994 ((vars->line_speed == SPEED_10) ||
995 (vars->line_speed == SPEED_100))) {
996 vars->phy_flags |= PHY_SGMII_FLAG;
997 } else {
998 vars->phy_flags &= ~PHY_SGMII_FLAG;
999 }
1000
1001 /* anything 10 and over uses the bmac */
1002 link_10g = ((vars->line_speed == SPEED_10000) ||
1003 (vars->line_speed == SPEED_12000) ||
1004 (vars->line_speed == SPEED_12500) ||
1005 (vars->line_speed == SPEED_13000) ||
1006 (vars->line_speed == SPEED_15000) ||
1007 (vars->line_speed == SPEED_16000));
1008 if (link_10g)
1009 vars->mac_type = MAC_TYPE_BMAC;
1010 else
1011 vars->mac_type = MAC_TYPE_EMAC;
1012
1013 } else { /* link down */
1014 DP(NETIF_MSG_LINK, "phy link down\n");
1015
1016 vars->phy_link_up = 0;
1017
1018 vars->line_speed = 0;
1019 vars->duplex = DUPLEX_FULL;
1020 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1021
1022 /* indicate no mac active */
1023 vars->mac_type = MAC_TYPE_NONE;
1024 }
1025
1026 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
1027 vars->link_status, vars->phy_link_up);
1028 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
1029 vars->line_speed, vars->duplex, vars->flow_ctrl);
1030}
1031
1032
1026static void bnx2x_set_master_ln(struct link_params *params, 1033static void bnx2x_set_master_ln(struct link_params *params,
1027 struct bnx2x_phy *phy) 1034 struct bnx2x_phy *phy)
1028{ 1035{
@@ -1271,9 +1278,9 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
1271 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; 1278 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1272 1279
1273 CL45_WR_OVER_CL22(bp, phy, 1280 CL45_WR_OVER_CL22(bp, phy,
1274 MDIO_REG_BANK_CL73_IEEEB1, 1281 MDIO_REG_BANK_CL73_IEEEB1,
1275 MDIO_CL73_IEEEB1_AN_ADV2, 1282 MDIO_CL73_IEEEB1_AN_ADV2,
1276 reg_val); 1283 reg_val);
1277 1284
1278 /* CL73 Autoneg Enabled */ 1285 /* CL73 Autoneg Enabled */
1279 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN; 1286 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
@@ -1560,42 +1567,6 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1560 1567
1561} 1568}
1562 1569
1563static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
1564 struct link_params *params,
1565 struct link_vars *vars)
1566{
1567 struct bnx2x *bp = params->bp;
1568 u16 ld_pause; /* local */
1569 u16 lp_pause; /* link partner */
1570 u16 pause_result;
1571 u8 ret = 0;
1572 /* read twice */
1573
1574 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1575
1576 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
1577 vars->flow_ctrl = phy->req_flow_ctrl;
1578 else if (phy->req_line_speed != SPEED_AUTO_NEG)
1579 vars->flow_ctrl = params->req_fc_auto_adv;
1580 else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
1581 ret = 1;
1582 bnx2x_cl45_read(bp, phy,
1583 MDIO_AN_DEVAD,
1584 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1585 bnx2x_cl45_read(bp, phy,
1586 MDIO_AN_DEVAD,
1587 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1588 pause_result = (ld_pause &
1589 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1590 pause_result |= (lp_pause &
1591 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1592 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
1593 pause_result);
1594 bnx2x_pause_resolve(vars, pause_result);
1595 }
1596 return ret;
1597}
1598
1599static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, 1570static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
1600 struct link_params *params) 1571 struct link_params *params)
1601{ 1572{
@@ -2004,6 +1975,79 @@ static u8 bnx2x_emac_program(struct link_params *params,
2004 return 0; 1975 return 0;
2005} 1976}
2006 1977
1978static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
1979 struct link_params *params)
1980{
1981
1982 u16 bank, i = 0;
1983 struct bnx2x *bp = params->bp;
1984
1985 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
1986 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
1987 CL45_WR_OVER_CL22(bp, phy,
1988 bank,
1989 MDIO_RX0_RX_EQ_BOOST,
1990 phy->rx_preemphasis[i]);
1991 }
1992
1993 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
1994 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
1995 CL45_WR_OVER_CL22(bp, phy,
1996 bank,
1997 MDIO_TX0_TX_DRIVER,
1998 phy->tx_preemphasis[i]);
1999 }
2000}
2001
2002static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
2003 struct link_params *params,
2004 struct link_vars *vars)
2005{
2006 struct bnx2x *bp = params->bp;
2007 u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
2008 (params->loopback_mode == LOOPBACK_XGXS));
2009 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2010 if (SINGLE_MEDIA_DIRECT(params) &&
2011 (params->feature_config_flags &
2012 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
2013 bnx2x_set_preemphasis(phy, params);
2014
2015 /* forced speed requested? */
2016 if (vars->line_speed != SPEED_AUTO_NEG ||
2017 (SINGLE_MEDIA_DIRECT(params) &&
2018 params->loopback_mode == LOOPBACK_EXT)) {
2019 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2020
2021 /* disable autoneg */
2022 bnx2x_set_autoneg(phy, params, vars, 0);
2023
2024 /* program speed and duplex */
2025 bnx2x_program_serdes(phy, params, vars);
2026
2027 } else { /* AN_mode */
2028 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2029
2030 /* AN enabled */
2031 bnx2x_set_brcm_cl37_advertisment(phy, params);
2032
2033 /* program duplex & pause advertisement (for aneg) */
2034 bnx2x_set_ieee_aneg_advertisment(phy, params,
2035 vars->ieee_fc);
2036
2037 /* enable autoneg */
2038 bnx2x_set_autoneg(phy, params, vars, enable_cl73);
2039
2040 /* enable and restart AN */
2041 bnx2x_restart_autoneg(phy, params, enable_cl73);
2042 }
2043
2044 } else { /* SGMII mode */
2045 DP(NETIF_MSG_LINK, "SGMII\n");
2046
2047 bnx2x_initialize_sgmii_process(phy, params, vars);
2048 }
2049}
2050
2007static u8 bnx2x_init_serdes(struct bnx2x_phy *phy, 2051static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
2008 struct link_params *params, 2052 struct link_params *params,
2009 struct link_vars *vars) 2053 struct link_vars *vars)
@@ -2058,16 +2102,845 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2058 return rc; 2102 return rc;
2059} 2103}
2060 2104
2105static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
2106 struct bnx2x_phy *phy)
2107{
2108 u16 cnt, ctrl;
2109 /* Wait for soft reset to get cleared upto 1 sec */
2110 for (cnt = 0; cnt < 1000; cnt++) {
2111 bnx2x_cl45_read(bp, phy,
2112 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
2113 if (!(ctrl & (1<<15)))
2114 break;
2115 msleep(1);
2116 }
2117 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
2118 return cnt;
2119}
2120
2121static void bnx2x_link_int_enable(struct link_params *params)
2122{
2123 u8 port = params->port;
2124 u32 mask;
2125 struct bnx2x *bp = params->bp;
2126
2127 /* setting the status to report on link up
2128 for either XGXS or SerDes */
2129
2130 if (params->switch_cfg == SWITCH_CFG_10G) {
2131 mask = (NIG_MASK_XGXS0_LINK10G |
2132 NIG_MASK_XGXS0_LINK_STATUS);
2133 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
2134 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2135 params->phy[INT_PHY].type !=
2136 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
2137 mask |= NIG_MASK_MI_INT;
2138 DP(NETIF_MSG_LINK, "enabled external phy int\n");
2139 }
2140
2141 } else { /* SerDes */
2142 mask = NIG_MASK_SERDES0_LINK_STATUS;
2143 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
2144 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2145 params->phy[INT_PHY].type !=
2146 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
2147 mask |= NIG_MASK_MI_INT;
2148 DP(NETIF_MSG_LINK, "enabled external phy int\n");
2149 }
2150 }
2151 bnx2x_bits_en(bp,
2152 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
2153 mask);
2154
2155 DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
2156 (params->switch_cfg == SWITCH_CFG_10G),
2157 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
2158 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
2159 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
2160 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
2161 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
2162 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
2163 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
2164 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
2165}
2166
2167static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
2168 u8 is_mi_int)
2169{
2170 u32 latch_status = 0, is_mi_int_status;
2171 /* Disable the MI INT ( external phy int )
2172 * by writing 1 to the status register. Link down indication
2173 * is high-active-signal, so in this case we need to write the
2174 * status to clear the XOR
2175 */
2176 /* Read Latched signals */
2177 latch_status = REG_RD(bp,
2178 NIG_REG_LATCH_STATUS_0 + port*8);
2179 is_mi_int_status = REG_RD(bp,
2180 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
2181 DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
2182 "latch_status = 0x%x\n",
2183 is_mi_int, is_mi_int_status, latch_status);
2184 /* Handle only those with latched-signal=up.*/
2185 if (latch_status & 1) {
2186 /* For all latched-signal=up,Write original_signal to status */
2187 if (is_mi_int)
2188 bnx2x_bits_en(bp,
2189 NIG_REG_STATUS_INTERRUPT_PORT0
2190 + port*4,
2191 NIG_STATUS_EMAC0_MI_INT);
2192 else
2193 bnx2x_bits_dis(bp,
2194 NIG_REG_STATUS_INTERRUPT_PORT0
2195 + port*4,
2196 NIG_STATUS_EMAC0_MI_INT);
2197 /* For all latched-signal=up : Re-Arm Latch signals */
2198 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
2199 (latch_status & 0xfffe) | (latch_status & 1));
2200 }
2201}
2202
2203static void bnx2x_link_int_ack(struct link_params *params,
2204 struct link_vars *vars, u8 is_10g,
2205 u8 is_mi_int)
2206{
2207 struct bnx2x *bp = params->bp;
2208 u8 port = params->port;
2209
2210 /* first reset all status
2211 * we assume only one line will be change at a time */
2212 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2213 (NIG_STATUS_XGXS0_LINK10G |
2214 NIG_STATUS_XGXS0_LINK_STATUS |
2215 NIG_STATUS_SERDES0_LINK_STATUS));
2216 if ((params->phy[EXT_PHY1].type
2217 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
2218 (params->phy[EXT_PHY1].type
2219 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) {
2220 bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
2221 }
2222 if (vars->phy_link_up) {
2223 if (is_10g) {
2224 /* Disable the 10G link interrupt
2225 * by writing 1 to the status register
2226 */
2227 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
2228 bnx2x_bits_en(bp,
2229 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2230 NIG_STATUS_XGXS0_LINK10G);
2231
2232 } else if (params->switch_cfg == SWITCH_CFG_10G) {
2233 /* Disable the link interrupt
2234 * by writing 1 to the relevant lane
2235 * in the status register
2236 */
2237 u32 ser_lane = ((params->lane_config &
2238 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2239 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2240
2241 DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
2242 vars->line_speed);
2243 bnx2x_bits_en(bp,
2244 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2245 ((1 << ser_lane) <<
2246 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
2247
2248 } else { /* SerDes */
2249 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
2250 /* Disable the link interrupt
2251 * by writing 1 to the status register
2252 */
2253 bnx2x_bits_en(bp,
2254 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2255 NIG_STATUS_SERDES0_LINK_STATUS);
2256 }
2257
2258 }
2259}
2260
2261static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
2262{
2263 u8 *str_ptr = str;
2264 u32 mask = 0xf0000000;
2265 u8 shift = 8*4;
2266 u8 digit;
2267 if (*len < 10) {
2268 /* Need more than 10chars for this format */
2269 *str_ptr = '\0';
2270 return -EINVAL;
2271 }
2272 while (shift > 0) {
2273
2274 shift -= 4;
2275 digit = ((num & mask) >> shift);
2276 if (digit < 0xa)
2277 *str_ptr = digit + '0';
2278 else
2279 *str_ptr = digit - 0xa + 'a';
2280 str_ptr++;
2281 mask = mask >> 4;
2282 if (shift == 4*4) {
2283 *str_ptr = ':';
2284 str_ptr++;
2285 }
2286 }
2287 *str_ptr = '\0';
2288 return 0;
2289}
2290
2291static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
2292{
2293 str[0] = '\0';
2294 (*len)--;
2295 return 0;
2296}
2297
2298u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
2299 u8 *version, u16 len)
2300{
2301 struct bnx2x *bp;
2302 u32 spirom_ver = 0;
2303 u8 status = 0;
2304 u8 *ver_p = version;
2305 if (version == NULL || params == NULL)
2306 return -EINVAL;
2307 bp = params->bp;
2308
2309 /* Extract first external phy*/
2310 version[0] = '\0';
2311 spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
2312
2313 if (params->phy[EXT_PHY1].format_fw_ver)
2314 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
2315 ver_p,
2316 &len);
2317 return status;
2318}
2319
2320static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
2321 struct link_params *params)
2322{
2323 u8 port = params->port;
2324 struct bnx2x *bp = params->bp;
2325
2326 if (phy->req_line_speed != SPEED_1000) {
2327 u32 md_devad;
2328
2329 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
2330
2331 /* change the uni_phy_addr in the nig */
2332 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
2333 port*0x18));
2334
2335 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
2336
2337 bnx2x_cl45_write(bp, phy,
2338 5,
2339 (MDIO_REG_BANK_AER_BLOCK +
2340 (MDIO_AER_BLOCK_AER_REG & 0xf)),
2341 0x2800);
2342
2343 bnx2x_cl45_write(bp, phy,
2344 5,
2345 (MDIO_REG_BANK_CL73_IEEEB0 +
2346 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
2347 0x6041);
2348 msleep(200);
2349 /* set aer mmd back */
2350 bnx2x_set_aer_mmd(params, phy);
2351
2352 /* and md_devad */
2353 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
2354 md_devad);
2355
2356 } else {
2357 u16 mii_ctrl;
2358 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
2359 bnx2x_cl45_read(bp, phy, 5,
2360 (MDIO_REG_BANK_COMBO_IEEE0 +
2361 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
2362 &mii_ctrl);
2363 bnx2x_cl45_write(bp, phy, 5,
2364 (MDIO_REG_BANK_COMBO_IEEE0 +
2365 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
2366 mii_ctrl |
2367 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
2368 }
2369}
2370
2371/*
2372 *------------------------------------------------------------------------
2373 * bnx2x_override_led_value -
2374 *
2375 * Override the led value of the requested led
2376 *
2377 *------------------------------------------------------------------------
2378 */
2379u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
2380 u32 led_idx, u32 value)
2381{
2382 u32 reg_val;
2383
2384 /* If port 0 then use EMAC0, else use EMAC1*/
2385 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2386
2387 DP(NETIF_MSG_LINK,
2388 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
2389 port, led_idx, value);
2390
2391 switch (led_idx) {
2392 case 0: /* 10MB led */
2393 /* Read the current value of the LED register in
2394 the EMAC block */
2395 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
2396 /* Set the OVERRIDE bit to 1 */
2397 reg_val |= EMAC_LED_OVERRIDE;
2398 /* If value is 1, set the 10M_OVERRIDE bit,
2399 otherwise reset it.*/
2400 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
2401 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
2402 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
2403 break;
2404 case 1: /*100MB led */
2405 /*Read the current value of the LED register in
2406 the EMAC block */
2407 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
2408 /* Set the OVERRIDE bit to 1 */
2409 reg_val |= EMAC_LED_OVERRIDE;
2410 /* If value is 1, set the 100M_OVERRIDE bit,
2411 otherwise reset it.*/
2412 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
2413 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
2414 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
2415 break;
2416 case 2: /* 1000MB led */
2417 /* Read the current value of the LED register in the
2418 EMAC block */
2419 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
2420 /* Set the OVERRIDE bit to 1 */
2421 reg_val |= EMAC_LED_OVERRIDE;
2422 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
2423 reset it. */
2424 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
2425 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
2426 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
2427 break;
2428 case 3: /* 2500MB led */
2429 /* Read the current value of the LED register in the
2430 EMAC block*/
2431 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
2432 /* Set the OVERRIDE bit to 1 */
2433 reg_val |= EMAC_LED_OVERRIDE;
2434 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
2435 reset it.*/
2436 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
2437 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
2438 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
2439 break;
2440 case 4: /*10G led */
2441 if (port == 0) {
2442 REG_WR(bp, NIG_REG_LED_10G_P0,
2443 value);
2444 } else {
2445 REG_WR(bp, NIG_REG_LED_10G_P1,
2446 value);
2447 }
2448 break;
2449 case 5: /* TRAFFIC led */
2450 /* Find if the traffic control is via BMAC or EMAC */
2451 if (port == 0)
2452 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
2453 else
2454 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
2455
2456 /* Override the traffic led in the EMAC:*/
2457 if (reg_val == 1) {
2458 /* Read the current value of the LED register in
2459 the EMAC block */
2460 reg_val = REG_RD(bp, emac_base +
2461 EMAC_REG_EMAC_LED);
2462 /* Set the TRAFFIC_OVERRIDE bit to 1 */
2463 reg_val |= EMAC_LED_OVERRIDE;
2464 /* If value is 1, set the TRAFFIC bit, otherwise
2465 reset it.*/
2466 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
2467 (reg_val & ~EMAC_LED_TRAFFIC);
2468 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
2469 } else { /* Override the traffic led in the BMAC: */
2470 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
2471 + port*4, 1);
2472 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
2473 value);
2474 }
2475 break;
2476 default:
2477 DP(NETIF_MSG_LINK,
2478 "bnx2x_override_led_value() unknown led index %d "
2479 "(should be 0-5)\n", led_idx);
2480 return -EINVAL;
2481 }
2482
2483 return 0;
2484}
2485
2486u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed)
2487{
2488 u8 port = params->port;
2489 u16 hw_led_mode = params->hw_led_mode;
2490 u8 rc = 0;
2491 u32 tmp;
2492 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2493 struct bnx2x *bp = params->bp;
2494 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
2495 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
2496 speed, hw_led_mode);
2497 switch (mode) {
2498 case LED_MODE_OFF:
2499 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
2500 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
2501 SHARED_HW_CFG_LED_MAC1);
2502
2503 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
2504 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
2505 break;
2506
2507 case LED_MODE_OPER:
2508 if (SINGLE_MEDIA_DIRECT(params)) {
2509 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
2510 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
2511 } else {
2512 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
2513 hw_led_mode);
2514 }
2515
2516 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
2517 port*4, 0);
2518 /* Set blinking rate to ~15.9Hz */
2519 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
2520 LED_BLINK_RATE_VAL);
2521 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
2522 port*4, 1);
2523 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
2524 EMAC_WR(bp, EMAC_REG_EMAC_LED,
2525 (tmp & (~EMAC_LED_OVERRIDE)));
2526
2527 if (CHIP_IS_E1(bp) &&
2528 ((speed == SPEED_2500) ||
2529 (speed == SPEED_1000) ||
2530 (speed == SPEED_100) ||
2531 (speed == SPEED_10))) {
2532 /* On Everest 1 Ax chip versions for speeds less than
2533 10G LED scheme is different */
2534 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
2535 + port*4, 1);
2536 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
2537 port*4, 0);
2538 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
2539 port*4, 1);
2540 }
2541 break;
2542
2543 default:
2544 rc = -EINVAL;
2545 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
2546 mode);
2547 break;
2548 }
2549 return rc;
2550
2551}
2552
2553u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
2554{
2555 struct bnx2x *bp = params->bp;
2556 u16 gp_status = 0, phy_index = 0;
2557
2558 CL45_RD_OVER_CL22(bp, &params->phy[INT_PHY],
2559 MDIO_REG_BANK_GP_STATUS,
2560 MDIO_GP_STATUS_TOP_AN_STATUS1,
2561 &gp_status);
2562 /* link is up only if both local phy and external phy are up */
2563 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
2564 u8 ext_phy_link_up = 1;
2565 struct link_vars temp_vars;
2566 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
2567 phy_index++) {
2568 if (params->phy[phy_index].read_status)
2569 ext_phy_link_up &=
2570 params->phy[phy_index].read_status(
2571 &params->phy[phy_index],
2572 params, &temp_vars);
2573 }
2574 if (ext_phy_link_up)
2575 return 0;
2576 }
2577 return -ESRCH;
2578}
2579
2580static u8 bnx2x_link_initialize(struct link_params *params,
2581 struct link_vars *vars)
2582{
2583 u8 rc = 0;
2584 u8 phy_index, non_ext_phy;
2585 struct bnx2x *bp = params->bp;
2586 /**
2587 * In case of external phy existence, the line speed would be the
2588 * line speed linked up by the external phy. In case it is direct
2589 * only, then the line_speed during initialization will be
2590 * equal to the req_line_speed
2591 */
2592 vars->line_speed = params->phy[INT_PHY].req_line_speed;
2593
2594 /**
2595 * Initialize the internal phy in case this is a direct board
2596 * (no external phys), or this board has external phy which requires
2597 * to first.
2598 */
2599
2600 if (params->phy[INT_PHY].config_init)
2601 params->phy[INT_PHY].config_init(
2602 &params->phy[INT_PHY],
2603 params, vars);
2604
2605 /* init ext phy and enable link state int */
2606 non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
2607 (params->loopback_mode == LOOPBACK_XGXS));
2608
2609 if (non_ext_phy ||
2610 (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
2611 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
2612 struct bnx2x_phy *phy = &params->phy[INT_PHY];
2613 if (vars->line_speed == SPEED_AUTO_NEG)
2614 bnx2x_set_parallel_detection(phy, params);
2615 bnx2x_init_internal_phy(phy, params, vars);
2616 }
2617
2618 /* Init external phy*/
2619 if (!non_ext_phy)
2620 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
2621 phy_index++) {
2622 params->phy[phy_index].config_init(
2623 &params->phy[phy_index],
2624 params, vars);
2625 }
2626
2627 /* Reset the interrupt indication after phy was initialized */
2628 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
2629 params->port*4,
2630 (NIG_STATUS_XGXS0_LINK10G |
2631 NIG_STATUS_XGXS0_LINK_STATUS |
2632 NIG_STATUS_SERDES0_LINK_STATUS |
2633 NIG_MASK_MI_INT));
2634 return rc;
2635}
2636
2637static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
2638 struct link_params *params)
2639{
2640 /* reset the SerDes/XGXS */
2641 REG_WR(params->bp, GRCBASE_MISC +
2642 MISC_REGISTERS_RESET_REG_3_CLEAR,
2643 (0x1ff << (params->port*16)));
2644}
2645
2646static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
2647 struct link_params *params)
2648{
2649 struct bnx2x *bp = params->bp;
2650 u8 gpio_port;
2651 /* HW reset */
2652 gpio_port = params->port;
2653 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2654 MISC_REGISTERS_GPIO_OUTPUT_LOW,
2655 gpio_port);
2656 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2657 MISC_REGISTERS_GPIO_OUTPUT_LOW,
2658 gpio_port);
2659 DP(NETIF_MSG_LINK, "reset external PHY\n");
2660}
2661
2662static u8 bnx2x_update_link_down(struct link_params *params,
2663 struct link_vars *vars)
2664{
2665 struct bnx2x *bp = params->bp;
2666 u8 port = params->port;
2667
2668 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
2669 bnx2x_set_led(params, LED_MODE_OFF, 0);
2670
2671 /* indicate no mac active */
2672 vars->mac_type = MAC_TYPE_NONE;
2673
2674 /* update shared memory */
2675 vars->link_status = 0;
2676 vars->line_speed = 0;
2677 bnx2x_update_mng(params, vars->link_status);
2678
2679 /* activate nig drain */
2680 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
2681
2682 /* disable emac */
2683 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
2684
2685 msleep(10);
2686
2687 /* reset BigMac */
2688 bnx2x_bmac_rx_disable(bp, params->port);
2689 REG_WR(bp, GRCBASE_MISC +
2690 MISC_REGISTERS_RESET_REG_2_CLEAR,
2691 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2692 return 0;
2693}
2694
2695static u8 bnx2x_update_link_up(struct link_params *params,
2696 struct link_vars *vars,
2697 u8 link_10g)
2698{
2699 struct bnx2x *bp = params->bp;
2700 u8 port = params->port;
2701 u8 rc = 0;
2702
2703 vars->link_status |= LINK_STATUS_LINK_UP;
2704 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
2705 vars->link_status |=
2706 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
2707
2708 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
2709 vars->link_status |=
2710 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
2711 if (link_10g) {
2712 bnx2x_bmac_enable(params, vars, 0);
2713 bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
2714 } else {
2715 rc = bnx2x_emac_program(params, vars);
2716
2717 bnx2x_emac_enable(params, vars, 0);
2718
2719 /* AN complete? */
2720 if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
2721 && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
2722 SINGLE_MEDIA_DIRECT(params))
2723 bnx2x_set_gmii_tx_driver(params);
2724 }
2725
2726 /* PBF - link up */
2727 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
2728 vars->line_speed);
2729
2730 /* disable drain */
2731 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
2732
2733 /* update shared memory */
2734 bnx2x_update_mng(params, vars->link_status);
2735 msleep(20);
2736 return rc;
2737}
2738/**
2739 * The bnx2x_link_update function should be called upon link
2740 * interrupt.
2741 * Link is considered up as follows:
2742 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
2743 * to be up
2744 * - SINGLE_MEDIA - The link between the 577xx and the external
2745 * phy (XGXS) need to up as well as the external link of the
2746 * phy (PHY_EXT1)
2747 * - DUAL_MEDIA - The link between the 577xx and the first
2748 * external phy needs to be up, and at least one of the 2
2749 * external phy link must be up.
2750 */
2751u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
2752{
2753 struct bnx2x *bp = params->bp;
2754 struct link_vars phy_vars[MAX_PHYS];
2755 u8 port = params->port;
2756 u8 link_10g, phy_index;
2757 u8 ext_phy_link_up = 0, cur_link_up, rc = 0;
2758 u8 is_mi_int = 0;
2759 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
2760 u8 active_external_phy = INT_PHY;
2761 vars->link_status = 0;
2762 for (phy_index = INT_PHY; phy_index < params->num_phys;
2763 phy_index++) {
2764 phy_vars[phy_index].flow_ctrl = 0;
2765 phy_vars[phy_index].link_status = 0;
2766 phy_vars[phy_index].line_speed = 0;
2767 phy_vars[phy_index].duplex = DUPLEX_FULL;
2768 phy_vars[phy_index].phy_link_up = 0;
2769 phy_vars[phy_index].link_up = 0;
2770 }
2771
2772 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
2773 port, (vars->phy_flags & PHY_XGXS_FLAG),
2774 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
2775
2776 is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
2777 port*0x18) > 0);
2778 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
2779 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
2780 is_mi_int,
2781 REG_RD(bp,
2782 NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
2783
2784 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
2785 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
2786 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
2787
2788 /* disable emac */
2789 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
2790
2791 /**
2792 * Step 1:
2793 * Check external link change only for external phys, and apply
2794 * priority selection between them in case the link on both phys
2795 * is up. Note that the instead of the common vars, a temporary
2796 * vars argument is used since each phy may have different link/
2797 * speed/duplex result
2798 */
2799 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
2800 phy_index++) {
2801 struct bnx2x_phy *phy = &params->phy[phy_index];
2802 if (!phy->read_status)
2803 continue;
2804 /* Read link status and params of this ext phy */
2805 cur_link_up = phy->read_status(phy, params,
2806 &phy_vars[phy_index]);
2807 if (cur_link_up) {
2808 DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
2809 phy_index);
2810 } else {
2811 DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
2812 phy_index);
2813 continue;
2814 }
2815
2816 if (!ext_phy_link_up) {
2817 ext_phy_link_up = 1;
2818 active_external_phy = phy_index;
2819 }
2820 }
2821 prev_line_speed = vars->line_speed;
2822 /**
2823 * Step 2:
2824 * Read the status of the internal phy. In case of
2825 * DIRECT_SINGLE_MEDIA board, this link is the external link,
2826 * otherwise this is the link between the 577xx and the first
2827 * external phy
2828 */
2829 if (params->phy[INT_PHY].read_status)
2830 params->phy[INT_PHY].read_status(
2831 &params->phy[INT_PHY],
2832 params, vars);
2833 /**
2834 * The INT_PHY flow control reside in the vars. This include the
2835 * case where the speed or flow control are not set to AUTO.
2836 * Otherwise, the active external phy flow control result is set
2837 * to the vars. The ext_phy_line_speed is needed to check if the
2838 * speed is different between the internal phy and external phy.
2839 * This case may be result of intermediate link speed change.
2840 */
2841 if (active_external_phy > INT_PHY) {
2842 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
2843 /**
2844 * Link speed is taken from the XGXS. AN and FC result from
2845 * the external phy.
2846 */
2847 vars->link_status |= phy_vars[active_external_phy].link_status;
2848 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
2849 vars->duplex = phy_vars[active_external_phy].duplex;
2850 if (params->phy[active_external_phy].supported &
2851 SUPPORTED_FIBRE)
2852 vars->link_status |= LINK_STATUS_SERDES_LINK;
2853 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
2854 active_external_phy);
2855 }
2856 DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
2857 " ext_phy_line_speed = %d\n", vars->flow_ctrl,
2858 vars->link_status, ext_phy_line_speed);
2859 /**
2860 * Upon link speed change set the NIG into drain mode. Comes to
2861 * deals with possible FIFO glitch due to clk change when speed
2862 * is decreased without link down indicator
2863 */
2864
2865 if (vars->phy_link_up) {
2866 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
2867 (ext_phy_line_speed != vars->line_speed)) {
2868 DP(NETIF_MSG_LINK, "Internal link speed %d is"
2869 " different than the external"
2870 " link speed %d\n", vars->line_speed,
2871 ext_phy_line_speed);
2872 vars->phy_link_up = 0;
2873 } else if (prev_line_speed != vars->line_speed) {
2874 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
2875 + params->port*4, 0);
2876 msleep(1);
2877 }
2878 }
2879
2880 /* anything 10 and over uses the bmac */
2881 link_10g = ((vars->line_speed == SPEED_10000) ||
2882 (vars->line_speed == SPEED_12000) ||
2883 (vars->line_speed == SPEED_12500) ||
2884 (vars->line_speed == SPEED_13000) ||
2885 (vars->line_speed == SPEED_15000) ||
2886 (vars->line_speed == SPEED_16000));
2887
2888 bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
2889
2890 /**
2891 * In case external phy link is up, and internal link is down
2892 * (not initialized yet probably after link initialization, it
2893 * needs to be initialized.
2894 * Note that after link down-up as result of cable plug, the xgxs
2895 * link would probably become up again without the need
2896 * initialize it
2897 */
2898 if (!(SINGLE_MEDIA_DIRECT(params))) {
2899 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
2900 " init_preceding = %d\n", ext_phy_link_up,
2901 vars->phy_link_up,
2902 params->phy[EXT_PHY1].flags &
2903 FLAGS_INIT_XGXS_FIRST);
2904 if (!(params->phy[EXT_PHY1].flags &
2905 FLAGS_INIT_XGXS_FIRST)
2906 && ext_phy_link_up && !vars->phy_link_up) {
2907 vars->line_speed = ext_phy_line_speed;
2908 if (vars->line_speed < SPEED_1000)
2909 vars->phy_flags |= PHY_SGMII_FLAG;
2910 else
2911 vars->phy_flags &= ~PHY_SGMII_FLAG;
2912 bnx2x_init_internal_phy(&params->phy[INT_PHY],
2913 params,
2914 vars);
2915 }
2916 }
2917 /**
2918 * Link is up only if both local phy and external phy (in case of
2919 * non-direct board) are up
2920 */
2921 vars->link_up = (vars->phy_link_up &&
2922 (ext_phy_link_up ||
2923 SINGLE_MEDIA_DIRECT(params)));
2924
2925 if (vars->link_up)
2926 rc = bnx2x_update_link_up(params, vars, link_10g);
2927 else
2928 rc = bnx2x_update_link_down(params, vars);
2929
2930 return rc;
2931}
2932
2933
2061/*****************************************************************************/ 2934/*****************************************************************************/
2062/* External Phy section */ 2935/* External Phy section */
2063/*****************************************************************************/ 2936/*****************************************************************************/
2064void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) 2937void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
2065{ 2938{
2066 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 2939 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2067 MISC_REGISTERS_GPIO_OUTPUT_LOW, port); 2940 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
2068 msleep(1); 2941 msleep(1);
2069 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 2942 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2070 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); 2943 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
2071} 2944}
2072 2945
2073static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, 2946static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
@@ -2094,59 +2967,211 @@ static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
2094 phy->ver_addr); 2967 phy->ver_addr);
2095} 2968}
2096 2969
2097static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, 2970static void bnx2x_ext_phy_set_pause(struct link_params *params,
2098 struct link_params *params) 2971 struct bnx2x_phy *phy,
2972 struct link_vars *vars)
2099{ 2973{
2100 u16 val, fw_ver1, fw_ver2, cnt; 2974 u16 val;
2101 struct bnx2x *bp = params->bp; 2975 struct bnx2x *bp = params->bp;
2976 /* read modify write pause advertizing */
2977 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
2102 2978
2103 /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ 2979 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2104 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
2105 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
2106 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
2107 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
2108 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
2109 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
2110 2980
2111 for (cnt = 0; cnt < 100; cnt++) { 2981 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2112 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); 2982 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2113 if (val & 1) 2983 if ((vars->ieee_fc &
2114 break; 2984 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2115 udelay(5); 2985 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2986 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2116 } 2987 }
2117 if (cnt == 100) { 2988 if ((vars->ieee_fc &
2118 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n"); 2989 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2119 bnx2x_save_spirom_version(bp, params->port, 0, 2990 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2120 phy->ver_addr); 2991 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
2992 }
2993 DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
2994 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
2995}
2996
2997static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
2998 struct link_params *params,
2999 struct link_vars *vars)
3000{
3001 struct bnx2x *bp = params->bp;
3002 u16 ld_pause; /* local */
3003 u16 lp_pause; /* link partner */
3004 u16 pause_result;
3005 u8 ret = 0;
3006 /* read twice */
3007
3008 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3009
3010 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
3011 vars->flow_ctrl = phy->req_flow_ctrl;
3012 else if (phy->req_line_speed != SPEED_AUTO_NEG)
3013 vars->flow_ctrl = params->req_fc_auto_adv;
3014 else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3015 ret = 1;
3016 bnx2x_cl45_read(bp, phy,
3017 MDIO_AN_DEVAD,
3018 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3019 bnx2x_cl45_read(bp, phy,
3020 MDIO_AN_DEVAD,
3021 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3022 pause_result = (ld_pause &
3023 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3024 pause_result |= (lp_pause &
3025 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3026 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
3027 pause_result);
3028 bnx2x_pause_resolve(vars, pause_result);
3029 }
3030 return ret;
3031}
3032
3033static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
3034 struct bnx2x_phy *phy,
3035 struct link_vars *vars)
3036{
3037 u16 val;
3038 bnx2x_cl45_read(bp, phy,
3039 MDIO_AN_DEVAD,
3040 MDIO_AN_REG_STATUS, &val);
3041 bnx2x_cl45_read(bp, phy,
3042 MDIO_AN_DEVAD,
3043 MDIO_AN_REG_STATUS, &val);
3044 if (val & (1<<5))
3045 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
3046 if ((val & (1<<0)) == 0)
3047 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
3048}
3049
3050/******************************************************************/
3051/* common BCM8073/BCM8727 PHY SECTION */
3052/******************************************************************/
3053static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
3054 struct link_params *params,
3055 struct link_vars *vars)
3056{
3057 struct bnx2x *bp = params->bp;
3058 if (phy->req_line_speed == SPEED_10 ||
3059 phy->req_line_speed == SPEED_100) {
3060 vars->flow_ctrl = phy->req_flow_ctrl;
2121 return; 3061 return;
2122 } 3062 }
2123 3063
3064 if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
3065 (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
3066 u16 pause_result;
3067 u16 ld_pause; /* local */
3068 u16 lp_pause; /* link partner */
3069 bnx2x_cl45_read(bp, phy,
3070 MDIO_AN_DEVAD,
3071 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
2124 3072
2125 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ 3073 bnx2x_cl45_read(bp, phy,
2126 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); 3074 MDIO_AN_DEVAD,
2127 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); 3075 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
2128 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); 3076 pause_result = (ld_pause &
2129 for (cnt = 0; cnt < 100; cnt++) { 3077 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
2130 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); 3078 pause_result |= (lp_pause &
2131 if (val & 1) 3079 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
2132 break; 3080
2133 udelay(5); 3081 bnx2x_pause_resolve(vars, pause_result);
3082 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
3083 pause_result);
2134 } 3084 }
2135 if (cnt == 100) { 3085}
2136 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n"); 3086
2137 bnx2x_save_spirom_version(bp, params->port, 0, 3087static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
2138 phy->ver_addr); 3088 struct bnx2x_phy *phy,
3089 u8 port)
3090{
3091 /* Boot port from external ROM */
3092 /* EDC grst */
3093 bnx2x_cl45_write(bp, phy,
3094 MDIO_PMA_DEVAD,
3095 MDIO_PMA_REG_GEN_CTRL,
3096 0x0001);
3097
3098 /* ucode reboot and rst */
3099 bnx2x_cl45_write(bp, phy,
3100 MDIO_PMA_DEVAD,
3101 MDIO_PMA_REG_GEN_CTRL,
3102 0x008c);
3103
3104 bnx2x_cl45_write(bp, phy,
3105 MDIO_PMA_DEVAD,
3106 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
3107
3108 /* Reset internal microprocessor */
3109 bnx2x_cl45_write(bp, phy,
3110 MDIO_PMA_DEVAD,
3111 MDIO_PMA_REG_GEN_CTRL,
3112 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
3113
3114 /* Release srst bit */
3115 bnx2x_cl45_write(bp, phy,
3116 MDIO_PMA_DEVAD,
3117 MDIO_PMA_REG_GEN_CTRL,
3118 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
3119
3120 /* wait for 120ms for code download via SPI port */
3121 msleep(120);
3122
3123 /* Clear ser_boot_ctl bit */
3124 bnx2x_cl45_write(bp, phy,
3125 MDIO_PMA_DEVAD,
3126 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
3127 bnx2x_save_bcm_spirom_ver(bp, phy, port);
3128}
3129
3130static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp,
3131 struct bnx2x_phy *phy)
3132{
3133 u16 val;
3134 bnx2x_cl45_read(bp, phy,
3135 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val);
3136
3137 if (val == 0) {
3138 /* Mustn't set low power mode in 8073 A0 */
2139 return; 3139 return;
2140 } 3140 }
2141 3141
2142 /* lower 16 bits of the register SPI_FW_STATUS */ 3142 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2143 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); 3143 bnx2x_cl45_read(bp, phy,
2144 /* upper 16 bits of register SPI_FW_STATUS */ 3144 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
2145 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); 3145 val &= ~(1<<13);
3146 bnx2x_cl45_write(bp, phy,
3147 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2146 3148
2147 bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, 3149 /* PLL controls */
2148 phy->ver_addr); 3150 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077);
3151 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000);
3152 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B);
3153 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240);
3154 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490);
3155
3156 /* Tx Controls */
3157 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74);
3158 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041);
3159 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640);
3160
3161 /* Rx Controls */
3162 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4);
3163 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249);
3164 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015);
3165
3166 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
3167 bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
3168 val |= (1<<13);
3169 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2149} 3170}
3171
3172/******************************************************************/
3173/* BCM8073 PHY SECTION */
3174/******************************************************************/
2150static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) 3175static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
2151{ 3176{
2152 /* This is only required for 8073A1, version 102 only */ 3177 /* This is only required for 8073A1, version 102 only */
@@ -2172,6 +3197,7 @@ static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
2172 3197
2173 return 1; 3198 return 1;
2174} 3199}
3200
2175static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) 3201static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
2176{ 3202{
2177 u16 val, cnt, cnt1 ; 3203 u16 val, cnt, cnt1 ;
@@ -2225,87 +3251,374 @@ static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
2225 return -EINVAL; 3251 return -EINVAL;
2226} 3252}
2227 3253
2228static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, 3254static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
2229 struct bnx2x_phy *phy,
2230 u8 port)
2231{ 3255{
2232 /* Boot port from external ROM */ 3256 /* Force KR or KX */
2233 /* EDC grst */
2234 bnx2x_cl45_write(bp, phy, 3257 bnx2x_cl45_write(bp, phy,
2235 MDIO_PMA_DEVAD, 3258 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
2236 MDIO_PMA_REG_GEN_CTRL,
2237 0x0001);
2238
2239 /* ucode reboot and rst */
2240 bnx2x_cl45_write(bp, phy, 3259 bnx2x_cl45_write(bp, phy,
2241 MDIO_PMA_DEVAD, 3260 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
2242 MDIO_PMA_REG_GEN_CTRL,
2243 0x008c);
2244
2245 bnx2x_cl45_write(bp, phy, 3261 bnx2x_cl45_write(bp, phy,
2246 MDIO_PMA_DEVAD, 3262 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
2247 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2248
2249 /* Reset internal microprocessor */
2250 bnx2x_cl45_write(bp, phy, 3263 bnx2x_cl45_write(bp, phy,
2251 MDIO_PMA_DEVAD, 3264 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
2252 MDIO_PMA_REG_GEN_CTRL, 3265}
2253 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2254 3266
2255 /* Release srst bit */ 3267static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2256 bnx2x_cl45_write(bp, phy, 3268 struct bnx2x_phy *phy,
2257 MDIO_PMA_DEVAD, 3269 struct link_vars *vars)
2258 MDIO_PMA_REG_GEN_CTRL, 3270{
2259 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); 3271 u16 cl37_val;
3272 struct bnx2x *bp = params->bp;
3273 bnx2x_cl45_read(bp, phy,
3274 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2260 3275
2261 /* wait for 120ms for code download via SPI port */ 3276 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2262 msleep(120); 3277 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3278 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3279 if ((vars->ieee_fc &
3280 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
3281 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
3282 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
3283 }
3284 if ((vars->ieee_fc &
3285 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3286 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3287 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3288 }
3289 if ((vars->ieee_fc &
3290 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3291 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3292 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3293 }
3294 DP(NETIF_MSG_LINK,
3295 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2263 3296
2264 /* Clear ser_boot_ctl bit */
2265 bnx2x_cl45_write(bp, phy, 3297 bnx2x_cl45_write(bp, phy,
2266 MDIO_PMA_DEVAD, 3298 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
2267 MDIO_PMA_REG_MISC_CTRL1, 0x0000); 3299 msleep(500);
2268 bnx2x_save_bcm_spirom_ver(bp, phy, port);
2269} 3300}
2270 3301
2271static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, 3302static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
2272 struct link_params *params) 3303 struct link_params *params,
3304 struct link_vars *vars)
2273{ 3305{
2274 struct bnx2x *bp = params->bp; 3306 struct bnx2x *bp = params->bp;
2275 /* Need to wait 100ms after reset */ 3307 u16 val = 0, tmp1;
2276 msleep(100); 3308 u8 gpio_port;
3309 DP(NETIF_MSG_LINK, "Init 8073\n");
2277 3310
2278 /* Micro controller re-boot */ 3311 gpio_port = params->port;
2279 bnx2x_cl45_write(bp, phy, 3312 /* Restore normal power mode*/
2280 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B); 3313 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3314 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
2281 3315
2282 /* Set soft reset */ 3316 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2283 bnx2x_cl45_write(bp, phy, 3317 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
2284 MDIO_PMA_DEVAD,
2285 MDIO_PMA_REG_GEN_CTRL,
2286 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2287 3318
3319 /* enable LASI */
2288 bnx2x_cl45_write(bp, phy, 3320 bnx2x_cl45_write(bp, phy,
2289 MDIO_PMA_DEVAD, 3321 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
2290 MDIO_PMA_REG_MISC_CTRL1, 0x0001); 3322 bnx2x_cl45_write(bp, phy,
3323 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
3324
3325 bnx2x_8073_set_pause_cl37(params, phy, vars);
3326
3327 bnx2x_8073_set_xaui_low_power_mode(bp, phy);
3328
3329 bnx2x_cl45_read(bp, phy,
3330 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
2291 3331
3332 bnx2x_cl45_read(bp, phy,
3333 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
3334
3335 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
3336
3337 /* Enable CL37 BAM */
3338 bnx2x_cl45_read(bp, phy,
3339 MDIO_AN_DEVAD,
3340 MDIO_AN_REG_8073_BAM, &val);
2292 bnx2x_cl45_write(bp, phy, 3341 bnx2x_cl45_write(bp, phy,
2293 MDIO_PMA_DEVAD, 3342 MDIO_AN_DEVAD,
2294 MDIO_PMA_REG_GEN_CTRL, 3343 MDIO_AN_REG_8073_BAM, val | 1);
2295 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2296 3344
2297 /* wait for 150ms for microcode load */ 3345 if (params->loopback_mode == LOOPBACK_EXT) {
2298 msleep(150); 3346 bnx2x_807x_force_10G(bp, phy);
3347 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
3348 return 0;
3349 } else {
3350 bnx2x_cl45_write(bp, phy,
3351 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
3352 }
3353 if (phy->req_line_speed != SPEED_AUTO_NEG) {
3354 if (phy->req_line_speed == SPEED_10000) {
3355 val = (1<<7);
3356 } else if (phy->req_line_speed == SPEED_2500) {
3357 val = (1<<5);
3358 /* Note that 2.5G works only
3359 when used with 1G advertisment */
3360 } else
3361 val = (1<<5);
3362 } else {
3363 val = 0;
3364 if (phy->speed_cap_mask &
3365 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3366 val |= (1<<7);
3367
3368 /* Note that 2.5G works only when
3369 used with 1G advertisment */
3370 if (phy->speed_cap_mask &
3371 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3372 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3373 val |= (1<<5);
3374 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
3375 }
3376
3377 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
3378 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
3379
3380 if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3381 (phy->req_line_speed == SPEED_AUTO_NEG)) ||
3382 (phy->req_line_speed == SPEED_2500)) {
3383 u16 phy_ver;
3384 /* Allow 2.5G for A1 and above */
3385 bnx2x_cl45_read(bp, phy,
3386 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
3387 &phy_ver);
3388 DP(NETIF_MSG_LINK, "Add 2.5G\n");
3389 if (phy_ver > 0)
3390 tmp1 |= 1;
3391 else
3392 tmp1 &= 0xfffe;
3393 } else {
3394 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3395 tmp1 &= 0xfffe;
3396 }
3397
3398 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
3399 /* Add support for CL37 (passive mode) II */
3400
3401 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
3402 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
3403 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
3404 0x20 : 0x40)));
3405
3406 /* Add support for CL37 (passive mode) III */
3407 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
3408
3409 /* The SNR will improve about 2db by changing
3410 BW and FEE main tap. Rest commands are executed
3411 after link is up*/
3412 if (bnx2x_8073_is_snr_needed(bp, phy))
3413 bnx2x_cl45_write(bp, phy,
3414 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
3415 0xFB0C);
3416
3417 /* Enable FEC (Forware Error Correction) Request in the AN */
3418 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
3419 tmp1 |= (1<<15);
3420 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
3421
3422 bnx2x_ext_phy_set_pause(params, phy, vars);
3423
3424 /* Restart autoneg */
3425 msleep(500);
3426 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
3427 DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
3428 ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
3429 return 0;
3430}
3431
3432static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
3433 struct link_params *params,
3434 struct link_vars *vars)
3435{
3436 struct bnx2x *bp = params->bp;
3437 u8 link_up = 0;
3438 u16 val1, val2;
3439 u16 link_status = 0;
3440 u16 an1000_status = 0;
3441
3442 bnx2x_cl45_read(bp, phy,
3443 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
3444
3445 DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
3446
3447 /* clear the interrupt LASI status register */
3448 bnx2x_cl45_read(bp, phy,
3449 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
3450 bnx2x_cl45_read(bp, phy,
3451 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
3452 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
3453 /* Clear MSG-OUT */
3454 bnx2x_cl45_read(bp, phy,
3455 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
3456
3457 /* Check the LASI */
3458 bnx2x_cl45_read(bp, phy,
3459 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
3460
3461 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3462
3463 /* Check the link status */
3464 bnx2x_cl45_read(bp, phy,
3465 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
3466 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3467
3468 bnx2x_cl45_read(bp, phy,
3469 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
3470 bnx2x_cl45_read(bp, phy,
3471 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
3472 link_up = ((val1 & 4) == 4);
3473 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3474
3475 if (link_up &&
3476 ((phy->req_line_speed != SPEED_10000))) {
3477 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
3478 return 0;
3479 }
3480 bnx2x_cl45_read(bp, phy,
3481 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
3482 bnx2x_cl45_read(bp, phy,
3483 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
3484
3485 /* Check the link status on 1.1.2 */
3486 bnx2x_cl45_read(bp, phy,
3487 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
3488 bnx2x_cl45_read(bp, phy,
3489 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
3490 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3491 "an_link_status=0x%x\n", val2, val1, an1000_status);
3492
3493 link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
3494 if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
3495 /* The SNR will improve about 2dbby
3496 changing the BW and FEE main tap.*/
3497 /* The 1st write to change FFE main
3498 tap is set before restart AN */
3499 /* Change PLL Bandwidth in EDC
3500 register */
3501 bnx2x_cl45_write(bp, phy,
3502 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
3503 0x26BC);
3504
3505 /* Change CDR Bandwidth in EDC register */
3506 bnx2x_cl45_write(bp, phy,
3507 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
3508 0x0333);
3509 }
3510 bnx2x_cl45_read(bp, phy,
3511 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
3512 &link_status);
3513
3514 /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
3515 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
3516 link_up = 1;
3517 vars->line_speed = SPEED_10000;
3518 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
3519 params->port);
3520 } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
3521 link_up = 1;
3522 vars->line_speed = SPEED_2500;
3523 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
3524 params->port);
3525 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
3526 link_up = 1;
3527 vars->line_speed = SPEED_1000;
3528 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
3529 params->port);
3530 } else {
3531 link_up = 0;
3532 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
3533 params->port);
3534 }
3535
3536 if (link_up) {
3537 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
3538 bnx2x_8073_resolve_fc(phy, params, vars);
3539 }
3540 return link_up;
3541}
3542
3543static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
3544 struct link_params *params)
3545{
3546 struct bnx2x *bp = params->bp;
3547 u8 gpio_port;
3548 gpio_port = params->port;
3549 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
3550 gpio_port);
3551 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3552 MISC_REGISTERS_GPIO_OUTPUT_LOW,
3553 gpio_port);
3554}
3555
3556/******************************************************************/
3557/* BCM8705 PHY SECTION */
3558/******************************************************************/
3559static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
3560 struct link_params *params,
3561 struct link_vars *vars)
3562{
3563 struct bnx2x *bp = params->bp;
3564 DP(NETIF_MSG_LINK, "init 8705\n");
3565 /* Restore normal power mode*/
3566 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3567 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3568 /* HW reset */
3569 bnx2x_ext_phy_hw_reset(bp, params->port);
3570 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
3571 bnx2x_wait_reset_complete(bp, phy);
2299 3572
2300 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2301 bnx2x_cl45_write(bp, phy, 3573 bnx2x_cl45_write(bp, phy,
2302 MDIO_PMA_DEVAD, 3574 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
2303 MDIO_PMA_REG_MISC_CTRL1, 0x0000); 3575 bnx2x_cl45_write(bp, phy,
3576 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
3577 bnx2x_cl45_write(bp, phy,
3578 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
3579 bnx2x_cl45_write(bp, phy,
3580 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
3581 /* BCM8705 doesn't have microcode, hence the 0 */
3582 bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
3583 return 0;
3584}
2304 3585
2305 msleep(200); 3586static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
2306 bnx2x_save_bcm_spirom_ver(bp, phy, params->port); 3587 struct link_params *params,
3588 struct link_vars *vars)
3589{
3590 u8 link_up = 0;
3591 u16 val1, rx_sd;
3592 struct bnx2x *bp = params->bp;
3593 DP(NETIF_MSG_LINK, "read status 8705\n");
3594 bnx2x_cl45_read(bp, phy,
3595 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
3596 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3597
3598 bnx2x_cl45_read(bp, phy,
3599 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
3600 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3601
3602 bnx2x_cl45_read(bp, phy,
3603 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
3604
3605 bnx2x_cl45_read(bp, phy,
3606 MDIO_PMA_DEVAD, 0xc809, &val1);
3607 bnx2x_cl45_read(bp, phy,
3608 MDIO_PMA_DEVAD, 0xc809, &val1);
3609
3610 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
3611 link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
3612 if (link_up) {
3613 vars->line_speed = SPEED_10000;
3614 bnx2x_ext_phy_resolve_fc(phy, params, vars);
3615 }
3616 return link_up;
2307} 3617}
2308 3618
3619/******************************************************************/
3620/* SFP+ module Section */
3621/******************************************************************/
2309static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, 3622static void bnx2x_sfp_set_transmitter(struct bnx2x *bp,
2310 struct bnx2x_phy *phy, 3623 struct bnx2x_phy *phy,
2311 u8 port, 3624 u8 port,
@@ -2392,7 +3705,7 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
2392 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); 3705 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2393 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == 3706 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2394 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) 3707 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2395 return 0; 3708 return 0;;
2396 msleep(1); 3709 msleep(1);
2397 } 3710 }
2398 return -EINVAL; 3711 return -EINVAL;
@@ -2637,6 +3950,64 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
2637 return -EINVAL; 3950 return -EINVAL;
2638} 3951}
2639 3952
3953static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
3954 struct link_params *params)
3955
3956{
3957 u8 val;
3958 struct bnx2x *bp = params->bp;
3959 u16 timeout;
3960 /* Initialization time after hot-plug may take up to 300ms for some
3961 phys type ( e.g. JDSU ) */
3962 for (timeout = 0; timeout < 60; timeout++) {
3963 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
3964 == 0) {
3965 DP(NETIF_MSG_LINK, "SFP+ module initialization "
3966 "took %d ms\n", timeout * 5);
3967 return 0;
3968 }
3969 msleep(5);
3970 }
3971 return -EINVAL;
3972}
3973
3974static void bnx2x_8727_power_module(struct bnx2x *bp,
3975 struct bnx2x_phy *phy,
3976 u8 is_power_up) {
3977 /* Make sure GPIOs are not using for LED mode */
3978 u16 val;
3979 /*
3980 * In the GPIO register, bit 4 is use to detemine if the GPIOs are
3981 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
3982 * output
3983 * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
3984 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
3985 * where the 1st bit is the over-current(only input), and 2nd bit is
3986 * for power( only output )
3987 */
3988
3989 /*
3990 * In case of NOC feature is disabled and power is up, set GPIO control
3991 * as input to enable listening of over-current indication
3992 */
3993 if (phy->flags & FLAGS_NOC)
3994 return;
3995 if (!(phy->flags &
3996 FLAGS_NOC) && is_power_up)
3997 val = (1<<4);
3998 else
3999 /*
4000 * Set GPIO control to OUTPUT, and set the power bit
4001 * to according to the is_power_up
4002 */
4003 val = ((!(is_power_up)) << 1);
4004
4005 bnx2x_cl45_write(bp, phy,
4006 MDIO_PMA_DEVAD,
4007 MDIO_PMA_REG_8727_GPIO_CTRL,
4008 val);
4009}
4010
2640static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, 4011static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
2641 struct bnx2x_phy *phy, 4012 struct bnx2x_phy *phy,
2642 u16 edc_mode) 4013 u16 edc_mode)
@@ -2721,65 +4092,6 @@ static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
2721 return 0; 4092 return 0;
2722} 4093}
2723 4094
2724
2725static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
2726 struct link_params *params)
2727
2728{
2729 u8 val;
2730 struct bnx2x *bp = params->bp;
2731 u16 timeout;
2732 /* Initialization time after hot-plug may take up to 300ms for some
2733 phys type ( e.g. JDSU ) */
2734 for (timeout = 0; timeout < 60; timeout++) {
2735 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
2736 == 0) {
2737 DP(NETIF_MSG_LINK, "SFP+ module initialization "
2738 "took %d ms\n", timeout * 5);
2739 return 0;
2740 }
2741 msleep(5);
2742 }
2743 return -EINVAL;
2744}
2745
2746static void bnx2x_8727_power_module(struct bnx2x *bp,
2747 struct bnx2x_phy *phy,
2748 u8 is_power_up) {
2749 /* Make sure GPIOs are not using for LED mode */
2750 u16 val;
2751 /*
2752 * In the GPIO register, bit 4 is use to detemine if the GPIOs are
2753 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
2754 * output
2755 * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
2756 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
2757 * where the 1st bit is the over-current(only input), and 2nd bit is
2758 * for power( only output )
2759 */
2760
2761 /*
2762 * In case of NOC feature is disabled and power is up, set GPIO control
2763 * as input to enable listening of over-current indication
2764 */
2765 if (phy->flags & FLAGS_NOC)
2766 return;
2767 if (!(phy->flags &
2768 FLAGS_NOC) && is_power_up)
2769 val = (1<<4);
2770 else
2771 /*
2772 * Set GPIO control to OUTPUT, and set the power bit
2773 * to according to the is_power_up
2774 */
2775 val = ((!(is_power_up)) << 1);
2776
2777 bnx2x_cl45_write(bp, phy,
2778 MDIO_PMA_DEVAD,
2779 MDIO_PMA_REG_8727_GPIO_CTRL,
2780 val);
2781}
2782
2783static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, 4095static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
2784 struct link_params *params) 4096 struct link_params *params)
2785{ 4097{
@@ -2889,276 +4201,56 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
2889 } 4201 }
2890} 4202}
2891 4203
2892static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy) 4204/******************************************************************/
2893{ 4205/* common BCM8706/BCM8726 PHY SECTION */
2894 /* Force KR or KX */ 4206/******************************************************************/
2895 bnx2x_cl45_write(bp, phy, 4207static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
2896 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); 4208 struct link_params *params,
2897 bnx2x_cl45_write(bp, phy,
2898 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
2899 bnx2x_cl45_write(bp, phy,
2900 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
2901 bnx2x_cl45_write(bp, phy,
2902 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
2903}
2904
2905static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp,
2906 struct bnx2x_phy *phy)
2907{
2908 u16 val;
2909 bnx2x_cl45_read(bp, phy,
2910 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val);
2911
2912 if (val == 0) {
2913 /* Mustn't set low power mode in 8073 A0 */
2914 return;
2915 }
2916
2917 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2918 bnx2x_cl45_read(bp, phy,
2919 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
2920 val &= ~(1<<13);
2921 bnx2x_cl45_write(bp, phy,
2922 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2923
2924 /* PLL controls */
2925 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077);
2926 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000);
2927 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B);
2928 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240);
2929 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490);
2930
2931 /* Tx Controls */
2932 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2933 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041);
2934 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640);
2935
2936 /* Rx Controls */
2937 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2938 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249);
2939 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015);
2940
2941 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2942 bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
2943 val |= (1<<13);
2944 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2945}
2946
2947static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2948 struct bnx2x_phy *phy,
2949 struct link_vars *vars) 4209 struct link_vars *vars)
2950{ 4210{
2951 u16 cl37_val; 4211 u8 link_up = 0;
4212 u16 val1, val2, rx_sd, pcs_status;
2952 struct bnx2x *bp = params->bp; 4213 struct bnx2x *bp = params->bp;
4214 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
4215 /* Clear RX Alarm*/
2953 bnx2x_cl45_read(bp, phy, 4216 bnx2x_cl45_read(bp, phy,
2954 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val); 4217 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
2955 4218 /* clear LASI indication*/
2956 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2957 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2958 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2959 if ((vars->ieee_fc &
2960 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2961 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2962 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2963 }
2964 if ((vars->ieee_fc &
2965 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2966 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2967 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2968 }
2969 if ((vars->ieee_fc &
2970 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2971 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2972 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2973 }
2974 DP(NETIF_MSG_LINK,
2975 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2976
2977 bnx2x_cl45_write(bp, phy,
2978 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
2979 msleep(500);
2980}
2981
2982static void bnx2x_ext_phy_set_pause(struct link_params *params,
2983 struct bnx2x_phy *phy,
2984 struct link_vars *vars)
2985{
2986 u16 val;
2987 struct bnx2x *bp = params->bp;
2988 /* read modify write pause advertizing */
2989 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
2990
2991 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2992
2993 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2994 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2995 if ((vars->ieee_fc &
2996 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2997 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2998 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2999 }
3000 if ((vars->ieee_fc &
3001 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3002 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3003 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3004 }
3005 DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3006 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3007}
3008
3009static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
3010 struct link_params *params)
3011{
3012
3013 u16 bank, i = 0;
3014 struct bnx2x *bp = params->bp;
3015
3016 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
3017 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
3018 CL45_WR_OVER_CL22(bp, phy,
3019 bank,
3020 MDIO_RX0_RX_EQ_BOOST,
3021 phy->rx_preemphasis[i]);
3022 }
3023
3024 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
3025 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
3026 CL45_WR_OVER_CL22(bp, phy,
3027 bank,
3028 MDIO_TX0_TX_DRIVER,
3029 phy->tx_preemphasis[i]);
3030 }
3031}
3032
3033static void bnx2x_848xx_set_led(struct bnx2x *bp,
3034 struct bnx2x_phy *phy)
3035{
3036 u16 val;
3037
3038 /* PHYC_CTL_LED_CTL */
3039 bnx2x_cl45_read(bp, phy, 4219 bnx2x_cl45_read(bp, phy,
3040 MDIO_PMA_DEVAD, 4220 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
3041 MDIO_PMA_REG_8481_LINK_SIGNAL, &val); 4221 bnx2x_cl45_read(bp, phy,
3042 val &= 0xFE00; 4222 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
3043 val |= 0x0092; 4223 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
3044
3045 bnx2x_cl45_write(bp, phy,
3046 MDIO_PMA_DEVAD,
3047 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
3048
3049 bnx2x_cl45_write(bp, phy,
3050 MDIO_PMA_DEVAD,
3051 MDIO_PMA_REG_8481_LED1_MASK,
3052 0x80);
3053
3054 bnx2x_cl45_write(bp, phy,
3055 MDIO_PMA_DEVAD,
3056 MDIO_PMA_REG_8481_LED2_MASK,
3057 0x18);
3058
3059 bnx2x_cl45_write(bp, phy,
3060 MDIO_PMA_DEVAD,
3061 MDIO_PMA_REG_8481_LED3_MASK,
3062 0x0040);
3063
3064 /* 'Interrupt Mask' */
3065 bnx2x_cl45_write(bp, phy,
3066 MDIO_AN_DEVAD,
3067 0xFFFB, 0xFFFD);
3068}
3069
3070static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
3071 struct link_params *params,
3072 struct link_vars *vars)
3073{
3074 struct bnx2x *bp = params->bp;
3075 u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
3076 (params->loopback_mode == LOOPBACK_XGXS_10));
3077 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
3078 if (SINGLE_MEDIA_DIRECT(params) &&
3079 (params->feature_config_flags &
3080 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
3081 bnx2x_set_preemphasis(phy, params);
3082
3083 /* forced speed requested? */
3084 if (vars->line_speed != SPEED_AUTO_NEG ||
3085 (SINGLE_MEDIA_DIRECT(params) &&
3086 params->loopback_mode == LOOPBACK_EXT)) {
3087 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3088
3089 /* disable autoneg */
3090 bnx2x_set_autoneg(phy, params, vars, 0);
3091
3092 /* program speed and duplex */
3093 bnx2x_program_serdes(phy, params, vars);
3094
3095 } else { /* AN_mode */
3096 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3097
3098 /* AN enabled */
3099 bnx2x_set_brcm_cl37_advertisment(phy, params);
3100
3101 /* program duplex & pause advertisement (for aneg) */
3102 bnx2x_set_ieee_aneg_advertisment(phy, params,
3103 vars->ieee_fc);
3104
3105 /* enable autoneg */
3106 bnx2x_set_autoneg(phy, params, vars, enable_cl73);
3107
3108 /* enable and restart AN */
3109 bnx2x_restart_autoneg(phy, params, enable_cl73);
3110 }
3111
3112 } else { /* SGMII mode */
3113 DP(NETIF_MSG_LINK, "SGMII\n");
3114 4224
3115 bnx2x_initialize_sgmii_process(phy, params, vars); 4225 bnx2x_cl45_read(bp, phy,
3116 } 4226 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
3117} 4227 bnx2x_cl45_read(bp, phy,
4228 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
4229 bnx2x_cl45_read(bp, phy,
4230 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
4231 bnx2x_cl45_read(bp, phy,
4232 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
3118 4233
3119static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, 4234 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
3120 struct bnx2x_phy *phy) 4235 " link_status 0x%x\n", rx_sd, pcs_status, val2);
3121{ 4236 /* link is up if both bit 0 of pmd_rx_sd and
3122 u16 cnt, ctrl; 4237 * bit 0 of pcs_status are set, or if the autoneg bit
3123 /* Wait for soft reset to get cleared upto 1 sec */ 4238 * 1 is set
3124 for (cnt = 0; cnt < 1000; cnt++) { 4239 */
3125 bnx2x_cl45_read(bp, phy, 4240 link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
3126 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl); 4241 if (link_up) {
3127 if (!(ctrl & (1<<15))) 4242 if (val2 & (1<<1))
3128 break; 4243 vars->line_speed = SPEED_1000;
3129 msleep(1); 4244 else
4245 vars->line_speed = SPEED_10000;
4246 bnx2x_ext_phy_resolve_fc(phy, params, vars);
3130 } 4247 }
3131 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt); 4248 return link_up;
3132 return cnt;
3133}
3134
3135static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
3136 struct link_params *params,
3137 struct link_vars *vars)
3138{
3139 struct bnx2x *bp = params->bp;
3140 DP(NETIF_MSG_LINK, "init 8705\n");
3141 /* Restore normal power mode*/
3142 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3143 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3144 /* HW reset */
3145 bnx2x_ext_phy_hw_reset(bp, params->port);
3146 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
3147 bnx2x_wait_reset_complete(bp, phy);
3148
3149 bnx2x_cl45_write(bp, phy,
3150 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
3151 bnx2x_cl45_write(bp, phy,
3152 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
3153 bnx2x_cl45_write(bp, phy,
3154 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
3155 bnx2x_cl45_write(bp, phy,
3156 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
3157 /* BCM8705 doesn't have microcode, hence the 0 */
3158 bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
3159 return 0;
3160} 4249}
3161 4250
4251/******************************************************************/
4252/* BCM8706 PHY SECTION */
4253/******************************************************************/
3162static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, 4254static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
3163 struct link_params *params, 4255 struct link_params *params,
3164 struct link_vars *vars) 4256 struct link_vars *vars)
@@ -3240,6 +4332,83 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
3240 return 0; 4332 return 0;
3241} 4333}
3242 4334
4335static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
4336 struct link_params *params,
4337 struct link_vars *vars)
4338{
4339 return bnx2x_8706_8726_read_status(phy, params, vars);
4340}
4341
4342/******************************************************************/
4343/* BCM8726 PHY SECTION */
4344/******************************************************************/
4345static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
4346 struct link_params *params)
4347{
4348 struct bnx2x *bp = params->bp;
4349 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4350 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
4351}
4352
4353static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
4354 struct link_params *params)
4355{
4356 struct bnx2x *bp = params->bp;
4357 /* Need to wait 100ms after reset */
4358 msleep(100);
4359
4360 /* Micro controller re-boot */
4361 bnx2x_cl45_write(bp, phy,
4362 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
4363
4364 /* Set soft reset */
4365 bnx2x_cl45_write(bp, phy,
4366 MDIO_PMA_DEVAD,
4367 MDIO_PMA_REG_GEN_CTRL,
4368 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
4369
4370 bnx2x_cl45_write(bp, phy,
4371 MDIO_PMA_DEVAD,
4372 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
4373
4374 bnx2x_cl45_write(bp, phy,
4375 MDIO_PMA_DEVAD,
4376 MDIO_PMA_REG_GEN_CTRL,
4377 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
4378
4379 /* wait for 150ms for microcode load */
4380 msleep(150);
4381
4382 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
4383 bnx2x_cl45_write(bp, phy,
4384 MDIO_PMA_DEVAD,
4385 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
4386
4387 msleep(200);
4388 bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
4389}
4390
4391static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
4392 struct link_params *params,
4393 struct link_vars *vars)
4394{
4395 struct bnx2x *bp = params->bp;
4396 u16 val1;
4397 u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
4398 if (link_up) {
4399 bnx2x_cl45_read(bp, phy,
4400 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
4401 &val1);
4402 if (val1 & (1<<15)) {
4403 DP(NETIF_MSG_LINK, "Tx is disabled\n");
4404 link_up = 0;
4405 vars->line_speed = 0;
4406 }
4407 }
4408 return link_up;
4409}
4410
4411
3243static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, 4412static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
3244 struct link_params *params, 4413 struct link_params *params,
3245 struct link_vars *vars) 4414 struct link_vars *vars)
@@ -3356,136 +4525,35 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
3356 4525
3357} 4526}
3358 4527
3359static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, 4528static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
3360 struct link_params *params, 4529 struct link_params *params)
3361 struct link_vars *vars)
3362{ 4530{
3363 struct bnx2x *bp = params->bp; 4531 struct bnx2x *bp = params->bp;
3364 u16 val = 0, tmp1; 4532 DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
3365 u8 gpio_port; 4533 /* Set serial boot control for external load */
3366 DP(NETIF_MSG_LINK, "Init 8073\n");
3367
3368 gpio_port = params->port;
3369 /* Restore normal power mode*/
3370 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3371 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
3372
3373 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3374 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
3375
3376 /* enable LASI */
3377 bnx2x_cl45_write(bp, phy,
3378 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
3379 bnx2x_cl45_write(bp, phy,
3380 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
3381
3382 bnx2x_8073_set_pause_cl37(params, phy, vars);
3383
3384 bnx2x_8073_set_xaui_low_power_mode(bp, phy);
3385
3386 bnx2x_cl45_read(bp, phy,
3387 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
3388
3389 bnx2x_cl45_read(bp, phy,
3390 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
3391
3392 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
3393
3394 /* Enable CL37 BAM */
3395 bnx2x_cl45_read(bp, phy,
3396 MDIO_AN_DEVAD,
3397 MDIO_AN_REG_8073_BAM, &val);
3398 bnx2x_cl45_write(bp, phy, 4534 bnx2x_cl45_write(bp, phy,
3399 MDIO_AN_DEVAD, 4535 MDIO_PMA_DEVAD,
3400 MDIO_AN_REG_8073_BAM, val | 1); 4536 MDIO_PMA_REG_GEN_CTRL, 0x0001);
3401
3402 if (params->loopback_mode == LOOPBACK_EXT) {
3403 bnx2x_807x_force_10G(bp, phy);
3404 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
3405 return 0;
3406 } else {
3407 bnx2x_cl45_write(bp, phy,
3408 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
3409 }
3410 if (phy->req_line_speed != SPEED_AUTO_NEG) {
3411 if (phy->req_line_speed == SPEED_10000) {
3412 val = (1<<7);
3413 } else if (phy->req_line_speed == SPEED_2500) {
3414 val = (1<<5);
3415 /* Note that 2.5G works only
3416 when used with 1G advertisment */
3417 } else
3418 val = (1<<5);
3419 } else {
3420 val = 0;
3421 if (phy->speed_cap_mask &
3422 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3423 val |= (1<<7);
3424
3425 /* Note that 2.5G works only when
3426 used with 1G advertisment */
3427 if (phy->speed_cap_mask &
3428 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3429 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3430 val |= (1<<5);
3431 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
3432 }
3433
3434 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
3435 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
3436
3437 if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3438 (phy->req_line_speed == SPEED_AUTO_NEG)) ||
3439 (phy->req_line_speed == SPEED_2500)) {
3440 u16 phy_ver;
3441 /* Allow 2.5G for A1 and above */
3442 bnx2x_cl45_read(bp, phy,
3443 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
3444 &phy_ver);
3445 DP(NETIF_MSG_LINK, "Add 2.5G\n");
3446 if (phy_ver > 0)
3447 tmp1 |= 1;
3448 else
3449 tmp1 &= 0xfffe;
3450 } else {
3451 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3452 tmp1 &= 0xfffe;
3453 }
3454
3455 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
3456 /* Add support for CL37 (passive mode) II */
3457
3458 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
3459 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
3460 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
3461 0x20 : 0x40)));
3462
3463 /* Add support for CL37 (passive mode) III */
3464 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
3465
3466 /* The SNR will improve about 2db by changing
3467 BW and FEE main tap. Rest commands are executed
3468 after link is up*/
3469 if (bnx2x_8073_is_snr_needed(bp, phy))
3470 bnx2x_cl45_write(bp, phy,
3471 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
3472 0xFB0C);
3473
3474 /* Enable FEC (Forware Error Correction) Request in the AN */
3475 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
3476 tmp1 |= (1<<15);
3477 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
3478
3479 bnx2x_ext_phy_set_pause(params, phy, vars);
3480
3481 /* Restart autoneg */
3482 msleep(500);
3483 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
3484 DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
3485 ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
3486 return 0;
3487} 4537}
3488 4538
4539/******************************************************************/
4540/* BCM8727 PHY SECTION */
4541/******************************************************************/
4542static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
4543 struct link_params *params) {
4544 u32 swap_val, swap_override;
4545 u8 port;
4546 /**
4547 * The PHY reset is controlled by GPIO 1. Fake the port number
4548 * to cancel the swap done in set_gpio()
4549 */
4550 struct bnx2x *bp = params->bp;
4551 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
4552 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
4553 port = (swap_val && swap_override) ^ 1;
4554 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4555 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
4556}
3489 4557
3490static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, 4558static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
3491 struct link_params *params, 4559 struct link_params *params,
@@ -3586,7 +4654,6 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
3586 0x0008); 4654 0x0008);
3587 } 4655 }
3588 4656
3589
3590 /* Set 2-wire transfer rate of SFP+ module EEPROM 4657 /* Set 2-wire transfer rate of SFP+ module EEPROM
3591 * to 100Khz since some DACs(direct attached cables) do 4658 * to 100Khz since some DACs(direct attached cables) do
3592 * not work at 400Khz. 4659 * not work at 400Khz.
@@ -3613,225 +4680,6 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
3613 return 0; 4680 return 0;
3614} 4681}
3615 4682
3616static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
3617 struct link_params *params,
3618 struct link_vars *vars)
3619{
3620 u16 fw_ver1, fw_ver2, val;
3621 struct bnx2x *bp = params->bp;
3622 DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
3623
3624 /* Restore normal power mode*/
3625 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3626 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3627 /* HW reset */
3628 bnx2x_ext_phy_hw_reset(bp, params->port);
3629 bnx2x_wait_reset_complete(bp, phy);
3630
3631 bnx2x_cl45_write(bp, phy,
3632 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
3633 DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
3634 bnx2x_cl45_write(bp, phy,
3635 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
3636
3637 bnx2x_ext_phy_set_pause(params, phy, vars);
3638 /* Restart autoneg */
3639 bnx2x_cl45_read(bp, phy,
3640 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
3641 val |= 0x200;
3642 bnx2x_cl45_write(bp, phy,
3643 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
3644
3645 /* Save spirom version */
3646 bnx2x_cl45_read(bp, phy,
3647 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
3648
3649 bnx2x_cl45_read(bp, phy,
3650 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
3651 bnx2x_save_spirom_version(bp, params->port,
3652 (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
3653 return 0;
3654}
3655
3656static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
3657 struct link_params *params,
3658 struct link_vars *vars)
3659{
3660 struct bnx2x *bp = params->bp;
3661 u16 autoneg_val, an_1000_val, an_10_100_val;
3662 bnx2x_wait_reset_complete(bp, phy);
3663 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
3664 1 << NIG_LATCH_BC_ENABLE_MI_INT);
3665
3666 bnx2x_cl45_write(bp, phy,
3667 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
3668 bnx2x_848xx_set_led(bp, phy);
3669 /* set 1000 speed advertisement */
3670 bnx2x_cl45_read(bp, phy,
3671 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
3672 &an_1000_val);
3673
3674 bnx2x_ext_phy_set_pause(params, phy, vars);
3675 bnx2x_cl45_read(bp, phy,
3676 MDIO_AN_DEVAD,
3677 MDIO_AN_REG_8481_LEGACY_AN_ADV,
3678 &an_10_100_val);
3679 bnx2x_cl45_read(bp, phy,
3680 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
3681 &autoneg_val);
3682 /* Disable forced speed */
3683 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
3684 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
3685
3686 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
3687 (phy->speed_cap_mask &
3688 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3689 (phy->req_line_speed == SPEED_1000)) {
3690 an_1000_val |= (1<<8);
3691 autoneg_val |= (1<<9 | 1<<12);
3692 if (phy->req_duplex == DUPLEX_FULL)
3693 an_1000_val |= (1<<9);
3694 DP(NETIF_MSG_LINK, "Advertising 1G\n");
3695 } else
3696 an_1000_val &= ~((1<<8) | (1<<9));
3697
3698 bnx2x_cl45_write(bp, phy,
3699 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
3700 an_1000_val);
3701
3702 /* set 10 speed advertisement */
3703 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
3704 (phy->speed_cap_mask &
3705 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
3706 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
3707 an_10_100_val |= (1<<7);
3708 /* Enable autoneg and restart autoneg for legacy speeds */
3709 autoneg_val |= (1<<9 | 1<<12);
3710
3711 if (phy->req_duplex == DUPLEX_FULL)
3712 an_10_100_val |= (1<<8);
3713 DP(NETIF_MSG_LINK, "Advertising 100M\n");
3714 }
3715 /* set 10 speed advertisement */
3716 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
3717 (phy->speed_cap_mask &
3718 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
3719 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
3720 an_10_100_val |= (1<<5);
3721 autoneg_val |= (1<<9 | 1<<12);
3722 if (phy->req_duplex == DUPLEX_FULL)
3723 an_10_100_val |= (1<<6);
3724 DP(NETIF_MSG_LINK, "Advertising 10M\n");
3725 }
3726
3727 /* Only 10/100 are allowed to work in FORCE mode */
3728 if (phy->req_line_speed == SPEED_100) {
3729 autoneg_val |= (1<<13);
3730 /* Enabled AUTO-MDIX when autoneg is disabled */
3731 bnx2x_cl45_write(bp, phy,
3732 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
3733 (1<<15 | 1<<9 | 7<<0));
3734 DP(NETIF_MSG_LINK, "Setting 100M force\n");
3735 }
3736 if (phy->req_line_speed == SPEED_10) {
3737 /* Enabled AUTO-MDIX when autoneg is disabled */
3738 bnx2x_cl45_write(bp, phy,
3739 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
3740 (1<<15 | 1<<9 | 7<<0));
3741 DP(NETIF_MSG_LINK, "Setting 10M force\n");
3742 }
3743
3744 bnx2x_cl45_write(bp, phy,
3745 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
3746 an_10_100_val);
3747
3748 if (phy->req_duplex == DUPLEX_FULL)
3749 autoneg_val |= (1<<8);
3750
3751 bnx2x_cl45_write(bp, phy,
3752 MDIO_AN_DEVAD,
3753 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
3754
3755 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
3756 (phy->speed_cap_mask &
3757 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3758 (phy->req_line_speed == SPEED_10000)) {
3759 DP(NETIF_MSG_LINK, "Advertising 10G\n");
3760 /* Restart autoneg for 10G*/
3761
3762 bnx2x_cl45_write(bp, phy,
3763 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
3764 0x3200);
3765 } else if (phy->req_line_speed != SPEED_10 &&
3766 phy->req_line_speed != SPEED_100) {
3767 bnx2x_cl45_write(bp, phy,
3768 MDIO_AN_DEVAD,
3769 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
3770 1);
3771 }
3772 /* Save spirom version */
3773 bnx2x_save_848xx_spirom_version(phy, params);
3774
3775 return 0;
3776}
3777
3778static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
3779 struct link_params *params,
3780 struct link_vars *vars)
3781{
3782 struct bnx2x *bp = params->bp;
3783 u16 temp;
3784 msleep(1);
3785 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
3786 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
3787 params->port);
3788 msleep(200); /* 100 is not enough */
3789
3790 /**
3791 * BCM84823 requires that XGXS links up first @ 10G for normal
3792 * behavior
3793 */
3794 temp = vars->line_speed;
3795 vars->line_speed = SPEED_10000;
3796 bnx2x_set_autoneg(phy, params, vars, 0);
3797 bnx2x_program_serdes(phy, params, vars);
3798 vars->line_speed = temp;
3799 return bnx2x_848xx_cmn_config_init(phy, params, vars);
3800}
3801
3802static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
3803 struct link_params *params,
3804 struct link_vars *vars)
3805{
3806 struct bnx2x *bp = params->bp;
3807 /* Restore normal power mode*/
3808 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3809 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3810
3811 /* HW reset */
3812 bnx2x_ext_phy_hw_reset(bp, params->port);
3813
3814 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
3815 return bnx2x_848xx_cmn_config_init(phy, params, vars);
3816}
3817
3818
3819static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
3820 struct bnx2x_phy *phy,
3821 struct link_vars *vars)
3822{
3823 u16 val;
3824 bnx2x_cl45_read(bp, phy,
3825 MDIO_AN_DEVAD,
3826 MDIO_AN_REG_STATUS, &val);
3827 bnx2x_cl45_read(bp, phy,
3828 MDIO_AN_DEVAD,
3829 MDIO_AN_REG_STATUS, &val);
3830 if (val & (1<<5))
3831 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
3832 if ((val & (1<<0)) == 0)
3833 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
3834}
3835static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, 4683static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
3836 struct link_params *params) 4684 struct link_params *params)
3837{ 4685{
@@ -3910,110 +4758,6 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
3910 module plugged in/out */ 4758 module plugged in/out */
3911} 4759}
3912 4760
3913
3914static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
3915 struct link_params *params,
3916 struct link_vars *vars)
3917{
3918 u8 link_up = 0;
3919 u16 val1, rx_sd;
3920 struct bnx2x *bp = params->bp;
3921 DP(NETIF_MSG_LINK, "read status 8705\n");
3922 bnx2x_cl45_read(bp, phy,
3923 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
3924 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3925
3926 bnx2x_cl45_read(bp, phy,
3927 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
3928 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3929
3930 bnx2x_cl45_read(bp, phy,
3931 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
3932
3933 bnx2x_cl45_read(bp, phy,
3934 MDIO_PMA_DEVAD, 0xc809, &val1);
3935 bnx2x_cl45_read(bp, phy,
3936 MDIO_PMA_DEVAD, 0xc809, &val1);
3937
3938 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
3939 link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
3940 if (link_up) {
3941 vars->line_speed = SPEED_10000;
3942 bnx2x_ext_phy_resolve_fc(phy, params, vars);
3943 }
3944 return link_up;
3945}
3946
3947static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
3948 struct link_params *params,
3949 struct link_vars *vars)
3950{
3951 u8 link_up = 0;
3952 u16 val1, val2, rx_sd, pcs_status;
3953 struct bnx2x *bp = params->bp;
3954 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3955 /* Clear RX Alarm*/
3956 bnx2x_cl45_read(bp, phy,
3957 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
3958 /* clear LASI indication*/
3959 bnx2x_cl45_read(bp, phy,
3960 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
3961 bnx2x_cl45_read(bp, phy,
3962 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
3963 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
3964
3965 bnx2x_cl45_read(bp, phy,
3966 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
3967 bnx2x_cl45_read(bp, phy,
3968 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
3969 bnx2x_cl45_read(bp, phy,
3970 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
3971 bnx2x_cl45_read(bp, phy,
3972 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
3973
3974 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
3975 " link_status 0x%x\n", rx_sd, pcs_status, val2);
3976 /* link is up if both bit 0 of pmd_rx_sd and
3977 * bit 0 of pcs_status are set, or if the autoneg bit
3978 * 1 is set
3979 */
3980 link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
3981 if (link_up) {
3982 if (val2 & (1<<1))
3983 vars->line_speed = SPEED_1000;
3984 else
3985 vars->line_speed = SPEED_10000;
3986 bnx2x_ext_phy_resolve_fc(phy, params, vars);
3987 }
3988 return link_up;
3989}
3990static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
3991 struct link_params *params,
3992 struct link_vars *vars)
3993{
3994 return bnx2x_8706_8726_read_status(phy, params, vars);
3995}
3996
3997static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
3998 struct link_params *params,
3999 struct link_vars *vars)
4000{
4001 struct bnx2x *bp = params->bp;
4002 u16 val1;
4003 u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
4004 if (link_up) {
4005 bnx2x_cl45_read(bp, phy,
4006 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
4007 &val1);
4008 if (val1 & (1<<15)) {
4009 DP(NETIF_MSG_LINK, "Tx is disabled\n");
4010 link_up = 0;
4011 vars->line_speed = 0;
4012 }
4013 }
4014 return link_up;
4015}
4016
4017static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, 4761static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
4018 struct link_params *params, 4762 struct link_params *params,
4019 struct link_vars *vars) 4763 struct link_vars *vars)
@@ -4126,184 +4870,275 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
4126 return link_up; 4870 return link_up;
4127} 4871}
4128 4872
4129static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, 4873static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
4130 struct link_params *params, 4874 struct link_params *params)
4131 struct link_vars *vars)
4132{ 4875{
4133 struct bnx2x *bp = params->bp; 4876 struct bnx2x *bp = params->bp;
4134 if (phy->req_line_speed == SPEED_10 || 4877 /* Disable Transmitter */
4135 phy->req_line_speed == SPEED_100) { 4878 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
4136 vars->flow_ctrl = phy->req_flow_ctrl; 4879}
4880
4881/******************************************************************/
4882/* BCM8481/BCM84823/BCM84833 PHY SECTION */
4883/******************************************************************/
4884static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
4885 struct link_params *params)
4886{
4887 u16 val, fw_ver1, fw_ver2, cnt;
4888 struct bnx2x *bp = params->bp;
4889
4890 /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
4891 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
4892 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
4893 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
4894 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
4895 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
4896 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
4897
4898 for (cnt = 0; cnt < 100; cnt++) {
4899 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
4900 if (val & 1)
4901 break;
4902 udelay(5);
4903 }
4904 if (cnt == 100) {
4905 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
4906 bnx2x_save_spirom_version(bp, params->port, 0,
4907 phy->ver_addr);
4137 return; 4908 return;
4138 } 4909 }
4139 4910
4140 if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
4141 (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
4142 u16 pause_result;
4143 u16 ld_pause; /* local */
4144 u16 lp_pause; /* link partner */
4145 bnx2x_cl45_read(bp, phy,
4146 MDIO_AN_DEVAD,
4147 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
4148
4149 bnx2x_cl45_read(bp, phy,
4150 MDIO_AN_DEVAD,
4151 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
4152 pause_result = (ld_pause &
4153 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
4154 pause_result |= (lp_pause &
4155 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
4156 4911
4157 bnx2x_pause_resolve(vars, pause_result); 4912 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
4158 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n", 4913 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
4159 pause_result); 4914 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
4915 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
4916 for (cnt = 0; cnt < 100; cnt++) {
4917 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
4918 if (val & 1)
4919 break;
4920 udelay(5);
4921 }
4922 if (cnt == 100) {
4923 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
4924 bnx2x_save_spirom_version(bp, params->port, 0,
4925 phy->ver_addr);
4926 return;
4160 } 4927 }
4928
4929 /* lower 16 bits of the register SPI_FW_STATUS */
4930 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
4931 /* upper 16 bits of register SPI_FW_STATUS */
4932 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
4933
4934 bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
4935 phy->ver_addr);
4161} 4936}
4162static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, 4937
4163 struct link_params *params, 4938static void bnx2x_848xx_set_led(struct bnx2x *bp,
4164 struct link_vars *vars) 4939 struct bnx2x_phy *phy)
4165{ 4940{
4166 struct bnx2x *bp = params->bp; 4941 u16 val;
4167 u8 link_up = 0;
4168 u16 val1, val2;
4169 u16 link_status = 0;
4170 u16 an1000_status = 0;
4171 4942
4943 /* PHYC_CTL_LED_CTL */
4172 bnx2x_cl45_read(bp, phy, 4944 bnx2x_cl45_read(bp, phy,
4173 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); 4945 MDIO_PMA_DEVAD,
4946 MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
4947 val &= 0xFE00;
4948 val |= 0x0092;
4174 4949
4175 DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1); 4950 bnx2x_cl45_write(bp, phy,
4951 MDIO_PMA_DEVAD,
4952 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
4176 4953
4177 /* clear the interrupt LASI status register */ 4954 bnx2x_cl45_write(bp, phy,
4178 bnx2x_cl45_read(bp, phy, 4955 MDIO_PMA_DEVAD,
4179 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); 4956 MDIO_PMA_REG_8481_LED1_MASK,
4180 bnx2x_cl45_read(bp, phy, 4957 0x80);
4181 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
4182 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
4183 /* Clear MSG-OUT */
4184 bnx2x_cl45_read(bp, phy,
4185 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
4186 4958
4187 /* Check the LASI */ 4959 bnx2x_cl45_write(bp, phy,
4188 bnx2x_cl45_read(bp, phy, 4960 MDIO_PMA_DEVAD,
4189 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); 4961 MDIO_PMA_REG_8481_LED2_MASK,
4962 0x18);
4190 4963
4191 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); 4964 bnx2x_cl45_write(bp, phy,
4965 MDIO_PMA_DEVAD,
4966 MDIO_PMA_REG_8481_LED3_MASK,
4967 0x0040);
4192 4968
4193 /* Check the link status */ 4969 /* 'Interrupt Mask' */
4194 bnx2x_cl45_read(bp, phy, 4970 bnx2x_cl45_write(bp, phy,
4195 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); 4971 MDIO_AN_DEVAD,
4196 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); 4972 0xFFFB, 0xFFFD);
4973}
4197 4974
4198 bnx2x_cl45_read(bp, phy, 4975static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
4199 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); 4976 struct link_params *params,
4200 bnx2x_cl45_read(bp, phy, 4977 struct link_vars *vars)
4201 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); 4978{
4202 link_up = ((val1 & 4) == 4); 4979 struct bnx2x *bp = params->bp;
4203 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); 4980 u16 autoneg_val, an_1000_val, an_10_100_val;
4981 /**
4982 * This phy uses the NIG latch mechanism since link indication
4983 * arrives through its LED4 and not via its LASI signal, so we
4984 * get steady signal instead of clear on read
4985 */
4986 bnx2x_wait_reset_complete(bp, phy);
4987 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
4988 1 << NIG_LATCH_BC_ENABLE_MI_INT);
4204 4989
4205 if (link_up && 4990 bnx2x_cl45_write(bp, phy,
4206 ((phy->req_line_speed != SPEED_10000))) { 4991 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
4207 if (bnx2x_8073_xaui_wa(bp, phy) != 0) 4992
4208 return 0; 4993 bnx2x_848xx_set_led(bp, phy);
4209 } 4994
4210 bnx2x_cl45_read(bp, phy, 4995 /* set 1000 speed advertisement */
4211 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4212 bnx2x_cl45_read(bp, phy, 4996 bnx2x_cl45_read(bp, phy,
4213 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); 4997 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
4998 &an_1000_val);
4214 4999
4215 /* Check the link status on 1.1.2 */ 5000 bnx2x_ext_phy_set_pause(params, phy, vars);
4216 bnx2x_cl45_read(bp, phy, 5001 bnx2x_cl45_read(bp, phy,
4217 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); 5002 MDIO_AN_DEVAD,
5003 MDIO_AN_REG_8481_LEGACY_AN_ADV,
5004 &an_10_100_val);
4218 bnx2x_cl45_read(bp, phy, 5005 bnx2x_cl45_read(bp, phy,
4219 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); 5006 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4220 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x," 5007 &autoneg_val);
4221 "an_link_status=0x%x\n", val2, val1, an1000_status); 5008 /* Disable forced speed */
5009 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
5010 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
4222 5011
4223 link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1))); 5012 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
4224 if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) { 5013 (phy->speed_cap_mask &
4225 /* The SNR will improve about 2dbby 5014 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
4226 changing the BW and FEE main tap.*/ 5015 (phy->req_line_speed == SPEED_1000)) {
4227 /* The 1st write to change FFE main 5016 an_1000_val |= (1<<8);
4228 tap is set before restart AN */ 5017 autoneg_val |= (1<<9 | 1<<12);
4229 /* Change PLL Bandwidth in EDC 5018 if (phy->req_duplex == DUPLEX_FULL)
4230 register */ 5019 an_1000_val |= (1<<9);
4231 bnx2x_cl45_write(bp, phy, 5020 DP(NETIF_MSG_LINK, "Advertising 1G\n");
4232 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH, 5021 } else
4233 0x26BC); 5022 an_1000_val &= ~((1<<8) | (1<<9));
4234 5023
4235 /* Change CDR Bandwidth in EDC register */ 5024 bnx2x_cl45_write(bp, phy,
4236 bnx2x_cl45_write(bp, phy, 5025 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
4237 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH, 5026 an_1000_val);
4238 0x0333); 5027
5028 /* set 10 speed advertisement */
5029 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5030 (phy->speed_cap_mask &
5031 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
5032 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
5033 an_10_100_val |= (1<<7);
5034 /* Enable autoneg and restart autoneg for legacy speeds */
5035 autoneg_val |= (1<<9 | 1<<12);
5036
5037 if (phy->req_duplex == DUPLEX_FULL)
5038 an_10_100_val |= (1<<8);
5039 DP(NETIF_MSG_LINK, "Advertising 100M\n");
5040 }
5041 /* set 10 speed advertisement */
5042 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5043 (phy->speed_cap_mask &
5044 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
5045 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
5046 an_10_100_val |= (1<<5);
5047 autoneg_val |= (1<<9 | 1<<12);
5048 if (phy->req_duplex == DUPLEX_FULL)
5049 an_10_100_val |= (1<<6);
5050 DP(NETIF_MSG_LINK, "Advertising 10M\n");
4239 } 5051 }
4240 bnx2x_cl45_read(bp, phy,
4241 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4242 &link_status);
4243 5052
4244 /* Bits 0..2 --> speed detected, bits 13..15--> link is down */ 5053 /* Only 10/100 are allowed to work in FORCE mode */
4245 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { 5054 if (phy->req_line_speed == SPEED_100) {
4246 link_up = 1; 5055 autoneg_val |= (1<<13);
4247 vars->line_speed = SPEED_10000; 5056 /* Enabled AUTO-MDIX when autoneg is disabled */
4248 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n", 5057 bnx2x_cl45_write(bp, phy,
4249 params->port); 5058 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
4250 } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) { 5059 (1<<15 | 1<<9 | 7<<0));
4251 link_up = 1; 5060 DP(NETIF_MSG_LINK, "Setting 100M force\n");
4252 vars->line_speed = SPEED_2500; 5061 }
4253 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n", 5062 if (phy->req_line_speed == SPEED_10) {
4254 params->port); 5063 /* Enabled AUTO-MDIX when autoneg is disabled */
4255 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { 5064 bnx2x_cl45_write(bp, phy,
4256 link_up = 1; 5065 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
4257 vars->line_speed = SPEED_1000; 5066 (1<<15 | 1<<9 | 7<<0));
4258 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", 5067 DP(NETIF_MSG_LINK, "Setting 10M force\n");
4259 params->port);
4260 } else {
4261 link_up = 0;
4262 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
4263 params->port);
4264 } 5068 }
4265 5069
4266 if (link_up) { 5070 bnx2x_cl45_write(bp, phy,
4267 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); 5071 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
4268 bnx2x_8073_resolve_fc(phy, params, vars); 5072 an_10_100_val);
5073
5074 if (phy->req_duplex == DUPLEX_FULL)
5075 autoneg_val |= (1<<8);
5076
5077 bnx2x_cl45_write(bp, phy,
5078 MDIO_AN_DEVAD,
5079 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
5080
5081 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5082 (phy->speed_cap_mask &
5083 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
5084 (phy->req_line_speed == SPEED_10000)) {
5085 DP(NETIF_MSG_LINK, "Advertising 10G\n");
5086 /* Restart autoneg for 10G*/
5087
5088 bnx2x_cl45_write(bp, phy,
5089 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
5090 0x3200);
5091 } else if (phy->req_line_speed != SPEED_10 &&
5092 phy->req_line_speed != SPEED_100) {
5093 bnx2x_cl45_write(bp, phy,
5094 MDIO_AN_DEVAD,
5095 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
5096 1);
4269 } 5097 }
4270 return link_up; 5098 /* Save spirom version */
5099 bnx2x_save_848xx_spirom_version(phy, params);
5100
5101 return 0;
4271} 5102}
4272 5103
4273static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, 5104static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
4274 struct link_params *params, 5105 struct link_params *params,
4275 struct link_vars *vars) 5106 struct link_vars *vars)
4276{ 5107{
4277 struct bnx2x *bp = params->bp; 5108 struct bnx2x *bp = params->bp;
4278 u8 link_up; 5109 /* Restore normal power mode*/
4279 u16 val1, val2; 5110 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4280 bnx2x_cl45_read(bp, phy, 5111 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
4281 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); 5112
4282 bnx2x_cl45_read(bp, phy, 5113 /* HW reset */
4283 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); 5114 bnx2x_ext_phy_hw_reset(bp, params->port);
4284 DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n", 5115
4285 val2, val1); 5116 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
4286 bnx2x_cl45_read(bp, phy, 5117 return bnx2x_848xx_cmn_config_init(phy, params, vars);
4287 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); 5118}
4288 bnx2x_cl45_read(bp, phy, 5119
4289 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); 5120static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
4290 DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n", 5121 struct link_params *params,
4291 val2, val1); 5122 struct link_vars *vars)
4292 link_up = ((val1 & 4) == 4); 5123{
4293 /* if link is up 5124 struct bnx2x *bp = params->bp;
4294 * print the AN outcome of the SFX7101 PHY 5125 u16 temp;
5126 msleep(1);
5127 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5128 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
5129 params->port);
5130 msleep(200); /* 100 is not enough */
5131
5132 /**
5133 * BCM84823 requires that XGXS links up first @ 10G for normal
5134 * behavior
4295 */ 5135 */
4296 if (link_up) { 5136 temp = vars->line_speed;
4297 bnx2x_cl45_read(bp, phy, 5137 vars->line_speed = SPEED_10000;
4298 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, 5138 bnx2x_set_autoneg(phy, params, vars, 0);
4299 &val2); 5139 bnx2x_program_serdes(phy, params, vars);
4300 vars->line_speed = SPEED_10000; 5140 vars->line_speed = temp;
4301 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n", 5141 return bnx2x_848xx_cmn_config_init(phy, params, vars);
4302 val2, (val2 & (1<<14)));
4303 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
4304 bnx2x_ext_phy_resolve_fc(phy, params, vars);
4305 }
4306 return link_up;
4307} 5142}
4308 5143
4309static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, 5144static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
@@ -4364,7 +5199,6 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
4364 DP(NETIF_MSG_LINK, "Link is up in %dMbps," 5199 DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
4365 " is_duplex_full= %d\n", vars->line_speed, 5200 " is_duplex_full= %d\n", vars->line_speed,
4366 (vars->duplex == DUPLEX_FULL)); 5201 (vars->duplex == DUPLEX_FULL));
4367
4368 /* Check legacy speed AN resolution */ 5202 /* Check legacy speed AN resolution */
4369 bnx2x_cl45_read(bp, phy, 5203 bnx2x_cl45_read(bp, phy,
4370 MDIO_AN_DEVAD, 5204 MDIO_AN_DEVAD,
@@ -4391,192 +5225,6 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
4391 return link_up; 5225 return link_up;
4392} 5226}
4393 5227
4394static void bnx2x_link_int_enable(struct link_params *params)
4395{
4396 u8 port = params->port;
4397 u32 mask;
4398 struct bnx2x *bp = params->bp;
4399
4400 /* setting the status to report on link up
4401 for either XGXS or SerDes */
4402
4403 if (params->switch_cfg == SWITCH_CFG_10G) {
4404 mask = (NIG_MASK_XGXS0_LINK10G |
4405 NIG_MASK_XGXS0_LINK_STATUS);
4406 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
4407 if (!(SINGLE_MEDIA_DIRECT(params)) &&
4408 params->phy[INT_PHY].type !=
4409 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
4410 mask |= NIG_MASK_MI_INT;
4411 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4412 }
4413
4414 } else { /* SerDes */
4415 mask = NIG_MASK_SERDES0_LINK_STATUS;
4416 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
4417 if (!(SINGLE_MEDIA_DIRECT(params)) &&
4418 params->phy[INT_PHY].type !=
4419 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
4420 mask |= NIG_MASK_MI_INT;
4421 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4422 }
4423 }
4424 bnx2x_bits_en(bp,
4425 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4426 mask);
4427
4428 DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
4429 (params->switch_cfg == SWITCH_CFG_10G),
4430 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4431 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
4432 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4433 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4434 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
4435 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4436 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4437 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4438}
4439
4440static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
4441 u8 is_mi_int)
4442{
4443 u32 latch_status = 0, is_mi_int_status;
4444 /* Disable the MI INT ( external phy int )
4445 * by writing 1 to the status register. Link down indication
4446 * is high-active-signal, so in this case we need to write the
4447 * status to clear the XOR
4448 */
4449 /* Read Latched signals */
4450 latch_status = REG_RD(bp,
4451 NIG_REG_LATCH_STATUS_0 + port*8);
4452 is_mi_int_status = REG_RD(bp,
4453 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
4454 DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
4455 "latch_status = 0x%x\n",
4456 is_mi_int, is_mi_int_status, latch_status);
4457 /* Handle only those with latched-signal=up.*/
4458 if (latch_status & 1) {
4459 /* For all latched-signal=up,Write original_signal to status */
4460 if (is_mi_int)
4461 bnx2x_bits_en(bp,
4462 NIG_REG_STATUS_INTERRUPT_PORT0
4463 + port*4,
4464 NIG_STATUS_EMAC0_MI_INT);
4465 else
4466 bnx2x_bits_dis(bp,
4467 NIG_REG_STATUS_INTERRUPT_PORT0
4468 + port*4,
4469 NIG_STATUS_EMAC0_MI_INT);
4470 /* For all latched-signal=up : Re-Arm Latch signals */
4471 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
4472 (latch_status & 0xfffe) | (latch_status & 1));
4473 }
4474}
4475
4476/*
4477 * link management
4478 */
4479static void bnx2x_link_int_ack(struct link_params *params,
4480 struct link_vars *vars, u8 is_10g,
4481 u8 is_mi_int)
4482{
4483 struct bnx2x *bp = params->bp;
4484 u8 port = params->port;
4485
4486 /* first reset all status
4487 * we assume only one line will be change at a time */
4488 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4489 (NIG_STATUS_XGXS0_LINK10G |
4490 NIG_STATUS_XGXS0_LINK_STATUS |
4491 NIG_STATUS_SERDES0_LINK_STATUS));
4492 if ((params->phy[EXT_PHY1].type
4493 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
4494 (params->phy[EXT_PHY1].type
4495 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) {
4496 bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
4497 }
4498 if (vars->phy_link_up) {
4499 if (is_10g) {
4500 /* Disable the 10G link interrupt
4501 * by writing 1 to the status register
4502 */
4503 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
4504 bnx2x_bits_en(bp,
4505 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4506 NIG_STATUS_XGXS0_LINK10G);
4507
4508 } else if (params->switch_cfg == SWITCH_CFG_10G) {
4509 /* Disable the link interrupt
4510 * by writing 1 to the relevant lane
4511 * in the status register
4512 */
4513 u32 ser_lane = ((params->lane_config &
4514 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4515 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4516
4517 DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
4518 vars->line_speed);
4519 bnx2x_bits_en(bp,
4520 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4521 ((1 << ser_lane) <<
4522 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
4523
4524 } else { /* SerDes */
4525 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
4526 /* Disable the link interrupt
4527 * by writing 1 to the status register
4528 */
4529 bnx2x_bits_en(bp,
4530 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4531 NIG_STATUS_SERDES0_LINK_STATUS);
4532 }
4533
4534 }
4535}
4536
4537static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
4538{
4539 if (*len < 5)
4540 return -EINVAL;
4541 str[0] = (spirom_ver & 0xFF);
4542 str[1] = (spirom_ver & 0xFF00) >> 8;
4543 str[2] = (spirom_ver & 0xFF0000) >> 16;
4544 str[3] = (spirom_ver & 0xFF000000) >> 24;
4545 str[4] = '\0';
4546 *len -= 5;
4547 return 0;
4548}
4549
4550static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
4551{
4552 u8 *str_ptr = str;
4553 u32 mask = 0xf0000000;
4554 u8 shift = 8*4;
4555 u8 digit;
4556 if (*len < 10) {
4557 /* Need more than 10chars for this format */
4558 *str_ptr = '\0';
4559 return -EINVAL;
4560 }
4561 while (shift > 0) {
4562
4563 shift -= 4;
4564 digit = ((num & mask) >> shift);
4565 if (digit < 0xa)
4566 *str_ptr = digit + '0';
4567 else
4568 *str_ptr = digit - 0xa + 'a';
4569 str_ptr++;
4570 mask = mask >> 4;
4571 if (shift == 4*4) {
4572 *str_ptr = ':';
4573 str_ptr++;
4574 }
4575 }
4576 *str_ptr = '\0';
4577 return 0;
4578}
4579
4580static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len) 5228static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
4581{ 5229{
4582 u8 status = 0; 5230 u8 status = 0;
@@ -4586,603 +5234,15 @@ static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
4586 return status; 5234 return status;
4587} 5235}
4588 5236
4589static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) 5237static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
4590{ 5238 struct link_params *params)
4591 str[0] = '\0';
4592 (*len)--;
4593 return 0;
4594}
4595u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4596 u8 *version, u16 len)
4597{
4598 struct bnx2x *bp;
4599 u32 spirom_ver = 0;
4600 u8 status = 0;
4601 u8 *ver_p = version;
4602 if (version == NULL || params == NULL)
4603 return -EINVAL;
4604 bp = params->bp;
4605
4606 /* Extract first external phy*/
4607 version[0] = '\0';
4608 spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
4609
4610 if (params->phy[EXT_PHY1].format_fw_ver)
4611 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
4612 ver_p,
4613 &len);
4614 return status;
4615}
4616
4617static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
4618 struct link_params *params)
4619{
4620 u8 port = params->port;
4621 struct bnx2x *bp = params->bp;
4622
4623 if (phy->req_line_speed != SPEED_1000) {
4624 u32 md_devad;
4625
4626 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4627
4628 /* change the uni_phy_addr in the nig */
4629 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4630 port*0x18));
4631
4632 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4633
4634 bnx2x_cl45_write(bp, phy,
4635 5,
4636 (MDIO_REG_BANK_AER_BLOCK +
4637 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4638 0x2800);
4639
4640 bnx2x_cl45_write(bp, phy,
4641 5,
4642 (MDIO_REG_BANK_CL73_IEEEB0 +
4643 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4644 0x6041);
4645 msleep(200);
4646 /* set aer mmd back */
4647 bnx2x_set_aer_mmd(params, phy);
4648
4649 /* and md_devad */
4650 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4651 md_devad);
4652
4653 } else {
4654 u16 mii_ctrl;
4655 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4656 bnx2x_cl45_read(bp, phy, 5,
4657 (MDIO_REG_BANK_COMBO_IEEE0 +
4658 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
4659 &mii_ctrl);
4660 bnx2x_cl45_write(bp, phy, 5,
4661 (MDIO_REG_BANK_COMBO_IEEE0 +
4662 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
4663 mii_ctrl |
4664 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
4665 }
4666}
4667
4668static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
4669 struct link_params *params)
4670{
4671 struct bnx2x *bp = params->bp;
4672 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4673 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
4674}
4675
4676static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
4677 struct link_params *params)
4678{
4679 struct bnx2x *bp = params->bp;
4680 /* SFX7101_XGXS_TEST1 */
4681 bnx2x_cl45_write(bp, phy,
4682 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
4683}
4684
4685/*
4686 *------------------------------------------------------------------------
4687 * bnx2x_override_led_value -
4688 *
4689 * Override the led value of the requested led
4690 *
4691 *------------------------------------------------------------------------
4692 */
4693u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4694 u32 led_idx, u32 value)
4695{
4696 u32 reg_val;
4697
4698 /* If port 0 then use EMAC0, else use EMAC1*/
4699 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4700
4701 DP(NETIF_MSG_LINK,
4702 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4703 port, led_idx, value);
4704
4705 switch (led_idx) {
4706 case 0: /* 10MB led */
4707 /* Read the current value of the LED register in
4708 the EMAC block */
4709 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4710 /* Set the OVERRIDE bit to 1 */
4711 reg_val |= EMAC_LED_OVERRIDE;
4712 /* If value is 1, set the 10M_OVERRIDE bit,
4713 otherwise reset it.*/
4714 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4715 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4716 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4717 break;
4718 case 1: /*100MB led */
4719 /*Read the current value of the LED register in
4720 the EMAC block */
4721 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4722 /* Set the OVERRIDE bit to 1 */
4723 reg_val |= EMAC_LED_OVERRIDE;
4724 /* If value is 1, set the 100M_OVERRIDE bit,
4725 otherwise reset it.*/
4726 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4727 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4728 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4729 break;
4730 case 2: /* 1000MB led */
4731 /* Read the current value of the LED register in the
4732 EMAC block */
4733 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4734 /* Set the OVERRIDE bit to 1 */
4735 reg_val |= EMAC_LED_OVERRIDE;
4736 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4737 reset it. */
4738 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4739 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4740 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4741 break;
4742 case 3: /* 2500MB led */
4743 /* Read the current value of the LED register in the
4744 EMAC block*/
4745 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4746 /* Set the OVERRIDE bit to 1 */
4747 reg_val |= EMAC_LED_OVERRIDE;
4748 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
4749 reset it.*/
4750 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4751 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4752 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4753 break;
4754 case 4: /*10G led */
4755 if (port == 0) {
4756 REG_WR(bp, NIG_REG_LED_10G_P0,
4757 value);
4758 } else {
4759 REG_WR(bp, NIG_REG_LED_10G_P1,
4760 value);
4761 }
4762 break;
4763 case 5: /* TRAFFIC led */
4764 /* Find if the traffic control is via BMAC or EMAC */
4765 if (port == 0)
4766 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4767 else
4768 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4769
4770 /* Override the traffic led in the EMAC:*/
4771 if (reg_val == 1) {
4772 /* Read the current value of the LED register in
4773 the EMAC block */
4774 reg_val = REG_RD(bp, emac_base +
4775 EMAC_REG_EMAC_LED);
4776 /* Set the TRAFFIC_OVERRIDE bit to 1 */
4777 reg_val |= EMAC_LED_OVERRIDE;
4778 /* If value is 1, set the TRAFFIC bit, otherwise
4779 reset it.*/
4780 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4781 (reg_val & ~EMAC_LED_TRAFFIC);
4782 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4783 } else { /* Override the traffic led in the BMAC: */
4784 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4785 + port*4, 1);
4786 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4787 value);
4788 }
4789 break;
4790 default:
4791 DP(NETIF_MSG_LINK,
4792 "bnx2x_override_led_value() unknown led index %d "
4793 "(should be 0-5)\n", led_idx);
4794 return -EINVAL;
4795 }
4796
4797 return 0;
4798}
4799
4800
4801u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed)
4802{
4803 u8 port = params->port;
4804 u16 hw_led_mode = params->hw_led_mode;
4805 u8 rc = 0;
4806 u32 tmp;
4807 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4808 struct bnx2x *bp = params->bp;
4809 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4810 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4811 speed, hw_led_mode);
4812 switch (mode) {
4813 case LED_MODE_OFF:
4814 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4815 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4816 SHARED_HW_CFG_LED_MAC1);
4817
4818 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4819 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4820 break;
4821
4822 case LED_MODE_OPER:
4823 if (SINGLE_MEDIA_DIRECT(params)) {
4824 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
4825 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
4826 } else {
4827 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4828 hw_led_mode);
4829 }
4830
4831 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4832 port*4, 0);
4833 /* Set blinking rate to ~15.9Hz */
4834 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4835 LED_BLINK_RATE_VAL);
4836 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4837 port*4, 1);
4838 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4839 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4840 (tmp & (~EMAC_LED_OVERRIDE)));
4841
4842 if (CHIP_IS_E1(bp) &&
4843 ((speed == SPEED_2500) ||
4844 (speed == SPEED_1000) ||
4845 (speed == SPEED_100) ||
4846 (speed == SPEED_10))) {
4847 /* On Everest 1 Ax chip versions for speeds less than
4848 10G LED scheme is different */
4849 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4850 + port*4, 1);
4851 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4852 port*4, 0);
4853 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4854 port*4, 1);
4855 }
4856 break;
4857
4858 default:
4859 rc = -EINVAL;
4860 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4861 mode);
4862 break;
4863 }
4864 return rc;
4865
4866}
4867
4868u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4869{
4870 struct bnx2x *bp = params->bp;
4871 u16 gp_status = 0, phy_index = 0;
4872
4873 CL45_RD_OVER_CL22(bp, &params->phy[INT_PHY],
4874 MDIO_REG_BANK_GP_STATUS,
4875 MDIO_GP_STATUS_TOP_AN_STATUS1,
4876 &gp_status);
4877 /* link is up only if both local phy and external phy are up */
4878 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
4879 u8 ext_phy_link_up = 1;
4880 struct link_vars temp_vars;
4881 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
4882 phy_index++) {
4883 if (params->phy[phy_index].read_status)
4884 ext_phy_link_up &=
4885 params->phy[phy_index].read_status(
4886 &params->phy[phy_index],
4887 params, &temp_vars);
4888 }
4889 if (ext_phy_link_up)
4890 return 0;
4891 }
4892 return -ESRCH;
4893}
4894
4895static u8 bnx2x_link_initialize(struct link_params *params,
4896 struct link_vars *vars)
4897{
4898 u8 rc = 0;
4899 u8 phy_index, non_ext_phy;
4900 struct bnx2x *bp = params->bp;
4901 /**
4902 * In case of external phy existence, the line speed would be the
4903 * line speed linked up by the external phy. In case it is direct
4904 * only, then the line_speed during initialization will be
4905 * equal to the req_line_speed
4906 */
4907 vars->line_speed = params->phy[INT_PHY].req_line_speed;
4908
4909 /**
4910 * Initialize the internal phy in case this is a direct board
4911 * (no external phys), or this board has external phy which requires
4912 * to first.
4913 */
4914
4915 if (params->phy[INT_PHY].config_init)
4916 params->phy[INT_PHY].config_init(
4917 &params->phy[INT_PHY],
4918 params, vars);
4919
4920 /* init ext phy and enable link state int */
4921 non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
4922 (params->loopback_mode == LOOPBACK_XGXS_10));
4923
4924 if (non_ext_phy ||
4925 (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
4926 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4927 struct bnx2x_phy *phy = &params->phy[INT_PHY];
4928 if (vars->line_speed == SPEED_AUTO_NEG)
4929 bnx2x_set_parallel_detection(phy, params);
4930 bnx2x_init_internal_phy(phy, params, vars);
4931 }
4932
4933 /* Init external phy*/
4934 if (!non_ext_phy)
4935 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
4936 phy_index++) {
4937 params->phy[phy_index].config_init(
4938 &params->phy[phy_index],
4939 params, vars);
4940 }
4941
4942 /* Reset the interrupt indication after phy was initialized */
4943 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
4944 params->port*4,
4945 (NIG_STATUS_XGXS0_LINK10G |
4946 NIG_STATUS_XGXS0_LINK_STATUS |
4947 NIG_STATUS_SERDES0_LINK_STATUS |
4948 NIG_MASK_MI_INT));
4949 return rc;
4950}
4951
4952static void set_phy_vars(struct link_params *params)
4953{
4954 struct bnx2x *bp = params->bp;
4955 u8 actual_phy_idx, phy_index;
4956
4957 for (phy_index = INT_PHY; phy_index < params->num_phys;
4958 phy_index++) {
4959
4960 actual_phy_idx = phy_index;
4961 params->phy[actual_phy_idx].req_flow_ctrl =
4962 params->req_flow_ctrl;
4963
4964 params->phy[actual_phy_idx].req_line_speed =
4965 params->req_line_speed;
4966
4967 params->phy[actual_phy_idx].speed_cap_mask =
4968 params->speed_cap_mask;
4969
4970 params->phy[actual_phy_idx].req_duplex =
4971 params->req_duplex;
4972
4973 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
4974 " speed_cap_mask %x\n",
4975 params->phy[actual_phy_idx].req_flow_ctrl,
4976 params->phy[actual_phy_idx].req_line_speed,
4977 params->phy[actual_phy_idx].speed_cap_mask);
4978 }
4979}
4980
4981u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4982{
4983 struct bnx2x *bp = params->bp;
4984 u32 val;
4985
4986 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
4987 DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
4988 params->req_line_speed, params->req_flow_ctrl);
4989 vars->link_status = 0;
4990 vars->phy_link_up = 0;
4991 vars->link_up = 0;
4992 vars->line_speed = 0;
4993 vars->duplex = DUPLEX_FULL;
4994 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4995 vars->mac_type = MAC_TYPE_NONE;
4996 vars->phy_flags = 0;
4997
4998 /* disable attentions */
4999 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
5000 (NIG_MASK_XGXS0_LINK_STATUS |
5001 NIG_MASK_XGXS0_LINK10G |
5002 NIG_MASK_SERDES0_LINK_STATUS |
5003 NIG_MASK_MI_INT));
5004
5005 bnx2x_emac_init(params, vars);
5006
5007 if (params->num_phys == 0) {
5008 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
5009 return -EINVAL;
5010 }
5011 set_phy_vars(params);
5012
5013 DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
5014 if (CHIP_REV_IS_FPGA(bp)) {
5015
5016 vars->link_up = 1;
5017 vars->line_speed = SPEED_10000;
5018 vars->duplex = DUPLEX_FULL;
5019 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5020 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5021 /* enable on E1.5 FPGA */
5022 if (CHIP_IS_E1H(bp)) {
5023 vars->flow_ctrl |=
5024 (BNX2X_FLOW_CTRL_TX |
5025 BNX2X_FLOW_CTRL_RX);
5026 vars->link_status |=
5027 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
5028 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
5029 }
5030
5031 bnx2x_emac_enable(params, vars, 0);
5032 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5033 /* disable drain */
5034 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
5035
5036 /* update shared memory */
5037 bnx2x_update_mng(params, vars->link_status);
5038
5039 return 0;
5040
5041 } else
5042 if (CHIP_REV_IS_EMUL(bp)) {
5043
5044 vars->link_up = 1;
5045 vars->line_speed = SPEED_10000;
5046 vars->duplex = DUPLEX_FULL;
5047 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5048 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5049
5050 bnx2x_bmac_enable(params, vars, 0);
5051
5052 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5053 /* Disable drain */
5054 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
5055 + params->port*4, 0);
5056
5057 /* update shared memory */
5058 bnx2x_update_mng(params, vars->link_status);
5059
5060 return 0;
5061
5062 } else
5063 if (params->loopback_mode == LOOPBACK_BMAC) {
5064
5065 vars->link_up = 1;
5066 vars->line_speed = SPEED_10000;
5067 vars->duplex = DUPLEX_FULL;
5068 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5069 vars->mac_type = MAC_TYPE_BMAC;
5070
5071 vars->phy_flags = PHY_XGXS_FLAG;
5072
5073 bnx2x_xgxs_deassert(params);
5074
5075 /* set bmac loopback */
5076 bnx2x_bmac_enable(params, vars, 1);
5077
5078 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5079 params->port*4, 0);
5080
5081 } else if (params->loopback_mode == LOOPBACK_EMAC) {
5082
5083 vars->link_up = 1;
5084 vars->line_speed = SPEED_1000;
5085 vars->duplex = DUPLEX_FULL;
5086 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5087 vars->mac_type = MAC_TYPE_EMAC;
5088
5089 vars->phy_flags = PHY_XGXS_FLAG;
5090
5091 bnx2x_xgxs_deassert(params);
5092 /* set bmac loopback */
5093 bnx2x_emac_enable(params, vars, 1);
5094 bnx2x_emac_program(params, vars);
5095 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5096 params->port*4, 0);
5097
5098 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
5099 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5100
5101 vars->link_up = 1;
5102 vars->line_speed = SPEED_10000;
5103 vars->duplex = DUPLEX_FULL;
5104 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5105
5106 vars->phy_flags = PHY_XGXS_FLAG;
5107
5108 val = REG_RD(bp,
5109 NIG_REG_XGXS0_CTRL_PHY_ADDR+
5110 params->port*0x18);
5111
5112 bnx2x_xgxs_deassert(params);
5113 bnx2x_link_initialize(params, vars);
5114
5115 vars->mac_type = MAC_TYPE_BMAC;
5116
5117 bnx2x_bmac_enable(params, vars, 0);
5118
5119 if (params->loopback_mode == LOOPBACK_XGXS_10) {
5120 /* set 10G XGXS loopback */
5121 params->phy[INT_PHY].config_loopback(
5122 &params->phy[INT_PHY],
5123 params);
5124
5125 } else {
5126 /* set external phy loopback */
5127 u8 phy_index;
5128 for (phy_index = EXT_PHY1;
5129 phy_index < params->num_phys; phy_index++) {
5130 if (params->phy[phy_index].config_loopback)
5131 params->phy[phy_index].config_loopback(
5132 &params->phy[phy_index],
5133 params);
5134 }
5135 }
5136
5137 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5138 params->port*4, 0);
5139
5140 bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
5141 } else
5142 /* No loopback */
5143 {
5144 if (params->switch_cfg == SWITCH_CFG_10G)
5145 bnx2x_xgxs_deassert(params);
5146 else
5147 bnx2x_serdes_deassert(bp, params->port);
5148 bnx2x_link_initialize(params, vars);
5149 msleep(30);
5150 bnx2x_link_int_enable(params);
5151 }
5152 return 0;
5153}
5154
5155
5156static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
5157 struct link_params *params)
5158{ 5239{
5159 struct bnx2x *bp = params->bp; 5240 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5160 DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port); 5241 MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
5161 /* Set serial boot control for external load */ 5242 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5162 bnx2x_cl45_write(bp, phy, 5243 MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
5163 MDIO_PMA_DEVAD,
5164 MDIO_PMA_REG_GEN_CTRL, 0x0001);
5165} 5244}
5166 5245
5167static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
5168 struct link_params *params)
5169{
5170 struct bnx2x *bp = params->bp;
5171 /* Disable Transmitter */
5172 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5173}
5174static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
5175 struct link_params *params)
5176{
5177 struct bnx2x *bp = params->bp;
5178 u8 gpio_port;
5179 gpio_port = params->port;
5180 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
5181 gpio_port);
5182 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5183 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5184 gpio_port);
5185}
5186static void bnx2x_8481_link_reset(struct bnx2x_phy *phy, 5246static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
5187 struct link_params *params) 5247 struct link_params *params)
5188{ 5248{
@@ -5202,385 +5262,131 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
5202 port); 5262 port);
5203} 5263}
5204 5264
5205static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, 5265/******************************************************************/
5206 struct link_params *params) 5266/* SFX7101 PHY SECTION */
5267/******************************************************************/
5268static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
5269 struct link_params *params)
5207{ 5270{
5208 struct bnx2x *bp = params->bp; 5271 struct bnx2x *bp = params->bp;
5209 u8 gpio_port; 5272 /* SFX7101_XGXS_TEST1 */
5210 /* HW reset */ 5273 bnx2x_cl45_write(bp, phy,
5211 gpio_port = params->port; 5274 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
5212 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5213 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5214 gpio_port);
5215 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5216 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5217 gpio_port);
5218 DP(NETIF_MSG_LINK, "reset external PHY\n");
5219}
5220
5221static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
5222 struct link_params *params)
5223{
5224 /* reset the SerDes/XGXS */
5225 REG_WR(params->bp, GRCBASE_MISC +
5226 MISC_REGISTERS_RESET_REG_3_CLEAR,
5227 (0x1ff << (params->port*16)));
5228} 5275}
5229 5276
5230u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, 5277static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
5231 u8 reset_ext_phy) 5278 struct link_params *params,
5279 struct link_vars *vars)
5232{ 5280{
5281 u16 fw_ver1, fw_ver2, val;
5233 struct bnx2x *bp = params->bp; 5282 struct bnx2x *bp = params->bp;
5234 u8 phy_index, port = params->port; 5283 DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
5235 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
5236 /* disable attentions */
5237 vars->link_status = 0;
5238 bnx2x_update_mng(params, vars->link_status);
5239 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5240 (NIG_MASK_XGXS0_LINK_STATUS |
5241 NIG_MASK_XGXS0_LINK10G |
5242 NIG_MASK_SERDES0_LINK_STATUS |
5243 NIG_MASK_MI_INT));
5244
5245 /* activate nig drain */
5246 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
5247
5248 /* disable nig egress interface */
5249 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
5250 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
5251 5284
5252 /* Stop BigMac rx */ 5285 /* Restore normal power mode*/
5253 bnx2x_bmac_rx_disable(bp, port); 5286 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5287 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5288 /* HW reset */
5289 bnx2x_ext_phy_hw_reset(bp, params->port);
5290 bnx2x_wait_reset_complete(bp, phy);
5254 5291
5255 /* disable emac */ 5292 bnx2x_cl45_write(bp, phy,
5256 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); 5293 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
5294 DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
5295 bnx2x_cl45_write(bp, phy,
5296 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
5257 5297
5258 msleep(10); 5298 bnx2x_ext_phy_set_pause(params, phy, vars);
5259 /* The PHY reset is controled by GPIO 1 5299 /* Restart autoneg */
5260 * Hold it as vars low 5300 bnx2x_cl45_read(bp, phy,
5261 */ 5301 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
5262 /* clear link led */ 5302 val |= 0x200;
5263 bnx2x_set_led(params, LED_MODE_OFF, 0); 5303 bnx2x_cl45_write(bp, phy,
5264 if (reset_ext_phy) { 5304 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
5265 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
5266 phy_index++) {
5267 if (params->phy[phy_index].link_reset)
5268 params->phy[phy_index].link_reset(
5269 &params->phy[phy_index],
5270 params);
5271 }
5272 }
5273 5305
5274 if (params->phy[INT_PHY].link_reset) 5306 /* Save spirom version */
5275 params->phy[INT_PHY].link_reset( 5307 bnx2x_cl45_read(bp, phy,
5276 &params->phy[INT_PHY], params); 5308 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
5277 /* reset BigMac */
5278 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
5279 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
5280 5309
5281 /* disable nig ingress interface */ 5310 bnx2x_cl45_read(bp, phy,
5282 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); 5311 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
5283 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); 5312 bnx2x_save_spirom_version(bp, params->port,
5284 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); 5313 (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
5285 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
5286 vars->link_up = 0;
5287 return 0; 5314 return 0;
5288} 5315}
5289 5316
5290static u8 bnx2x_update_link_down(struct link_params *params, 5317static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
5291 struct link_vars *vars) 5318 struct link_params *params,
5319 struct link_vars *vars)
5292{ 5320{
5293 struct bnx2x *bp = params->bp; 5321 struct bnx2x *bp = params->bp;
5294 u8 port = params->port; 5322 u8 link_up;
5295 5323 u16 val1, val2;
5296 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); 5324 bnx2x_cl45_read(bp, phy,
5297 bnx2x_set_led(params, LED_MODE_OFF, 0); 5325 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
5298 5326 bnx2x_cl45_read(bp, phy,
5299 /* indicate no mac active */ 5327 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5300 vars->mac_type = MAC_TYPE_NONE; 5328 DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
5301 5329 val2, val1);
5302 /* update shared memory */ 5330 bnx2x_cl45_read(bp, phy,
5303 vars->link_status = 0; 5331 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
5304 vars->line_speed = 0; 5332 bnx2x_cl45_read(bp, phy,
5305 bnx2x_update_mng(params, vars->link_status); 5333 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
5306 5334 DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
5307 /* activate nig drain */ 5335 val2, val1);
5308 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); 5336 link_up = ((val1 & 4) == 4);
5309 5337 /* if link is up
5310 /* disable emac */ 5338 * print the AN outcome of the SFX7101 PHY
5311 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); 5339 */
5340 if (link_up) {
5341 bnx2x_cl45_read(bp, phy,
5342 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
5343 &val2);
5344 vars->line_speed = SPEED_10000;
5345 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
5346 val2, (val2 & (1<<14)));
5347 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
5348 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5349 }
5350 return link_up;
5351}
5312 5352
5313 msleep(10);
5314 5353
5315 /* reset BigMac */ 5354static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
5316 bnx2x_bmac_rx_disable(bp, params->port); 5355{
5317 REG_WR(bp, GRCBASE_MISC + 5356 if (*len < 5)
5318 MISC_REGISTERS_RESET_REG_2_CLEAR, 5357 return -EINVAL;
5319 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); 5358 str[0] = (spirom_ver & 0xFF);
5359 str[1] = (spirom_ver & 0xFF00) >> 8;
5360 str[2] = (spirom_ver & 0xFF0000) >> 16;
5361 str[3] = (spirom_ver & 0xFF000000) >> 24;
5362 str[4] = '\0';
5363 *len -= 5;
5320 return 0; 5364 return 0;
5321} 5365}
5322 5366
5323static u8 bnx2x_update_link_up(struct link_params *params, 5367void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
5324 struct link_vars *vars,
5325 u8 link_10g)
5326{
5327 struct bnx2x *bp = params->bp;
5328 u8 port = params->port;
5329 u8 rc = 0;
5330
5331 vars->link_status |= LINK_STATUS_LINK_UP;
5332 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
5333 vars->link_status |=
5334 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
5335
5336 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
5337 vars->link_status |=
5338 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
5339 if (link_10g) {
5340 bnx2x_bmac_enable(params, vars, 0);
5341 bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
5342 } else {
5343 rc = bnx2x_emac_program(params, vars);
5344
5345 bnx2x_emac_enable(params, vars, 0);
5346
5347 /* AN complete? */
5348 if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
5349 && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
5350 SINGLE_MEDIA_DIRECT(params))
5351 bnx2x_set_gmii_tx_driver(params);
5352 }
5353
5354 /* PBF - link up */
5355 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
5356 vars->line_speed);
5357
5358 /* disable drain */
5359 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
5360
5361 /* update shared memory */
5362 bnx2x_update_mng(params, vars->link_status);
5363 msleep(20);
5364 return rc;
5365}
5366/**
5367 * The bnx2x_link_update function should be called upon link
5368 * interrupt.
5369 * Link is considered up as follows:
5370 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
5371 * to be up
5372 * - SINGLE_MEDIA - The link between the 577xx and the external
5373 * phy (XGXS) need to up as well as the external link of the
5374 * phy (PHY_EXT1)
5375 * - DUAL_MEDIA - The link between the 577xx and the first
5376 * external phy needs to be up, and at least one of the 2
5377 * external phy link must be up.
5378 */
5379u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
5380{ 5368{
5381 struct bnx2x *bp = params->bp; 5369 u16 val, cnt;
5382 struct link_vars phy_vars[MAX_PHYS];
5383 u8 port = params->port;
5384 u8 link_10g, phy_index;
5385 u8 ext_phy_link_up = 0, cur_link_up, rc = 0;
5386 u8 is_mi_int = 0;
5387 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
5388 u8 active_external_phy = INT_PHY;
5389 vars->link_status = 0;
5390 for (phy_index = INT_PHY; phy_index < params->num_phys;
5391 phy_index++) {
5392 phy_vars[phy_index].flow_ctrl = 0;
5393 phy_vars[phy_index].link_status = 0;
5394 phy_vars[phy_index].line_speed = 0;
5395 phy_vars[phy_index].duplex = DUPLEX_FULL;
5396 phy_vars[phy_index].phy_link_up = 0;
5397 phy_vars[phy_index].link_up = 0;
5398 }
5399
5400 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
5401 port, (vars->phy_flags & PHY_XGXS_FLAG),
5402 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5403
5404 is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
5405 port*0x18) > 0);
5406 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
5407 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5408 is_mi_int,
5409 REG_RD(bp,
5410 NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
5411
5412 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5413 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5414 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5415
5416 /* disable emac */
5417 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5418
5419 /**
5420 * Step 1:
5421 * Check external link change only for external phys, and apply
5422 * priority selection between them in case the link on both phys
5423 * is up. Note that the instead of the common vars, a temporary
5424 * vars argument is used since each phy may have different link/
5425 * speed/duplex result
5426 */
5427 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
5428 phy_index++) {
5429 struct bnx2x_phy *phy = &params->phy[phy_index];
5430 if (!phy->read_status)
5431 continue;
5432 /* Read link status and params of this ext phy */
5433 cur_link_up = phy->read_status(phy, params,
5434 &phy_vars[phy_index]);
5435 if (cur_link_up) {
5436 DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
5437 phy_index);
5438 } else {
5439 DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
5440 phy_index);
5441 continue;
5442 }
5443
5444 if (!ext_phy_link_up) {
5445 ext_phy_link_up = 1;
5446 active_external_phy = phy_index;
5447 }
5448 }
5449 prev_line_speed = vars->line_speed;
5450 /**
5451 * Step 2:
5452 * Read the status of the internal phy. In case of
5453 * DIRECT_SINGLE_MEDIA board, this link is the external link,
5454 * otherwise this is the link between the 577xx and the first
5455 * external phy
5456 */
5457 if (params->phy[INT_PHY].read_status)
5458 params->phy[INT_PHY].read_status(
5459 &params->phy[INT_PHY],
5460 params, vars);
5461 /**
5462 * The INT_PHY flow control reside in the vars. This include the
5463 * case where the speed or flow control are not set to AUTO.
5464 * Otherwise, the active external phy flow control result is set
5465 * to the vars. The ext_phy_line_speed is needed to check if the
5466 * speed is different between the internal phy and external phy.
5467 * This case may be result of intermediate link speed change.
5468 */
5469 if (active_external_phy > INT_PHY) {
5470 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
5471 /**
5472 * Link speed is taken from the XGXS. AN and FC result from
5473 * the external phy.
5474 */
5475 vars->link_status |= phy_vars[active_external_phy].link_status;
5476 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
5477 vars->duplex = phy_vars[active_external_phy].duplex;
5478 if (params->phy[active_external_phy].supported &
5479 SUPPORTED_FIBRE)
5480 vars->link_status |= LINK_STATUS_SERDES_LINK;
5481 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
5482 active_external_phy);
5483 }
5484 DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
5485 " ext_phy_line_speed = %d\n", vars->flow_ctrl,
5486 vars->link_status, ext_phy_line_speed);
5487 /**
5488 * Upon link speed change set the NIG into drain mode. Comes to
5489 * deals with possible FIFO glitch due to clk change when speed
5490 * is decreased without link down indicator
5491 */
5492
5493 if (vars->phy_link_up) {
5494 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
5495 (ext_phy_line_speed != vars->line_speed)) {
5496 DP(NETIF_MSG_LINK, "Internal link speed %d is"
5497 " different than the external"
5498 " link speed %d\n", vars->line_speed,
5499 ext_phy_line_speed);
5500 vars->phy_link_up = 0;
5501 } else if (prev_line_speed != vars->line_speed) {
5502 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
5503 + params->port*4, 0);
5504 msleep(1);
5505 }
5506 }
5507 5370
5508 /* anything 10 and over uses the bmac */ 5371 bnx2x_cl45_read(bp, phy,
5509 link_10g = ((vars->line_speed == SPEED_10000) || 5372 MDIO_PMA_DEVAD,
5510 (vars->line_speed == SPEED_12000) || 5373 MDIO_PMA_REG_7101_RESET, &val);
5511 (vars->line_speed == SPEED_12500) ||
5512 (vars->line_speed == SPEED_13000) ||
5513 (vars->line_speed == SPEED_15000) ||
5514 (vars->line_speed == SPEED_16000));
5515 5374
5516 bnx2x_link_int_ack(params, vars, link_10g, is_mi_int); 5375 for (cnt = 0; cnt < 10; cnt++) {
5376 msleep(50);
5377 /* Writes a self-clearing reset */
5378 bnx2x_cl45_write(bp, phy,
5379 MDIO_PMA_DEVAD,
5380 MDIO_PMA_REG_7101_RESET,
5381 (val | (1<<15)));
5382 /* Wait for clear */
5383 bnx2x_cl45_read(bp, phy,
5384 MDIO_PMA_DEVAD,
5385 MDIO_PMA_REG_7101_RESET, &val);
5517 5386
5518 /** 5387 if ((val & (1<<15)) == 0)
5519 * In case external phy link is up, and internal link is down 5388 break;
5520 * (not initialized yet probably after link initialization, it
5521 * needs to be initialized.
5522 * Note that after link down-up as result of cable plug, the xgxs
5523 * link would probably become up again without the need
5524 * initialize it
5525 */
5526 if (!(SINGLE_MEDIA_DIRECT(params))) {
5527 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
5528 " init_preceding = %d\n", ext_phy_link_up,
5529 vars->phy_link_up,
5530 params->phy[EXT_PHY1].flags &
5531 FLAGS_INIT_XGXS_FIRST);
5532 if (!(params->phy[EXT_PHY1].flags &
5533 FLAGS_INIT_XGXS_FIRST)
5534 && ext_phy_link_up && !vars->phy_link_up) {
5535 vars->line_speed = ext_phy_line_speed;
5536 if (vars->line_speed < SPEED_1000)
5537 vars->phy_flags |= PHY_SGMII_FLAG;
5538 else
5539 vars->phy_flags &= ~PHY_SGMII_FLAG;
5540 bnx2x_init_internal_phy(&params->phy[INT_PHY],
5541 params,
5542 vars);
5543 }
5544 } 5389 }
5545 /**
5546 * Link is up only if both local phy and external phy (in case of
5547 * non-direct board) are up
5548 */
5549 vars->link_up = (vars->phy_link_up &&
5550 (ext_phy_link_up ||
5551 SINGLE_MEDIA_DIRECT(params)));
5552
5553 if (vars->link_up)
5554 rc = bnx2x_update_link_up(params, vars, link_10g);
5555 else
5556 rc = bnx2x_update_link_down(params, vars);
5557
5558 return rc;
5559}
5560
5561static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
5562 struct link_params *params)
5563{
5564 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5565 MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
5566 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5567 MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
5568}
5569
5570static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
5571 struct link_params *params) {
5572 u32 swap_val, swap_override;
5573 u8 port;
5574 /**
5575 * The PHY reset is controlled by GPIO 1. Fake the port number
5576 * to cancel the swap done in set_gpio()
5577 */
5578 struct bnx2x *bp = params->bp;
5579 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5580 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5581 port = (swap_val && swap_override) ^ 1;
5582 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5583 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5584} 5390}
5585 5391
5586static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy, 5392static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
@@ -5592,6 +5398,7 @@ static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
5592 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, 5398 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5593 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); 5399 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
5594} 5400}
5401
5595/******************************************************************/ 5402/******************************************************************/
5596/* STATIC PHY DECLARATION */ 5403/* STATIC PHY DECLARATION */
5597/******************************************************************/ 5404/******************************************************************/
@@ -5854,7 +5661,6 @@ static struct bnx2x_phy phy_8727 = {
5854 .mdio_ctrl = 0, 5661 .mdio_ctrl = 0,
5855 .supported = (SUPPORTED_10000baseT_Full | 5662 .supported = (SUPPORTED_10000baseT_Full |
5856 SUPPORTED_1000baseT_Full | 5663 SUPPORTED_1000baseT_Full |
5857 SUPPORTED_Autoneg |
5858 SUPPORTED_FIBRE | 5664 SUPPORTED_FIBRE |
5859 SUPPORTED_Pause | 5665 SUPPORTED_Pause |
5860 SUPPORTED_Asym_Pause), 5666 SUPPORTED_Asym_Pause),
@@ -6240,6 +6046,271 @@ u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx)
6240 return 0; 6046 return 0;
6241} 6047}
6242 6048
6049static void set_phy_vars(struct link_params *params)
6050{
6051 struct bnx2x *bp = params->bp;
6052 u8 actual_phy_idx, phy_index;
6053
6054 for (phy_index = INT_PHY; phy_index < params->num_phys;
6055 phy_index++) {
6056
6057 actual_phy_idx = phy_index;
6058 params->phy[actual_phy_idx].req_flow_ctrl =
6059 params->req_flow_ctrl;
6060
6061 params->phy[actual_phy_idx].req_line_speed =
6062 params->req_line_speed;
6063
6064 params->phy[actual_phy_idx].speed_cap_mask =
6065 params->speed_cap_mask;
6066
6067 params->phy[actual_phy_idx].req_duplex =
6068 params->req_duplex;
6069
6070 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
6071 " speed_cap_mask %x\n",
6072 params->phy[actual_phy_idx].req_flow_ctrl,
6073 params->phy[actual_phy_idx].req_line_speed,
6074 params->phy[actual_phy_idx].speed_cap_mask);
6075 }
6076}
6077
6078u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
6079{
6080 struct bnx2x *bp = params->bp;
6081 u32 val;
6082
6083 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
6084 DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
6085 params->req_line_speed, params->req_flow_ctrl);
6086 vars->link_status = 0;
6087 vars->phy_link_up = 0;
6088 vars->link_up = 0;
6089 vars->line_speed = 0;
6090 vars->duplex = DUPLEX_FULL;
6091 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6092 vars->mac_type = MAC_TYPE_NONE;
6093 vars->phy_flags = 0;
6094
6095 /* disable attentions */
6096 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
6097 (NIG_MASK_XGXS0_LINK_STATUS |
6098 NIG_MASK_XGXS0_LINK10G |
6099 NIG_MASK_SERDES0_LINK_STATUS |
6100 NIG_MASK_MI_INT));
6101
6102 bnx2x_emac_init(params, vars);
6103
6104 if (params->num_phys == 0) {
6105 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
6106 return -EINVAL;
6107 }
6108 set_phy_vars(params);
6109
6110 DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
6111 if (CHIP_REV_IS_FPGA(bp)) {
6112
6113 vars->link_up = 1;
6114 vars->line_speed = SPEED_10000;
6115 vars->duplex = DUPLEX_FULL;
6116 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6117 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6118 /* enable on E1.5 FPGA */
6119 if (CHIP_IS_E1H(bp)) {
6120 vars->flow_ctrl |=
6121 (BNX2X_FLOW_CTRL_TX |
6122 BNX2X_FLOW_CTRL_RX);
6123 vars->link_status |=
6124 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
6125 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
6126 }
6127
6128 bnx2x_emac_enable(params, vars, 0);
6129 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6130 /* disable drain */
6131 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6132
6133 /* update shared memory */
6134 bnx2x_update_mng(params, vars->link_status);
6135
6136 return 0;
6137
6138 } else
6139 if (CHIP_REV_IS_EMUL(bp)) {
6140
6141 vars->link_up = 1;
6142 vars->line_speed = SPEED_10000;
6143 vars->duplex = DUPLEX_FULL;
6144 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6145 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6146
6147 bnx2x_bmac_enable(params, vars, 0);
6148
6149 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6150 /* Disable drain */
6151 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
6152 + params->port*4, 0);
6153
6154 /* update shared memory */
6155 bnx2x_update_mng(params, vars->link_status);
6156
6157 return 0;
6158
6159 } else
6160 if (params->loopback_mode == LOOPBACK_BMAC) {
6161
6162 vars->link_up = 1;
6163 vars->line_speed = SPEED_10000;
6164 vars->duplex = DUPLEX_FULL;
6165 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6166 vars->mac_type = MAC_TYPE_BMAC;
6167
6168 vars->phy_flags = PHY_XGXS_FLAG;
6169
6170 bnx2x_xgxs_deassert(params);
6171
6172 /* set bmac loopback */
6173 bnx2x_bmac_enable(params, vars, 1);
6174
6175 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6176 params->port*4, 0);
6177
6178 } else if (params->loopback_mode == LOOPBACK_EMAC) {
6179
6180 vars->link_up = 1;
6181 vars->line_speed = SPEED_1000;
6182 vars->duplex = DUPLEX_FULL;
6183 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6184 vars->mac_type = MAC_TYPE_EMAC;
6185
6186 vars->phy_flags = PHY_XGXS_FLAG;
6187
6188 bnx2x_xgxs_deassert(params);
6189 /* set bmac loopback */
6190 bnx2x_emac_enable(params, vars, 1);
6191 bnx2x_emac_program(params, vars);
6192 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6193 params->port*4, 0);
6194
6195 } else if ((params->loopback_mode == LOOPBACK_XGXS) ||
6196 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6197
6198 vars->link_up = 1;
6199 vars->line_speed = SPEED_10000;
6200 vars->duplex = DUPLEX_FULL;
6201 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6202
6203 vars->phy_flags = PHY_XGXS_FLAG;
6204
6205 val = REG_RD(bp,
6206 NIG_REG_XGXS0_CTRL_PHY_ADDR+
6207 params->port*0x18);
6208
6209 bnx2x_xgxs_deassert(params);
6210 bnx2x_link_initialize(params, vars);
6211
6212 vars->mac_type = MAC_TYPE_BMAC;
6213
6214 bnx2x_bmac_enable(params, vars, 0);
6215
6216 if (params->loopback_mode == LOOPBACK_XGXS) {
6217 /* set 10G XGXS loopback */
6218 params->phy[INT_PHY].config_loopback(
6219 &params->phy[INT_PHY],
6220 params);
6221
6222 } else {
6223 /* set external phy loopback */
6224 u8 phy_index;
6225 for (phy_index = EXT_PHY1;
6226 phy_index < params->num_phys; phy_index++) {
6227 if (params->phy[phy_index].config_loopback)
6228 params->phy[phy_index].config_loopback(
6229 &params->phy[phy_index],
6230 params);
6231 }
6232 }
6233
6234 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6235 params->port*4, 0);
6236
6237 bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
6238 } else
6239 /* No loopback */
6240 {
6241 if (params->switch_cfg == SWITCH_CFG_10G)
6242 bnx2x_xgxs_deassert(params);
6243 else
6244 bnx2x_serdes_deassert(bp, params->port);
6245 bnx2x_link_initialize(params, vars);
6246 msleep(30);
6247 bnx2x_link_int_enable(params);
6248 }
6249 return 0;
6250}
6251u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6252 u8 reset_ext_phy)
6253{
6254 struct bnx2x *bp = params->bp;
6255 u8 phy_index, port = params->port;
6256 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
6257 /* disable attentions */
6258 vars->link_status = 0;
6259 bnx2x_update_mng(params, vars->link_status);
6260 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6261 (NIG_MASK_XGXS0_LINK_STATUS |
6262 NIG_MASK_XGXS0_LINK10G |
6263 NIG_MASK_SERDES0_LINK_STATUS |
6264 NIG_MASK_MI_INT));
6265
6266 /* activate nig drain */
6267 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6268
6269 /* disable nig egress interface */
6270 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6271 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6272
6273 /* Stop BigMac rx */
6274 bnx2x_bmac_rx_disable(bp, port);
6275
6276 /* disable emac */
6277 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6278
6279 msleep(10);
6280 /* The PHY reset is controled by GPIO 1
6281 * Hold it as vars low
6282 */
6283 /* clear link led */
6284 bnx2x_set_led(params, LED_MODE_OFF, 0);
6285 if (reset_ext_phy) {
6286 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6287 phy_index++) {
6288 if (params->phy[phy_index].link_reset)
6289 params->phy[phy_index].link_reset(
6290 &params->phy[phy_index],
6291 params);
6292 }
6293 }
6294
6295 if (params->phy[INT_PHY].link_reset)
6296 params->phy[INT_PHY].link_reset(
6297 &params->phy[INT_PHY], params);
6298 /* reset BigMac */
6299 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
6300 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6301
6302 /* disable nig ingress interface */
6303 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
6304 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
6305 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6306 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6307 vars->link_up = 0;
6308 return 0;
6309}
6310
6311/****************************************************************************/
6312/* Common function */
6313/****************************************************************************/
6243static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) 6314static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6244{ 6315{
6245 struct bnx2x_phy phy[PORT_MAX]; 6316 struct bnx2x_phy phy[PORT_MAX];
@@ -6348,6 +6419,43 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6348 return 0; 6419 return 0;
6349} 6420}
6350 6421
6422static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6423{
6424 u32 val;
6425 s8 port;
6426 struct bnx2x_phy phy;
6427 /* Use port1 because of the static port-swap */
6428 /* Enable the module detection interrupt */
6429 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
6430 val |= ((1<<MISC_REGISTERS_GPIO_3)|
6431 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
6432 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6433
6434 bnx2x_ext_phy_hw_reset(bp, 1);
6435 msleep(5);
6436 for (port = 0; port < PORT_MAX; port++) {
6437 /* Extract the ext phy address for the port */
6438 if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base,
6439 port, &phy) !=
6440 0) {
6441 DP(NETIF_MSG_LINK, "populate phy failed\n");
6442 return -EINVAL;
6443 }
6444
6445 /* Reset phy*/
6446 bnx2x_cl45_write(bp, &phy,
6447 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
6448
6449
6450 /* Set fault module detected LED on */
6451 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6452 MISC_REGISTERS_GPIO_HIGH,
6453 port);
6454 }
6455
6456 return 0;
6457}
6458
6351static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) 6459static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6352{ 6460{
6353 s8 port, first_port, i; 6461 s8 port, first_port, i;
@@ -6420,43 +6528,6 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6420 return 0; 6528 return 0;
6421} 6529}
6422 6530
6423static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6424{
6425 u32 val;
6426 s8 port;
6427 struct bnx2x_phy phy;
6428 /* Use port1 because of the static port-swap */
6429 /* Enable the module detection interrupt */
6430 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
6431 val |= ((1<<MISC_REGISTERS_GPIO_3)|
6432 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
6433 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6434
6435 bnx2x_ext_phy_hw_reset(bp, 1);
6436 msleep(5);
6437 for (port = 0; port < PORT_MAX; port++) {
6438 /* Extract the ext phy address for the port */
6439 if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base,
6440 port, &phy) !=
6441 0) {
6442 DP(NETIF_MSG_LINK, "populate phy failed\n");
6443 return -EINVAL;
6444 }
6445
6446 /* Reset phy*/
6447 bnx2x_cl45_write(bp, &phy,
6448 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
6449
6450
6451 /* Set fault module detected LED on */
6452 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6453 MISC_REGISTERS_GPIO_HIGH,
6454 port);
6455 }
6456
6457 return 0;
6458}
6459
6460u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) 6531u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6461{ 6532{
6462 u8 rc = 0; 6533 u8 rc = 0;
@@ -6497,30 +6568,6 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6497 return rc; 6568 return rc;
6498} 6569}
6499 6570
6500void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
6501{
6502 u16 val, cnt;
6503
6504 bnx2x_cl45_read(bp, phy,
6505 MDIO_PMA_DEVAD,
6506 MDIO_PMA_REG_7101_RESET, &val);
6507
6508 for (cnt = 0; cnt < 10; cnt++) {
6509 msleep(50);
6510 /* Writes a self-clearing reset */
6511 bnx2x_cl45_write(bp, phy,
6512 MDIO_PMA_DEVAD,
6513 MDIO_PMA_REG_7101_RESET,
6514 (val | (1<<15)));
6515 /* Wait for clear */
6516 bnx2x_cl45_read(bp, phy,
6517 MDIO_PMA_DEVAD,
6518 MDIO_PMA_REG_7101_RESET, &val);
6519
6520 if ((val & (1<<15)) == 0)
6521 break;
6522 }
6523}
6524 6571
6525u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base) 6572u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base)
6526{ 6573{
diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h
index 99e11576c6e4..35f665f97be6 100644
--- a/drivers/net/bnx2x/bnx2x_link.h
+++ b/drivers/net/bnx2x/bnx2x_link.h
@@ -173,7 +173,7 @@ struct link_params {
173#define LOOPBACK_NONE 0 173#define LOOPBACK_NONE 0
174#define LOOPBACK_EMAC 1 174#define LOOPBACK_EMAC 1
175#define LOOPBACK_BMAC 2 175#define LOOPBACK_BMAC 2
176#define LOOPBACK_XGXS_10 3 176#define LOOPBACK_XGXS 3
177#define LOOPBACK_EXT_PHY 4 177#define LOOPBACK_EXT_PHY 4
178#define LOOPBACK_EXT 5 178#define LOOPBACK_EXT 5
179 179
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 0210dde760d9..30618c7ed4ed 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -1269,7 +1269,7 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
1269 bnx2x_acquire_phy_lock(bp); 1269 bnx2x_acquire_phy_lock(bp);
1270 1270
1271 if (load_mode == LOAD_DIAG) 1271 if (load_mode == LOAD_DIAG)
1272 bp->link_params.loopback_mode = LOOPBACK_XGXS_10; 1272 bp->link_params.loopback_mode = LOOPBACK_XGXS;
1273 1273
1274 rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); 1274 rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
1275 1275