aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb/igb_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/igb/igb_ethtool.c')
-rw-r--r--drivers/net/igb/igb_ethtool.c146
1 files changed, 111 insertions, 35 deletions
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index ed756c12aba6..e27d5a533b4f 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -827,8 +827,9 @@ err_setup:
827/* ethtool register test data */ 827/* ethtool register test data */
828struct igb_reg_test { 828struct igb_reg_test {
829 u16 reg; 829 u16 reg;
830 u8 array_len; 830 u16 reg_offset;
831 u8 test_type; 831 u16 array_len;
832 u16 test_type;
832 u32 mask; 833 u32 mask;
833 u32 write; 834 u32 write;
834}; 835};
@@ -850,34 +851,72 @@ struct igb_reg_test {
850#define TABLE64_TEST_LO 5 851#define TABLE64_TEST_LO 5
851#define TABLE64_TEST_HI 6 852#define TABLE64_TEST_HI 6
852 853
853/* default register test */ 854/* 82576 reg test */
855static struct igb_reg_test reg_test_82576[] = {
856 { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
857 { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
858 { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
859 { E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
860 { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
861 { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
862 { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
863 { E1000_RDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
864 { E1000_RDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
865 { E1000_RDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
866 /* Enable all four RX queues before testing. */
867 { E1000_RXDCTL(0), 0x100, 1, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
868 /* RDH is read-only for 82576, only test RDT. */
869 { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
870 { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
871 { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
872 { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
873 { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
874 { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
875 { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
876 { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
877 { E1000_TDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
878 { E1000_TDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
879 { E1000_TDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
880 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
881 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
882 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
883 { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
884 { E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
885 { E1000_RA, 0, 16, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
886 { E1000_RA2, 0, 8, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
887 { E1000_RA2, 0, 8, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
888 { E1000_MTA, 0, 128,TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
889 { 0, 0, 0, 0 }
890};
891
892/* 82575 register test */
854static struct igb_reg_test reg_test_82575[] = { 893static struct igb_reg_test reg_test_82575[] = {
855 { E1000_FCAL, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 894 { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
856 { E1000_FCAH, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF }, 895 { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
857 { E1000_FCT, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF }, 896 { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
858 { E1000_VET, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 897 { E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
859 { E1000_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, 898 { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
860 { E1000_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 899 { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
861 { E1000_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, 900 { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
862 /* Enable all four RX queues before testing. */ 901 /* Enable all four RX queues before testing. */
863 { E1000_RXDCTL(0), 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE }, 902 { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
864 /* RDH is read-only for 82575, only test RDT. */ 903 /* RDH is read-only for 82575, only test RDT. */
865 { E1000_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, 904 { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
866 { E1000_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 }, 905 { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
867 { E1000_FCRTH, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 }, 906 { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
868 { E1000_FCTTV, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, 907 { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
869 { E1000_TIPG, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF }, 908 { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
870 { E1000_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, 909 { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
871 { E1000_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 910 { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
872 { E1000_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, 911 { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
873 { E1000_RCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, 912 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
874 { E1000_RCTL, 1, SET_READ_TEST, 0x04CFB3FE, 0x003FFFFB }, 913 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB3FE, 0x003FFFFB },
875 { E1000_RCTL, 1, SET_READ_TEST, 0x04CFB3FE, 0xFFFFFFFF }, 914 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB3FE, 0xFFFFFFFF },
876 { E1000_TCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, 915 { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
877 { E1000_TXCW, 1, PATTERN_TEST, 0xC000FFFF, 0x0000FFFF }, 916 { E1000_TXCW, 0x100, 1, PATTERN_TEST, 0xC000FFFF, 0x0000FFFF },
878 { E1000_RA, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, 917 { E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
879 { E1000_RA, 16, TABLE64_TEST_HI, 0x800FFFFF, 0xFFFFFFFF }, 918 { E1000_RA, 0, 16, TABLE64_TEST_HI, 0x800FFFFF, 0xFFFFFFFF },
880 { E1000_MTA, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 919 { E1000_MTA, 0, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
881 { 0, 0, 0, 0 } 920 { 0, 0, 0, 0 }
882}; 921};
883 922
@@ -937,7 +976,15 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
937 u32 i, toggle; 976 u32 i, toggle;
938 977
939 toggle = 0x7FFFF3FF; 978 toggle = 0x7FFFF3FF;
940 test = reg_test_82575; 979
980 switch (adapter->hw.mac.type) {
981 case e1000_82576:
982 test = reg_test_82576;
983 break;
984 default:
985 test = reg_test_82575;
986 break;
987 }
941 988
942 /* Because the status register is such a special case, 989 /* Because the status register is such a special case,
943 * we handle it separately from the rest of the register 990 * we handle it separately from the rest of the register
@@ -964,19 +1011,19 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
964 for (i = 0; i < test->array_len; i++) { 1011 for (i = 0; i < test->array_len; i++) {
965 switch (test->test_type) { 1012 switch (test->test_type) {
966 case PATTERN_TEST: 1013 case PATTERN_TEST:
967 REG_PATTERN_TEST(test->reg + (i * 0x100), 1014 REG_PATTERN_TEST(test->reg + (i * test->reg_offset),
968 test->mask, 1015 test->mask,
969 test->write); 1016 test->write);
970 break; 1017 break;
971 case SET_READ_TEST: 1018 case SET_READ_TEST:
972 REG_SET_AND_CHECK(test->reg + (i * 0x100), 1019 REG_SET_AND_CHECK(test->reg + (i * test->reg_offset),
973 test->mask, 1020 test->mask,
974 test->write); 1021 test->write);
975 break; 1022 break;
976 case WRITE_NO_TEST: 1023 case WRITE_NO_TEST:
977 writel(test->write, 1024 writel(test->write,
978 (adapter->hw.hw_addr + test->reg) 1025 (adapter->hw.hw_addr + test->reg)
979 + (i * 0x100)); 1026 + (i * test->reg_offset));
980 break; 1027 break;
981 case TABLE32_TEST: 1028 case TABLE32_TEST:
982 REG_PATTERN_TEST(test->reg + (i * 4), 1029 REG_PATTERN_TEST(test->reg + (i * 4),
@@ -1392,13 +1439,39 @@ static int igb_set_phy_loopback(struct igb_adapter *adapter)
1392static int igb_setup_loopback_test(struct igb_adapter *adapter) 1439static int igb_setup_loopback_test(struct igb_adapter *adapter)
1393{ 1440{
1394 struct e1000_hw *hw = &adapter->hw; 1441 struct e1000_hw *hw = &adapter->hw;
1395 u32 rctl; 1442 u32 reg;
1396 1443
1397 if (hw->phy.media_type == e1000_media_type_fiber || 1444 if (hw->phy.media_type == e1000_media_type_fiber ||
1398 hw->phy.media_type == e1000_media_type_internal_serdes) { 1445 hw->phy.media_type == e1000_media_type_internal_serdes) {
1399 rctl = rd32(E1000_RCTL); 1446 reg = rd32(E1000_RCTL);
1400 rctl |= E1000_RCTL_LBM_TCVR; 1447 reg |= E1000_RCTL_LBM_TCVR;
1401 wr32(E1000_RCTL, rctl); 1448 wr32(E1000_RCTL, reg);
1449
1450 wr32(E1000_SCTL, E1000_ENABLE_SERDES_LOOPBACK);
1451
1452 reg = rd32(E1000_CTRL);
1453 reg &= ~(E1000_CTRL_RFCE |
1454 E1000_CTRL_TFCE |
1455 E1000_CTRL_LRST);
1456 reg |= E1000_CTRL_SLU |
1457 E1000_CTRL_FD;
1458 wr32(E1000_CTRL, reg);
1459
1460 /* Unset switch control to serdes energy detect */
1461 reg = rd32(E1000_CONNSW);
1462 reg &= ~E1000_CONNSW_ENRGSRC;
1463 wr32(E1000_CONNSW, reg);
1464
1465 /* Set PCS register for forced speed */
1466 reg = rd32(E1000_PCS_LCTL);
1467 reg &= ~E1000_PCS_LCTL_AN_ENABLE; /* Disable Autoneg*/
1468 reg |= E1000_PCS_LCTL_FLV_LINK_UP | /* Force link up */
1469 E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */
1470 E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */
1471 E1000_PCS_LCTL_FSD | /* Force Speed */
1472 E1000_PCS_LCTL_FORCE_LINK; /* Force Link */
1473 wr32(E1000_PCS_LCTL, reg);
1474
1402 return 0; 1475 return 0;
1403 } else if (hw->phy.media_type == e1000_media_type_copper) { 1476 } else if (hw->phy.media_type == e1000_media_type_copper) {
1404 return igb_set_phy_loopback(adapter); 1477 return igb_set_phy_loopback(adapter);
@@ -1654,10 +1727,13 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
1654 1727
1655 switch (hw->device_id) { 1728 switch (hw->device_id) {
1656 case E1000_DEV_ID_82575GB_QUAD_COPPER: 1729 case E1000_DEV_ID_82575GB_QUAD_COPPER:
1730 case E1000_DEV_ID_82576_QUAD_COPPER:
1657 /* WoL not supported */ 1731 /* WoL not supported */
1658 wol->supported = 0; 1732 wol->supported = 0;
1659 break; 1733 break;
1660 case E1000_DEV_ID_82575EB_FIBER_SERDES: 1734 case E1000_DEV_ID_82575EB_FIBER_SERDES:
1735 case E1000_DEV_ID_82576_FIBER:
1736 case E1000_DEV_ID_82576_SERDES:
1661 /* Wake events not supported on port B */ 1737 /* Wake events not supported on port B */
1662 if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1) { 1738 if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1) {
1663 wol->supported = 0; 1739 wol->supported = 0;