aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/igb/igb_ethtool.c87
1 files changed, 61 insertions, 26 deletions
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index d7bdc6c16d0..33c23a117fe 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -855,23 +855,26 @@ static struct igb_reg_test reg_test_82576[] = {
855 { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, 855 { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
856 { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 856 { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
857 { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, 857 { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
858 { E1000_RDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, 858 { E1000_RDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
859 { E1000_RDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 859 { E1000_RDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
860 { E1000_RDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, 860 { E1000_RDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
861 /* Enable all four RX queues before testing. */ 861 /* Enable all RX queues before testing. */
862 { E1000_RXDCTL(0), 0x100, 1, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE }, 862 { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
863 { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
863 /* RDH is read-only for 82576, only test RDT. */ 864 /* RDH is read-only for 82576, only test RDT. */
864 { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, 865 { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
866 { E1000_RDT(4), 0x40, 12, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
865 { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 }, 867 { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
868 { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, 0 },
866 { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 }, 869 { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
867 { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, 870 { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
868 { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF }, 871 { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
869 { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, 872 { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
870 { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 873 { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
871 { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, 874 { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
872 { E1000_TDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, 875 { E1000_TDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
873 { E1000_TDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 876 { E1000_TDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
874 { E1000_TDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, 877 { E1000_TDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
875 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, 878 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
876 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, 879 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
877 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, 880 { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
@@ -918,12 +921,13 @@ static struct igb_reg_test reg_test_82575[] = {
918static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, 921static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
919 int reg, u32 mask, u32 write) 922 int reg, u32 mask, u32 write)
920{ 923{
924 struct e1000_hw *hw = &adapter->hw;
921 u32 pat, val; 925 u32 pat, val;
922 u32 _test[] = 926 u32 _test[] =
923 {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; 927 {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
924 for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { 928 for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
925 writel((_test[pat] & write), (adapter->hw.hw_addr + reg)); 929 wr32(reg, (_test[pat] & write));
926 val = readl(adapter->hw.hw_addr + reg); 930 val = rd32(reg);
927 if (val != (_test[pat] & write & mask)) { 931 if (val != (_test[pat] & write & mask)) {
928 dev_err(&adapter->pdev->dev, "pattern test reg %04X " 932 dev_err(&adapter->pdev->dev, "pattern test reg %04X "
929 "failed: got 0x%08X expected 0x%08X\n", 933 "failed: got 0x%08X expected 0x%08X\n",
@@ -938,9 +942,10 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
938static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data, 942static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
939 int reg, u32 mask, u32 write) 943 int reg, u32 mask, u32 write)
940{ 944{
945 struct e1000_hw *hw = &adapter->hw;
941 u32 val; 946 u32 val;
942 writel((write & mask), (adapter->hw.hw_addr + reg)); 947 wr32(reg, write & mask);
943 val = readl(adapter->hw.hw_addr + reg); 948 val = rd32(reg);
944 if ((write & mask) != (val & mask)) { 949 if ((write & mask) != (val & mask)) {
945 dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:" 950 dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:"
946 " got 0x%08X expected 0x%08X\n", reg, 951 " got 0x%08X expected 0x%08X\n", reg,
@@ -1006,12 +1011,14 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
1006 for (i = 0; i < test->array_len; i++) { 1011 for (i = 0; i < test->array_len; i++) {
1007 switch (test->test_type) { 1012 switch (test->test_type) {
1008 case PATTERN_TEST: 1013 case PATTERN_TEST:
1009 REG_PATTERN_TEST(test->reg + (i * test->reg_offset), 1014 REG_PATTERN_TEST(test->reg +
1015 (i * test->reg_offset),
1010 test->mask, 1016 test->mask,
1011 test->write); 1017 test->write);
1012 break; 1018 break;
1013 case SET_READ_TEST: 1019 case SET_READ_TEST:
1014 REG_SET_AND_CHECK(test->reg + (i * test->reg_offset), 1020 REG_SET_AND_CHECK(test->reg +
1021 (i * test->reg_offset),
1015 test->mask, 1022 test->mask,
1016 test->write); 1023 test->write);
1017 break; 1024 break;
@@ -1083,16 +1090,17 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
1083{ 1090{
1084 struct e1000_hw *hw = &adapter->hw; 1091 struct e1000_hw *hw = &adapter->hw;
1085 struct net_device *netdev = adapter->netdev; 1092 struct net_device *netdev = adapter->netdev;
1086 u32 mask, i = 0, shared_int = true; 1093 u32 mask, ics_mask, i = 0, shared_int = true;
1087 u32 irq = adapter->pdev->irq; 1094 u32 irq = adapter->pdev->irq;
1088 1095
1089 *data = 0; 1096 *data = 0;
1090 1097
1091 /* Hook up test interrupt handler just for this test */ 1098 /* Hook up test interrupt handler just for this test */
1092 if (adapter->msix_entries) { 1099 if (adapter->msix_entries)
1093 /* NOTE: we don't test MSI-X interrupts here, yet */ 1100 /* NOTE: we don't test MSI-X interrupts here, yet */
1094 return 0; 1101 return 0;
1095 } else if (adapter->flags & IGB_FLAG_HAS_MSI) { 1102
1103 if (adapter->flags & IGB_FLAG_HAS_MSI) {
1096 shared_int = false; 1104 shared_int = false;
1097 if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) { 1105 if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
1098 *data = 1; 1106 *data = 1;
@@ -1108,16 +1116,31 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
1108 } 1116 }
1109 dev_info(&adapter->pdev->dev, "testing %s interrupt\n", 1117 dev_info(&adapter->pdev->dev, "testing %s interrupt\n",
1110 (shared_int ? "shared" : "unshared")); 1118 (shared_int ? "shared" : "unshared"));
1111
1112 /* Disable all the interrupts */ 1119 /* Disable all the interrupts */
1113 wr32(E1000_IMC, 0xFFFFFFFF); 1120 wr32(E1000_IMC, 0xFFFFFFFF);
1114 msleep(10); 1121 msleep(10);
1115 1122
1123 /* Define all writable bits for ICS */
1124 switch(hw->mac.type) {
1125 case e1000_82575:
1126 ics_mask = 0x37F47EDD;
1127 break;
1128 case e1000_82576:
1129 ics_mask = 0x77D4FBFD;
1130 break;
1131 default:
1132 ics_mask = 0x7FFFFFFF;
1133 break;
1134 }
1135
1116 /* Test each interrupt */ 1136 /* Test each interrupt */
1117 for (; i < 10; i++) { 1137 for (; i < 31; i++) {
1118 /* Interrupt to test */ 1138 /* Interrupt to test */
1119 mask = 1 << i; 1139 mask = 1 << i;
1120 1140
1141 if (!(mask & ics_mask))
1142 continue;
1143
1121 if (!shared_int) { 1144 if (!shared_int) {
1122 /* Disable the interrupt to be reported in 1145 /* Disable the interrupt to be reported in
1123 * the cause register and then force the same 1146 * the cause register and then force the same
@@ -1126,8 +1149,12 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
1126 * test failed. 1149 * test failed.
1127 */ 1150 */
1128 adapter->test_icr = 0; 1151 adapter->test_icr = 0;
1129 wr32(E1000_IMC, ~mask & 0x00007FFF); 1152
1130 wr32(E1000_ICS, ~mask & 0x00007FFF); 1153 /* Flush any pending interrupts */
1154 wr32(E1000_ICR, ~0);
1155
1156 wr32(E1000_IMC, mask);
1157 wr32(E1000_ICS, mask);
1131 msleep(10); 1158 msleep(10);
1132 1159
1133 if (adapter->test_icr & mask) { 1160 if (adapter->test_icr & mask) {
@@ -1143,6 +1170,10 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
1143 * test failed. 1170 * test failed.
1144 */ 1171 */
1145 adapter->test_icr = 0; 1172 adapter->test_icr = 0;
1173
1174 /* Flush any pending interrupts */
1175 wr32(E1000_ICR, ~0);
1176
1146 wr32(E1000_IMS, mask); 1177 wr32(E1000_IMS, mask);
1147 wr32(E1000_ICS, mask); 1178 wr32(E1000_ICS, mask);
1148 msleep(10); 1179 msleep(10);
@@ -1160,11 +1191,15 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
1160 * test failed. 1191 * test failed.
1161 */ 1192 */
1162 adapter->test_icr = 0; 1193 adapter->test_icr = 0;
1163 wr32(E1000_IMC, ~mask & 0x00007FFF); 1194
1164 wr32(E1000_ICS, ~mask & 0x00007FFF); 1195 /* Flush any pending interrupts */
1196 wr32(E1000_ICR, ~0);
1197
1198 wr32(E1000_IMC, ~mask);
1199 wr32(E1000_ICS, ~mask);
1165 msleep(10); 1200 msleep(10);
1166 1201
1167 if (adapter->test_icr) { 1202 if (adapter->test_icr & mask) {
1168 *data = 5; 1203 *data = 5;
1169 break; 1204 break;
1170 } 1205 }
@@ -1172,7 +1207,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
1172 } 1207 }
1173 1208
1174 /* Disable all the interrupts */ 1209 /* Disable all the interrupts */
1175 wr32(E1000_IMC, 0xFFFFFFFF); 1210 wr32(E1000_IMC, ~0);
1176 msleep(10); 1211 msleep(10);
1177 1212
1178 /* Unhook test interrupt handler */ 1213 /* Unhook test interrupt handler */
@@ -1450,7 +1485,7 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter)
1450 E1000_CTRL_TFCE | 1485 E1000_CTRL_TFCE |
1451 E1000_CTRL_LRST); 1486 E1000_CTRL_LRST);
1452 reg |= E1000_CTRL_SLU | 1487 reg |= E1000_CTRL_SLU |
1453 E1000_CTRL_FD; 1488 E1000_CTRL_FD;
1454 wr32(E1000_CTRL, reg); 1489 wr32(E1000_CTRL, reg);
1455 1490
1456 /* Unset switch control to serdes energy detect */ 1491 /* Unset switch control to serdes energy detect */