aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb/igb_ethtool.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-02-06 18:18:48 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-07 05:43:08 -0500
commit2753f4cebf034a53f87b24679f394854275dcacb (patch)
treee653a2187ee4960174451b4b9ec4cfee2c8d5d66 /drivers/net/igb/igb_ethtool.c
parent7d8eb29e6eae9cc13e1975daf28d2ae789c1f110 (diff)
igb: update testing done by ethtool
Most of the code for the testing has pretty much become stale at this point and is need of update. This update just streamlines most of the code, widens the range of interrupt testing. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb/igb_ethtool.c')
-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 d7bdc6c16d0e..33c23a117fe6 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 */