diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 108 |
1 files changed, 62 insertions, 46 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index bcba057b510f..410c29875785 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
| @@ -1236,46 +1236,62 @@ static const struct ixgbe_reg_test reg_test_82598[] = { | |||
| 1236 | { 0, 0, 0, 0 } | 1236 | { 0, 0, 0, 0 } |
| 1237 | }; | 1237 | }; |
| 1238 | 1238 | ||
| 1239 | static const u32 register_test_patterns[] = { | 1239 | static bool reg_pattern_test(struct ixgbe_adapter *adapter, u64 *data, int reg, |
| 1240 | 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF | 1240 | u32 mask, u32 write) |
| 1241 | }; | 1241 | { |
| 1242 | 1242 | u32 pat, val, before; | |
| 1243 | #define REG_PATTERN_TEST(R, M, W) \ | 1243 | static const u32 test_pattern[] = { |
| 1244 | { \ | 1244 | 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; |
| 1245 | u32 pat, val, before; \ | 1245 | |
| 1246 | for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { \ | 1246 | for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) { |
| 1247 | before = readl(adapter->hw.hw_addr + R); \ | 1247 | before = readl(adapter->hw.hw_addr + reg); |
| 1248 | writel((register_test_patterns[pat] & W), \ | 1248 | writel((test_pattern[pat] & write), |
| 1249 | (adapter->hw.hw_addr + R)); \ | 1249 | (adapter->hw.hw_addr + reg)); |
| 1250 | val = readl(adapter->hw.hw_addr + R); \ | 1250 | val = readl(adapter->hw.hw_addr + reg); |
| 1251 | if (val != (register_test_patterns[pat] & W & M)) { \ | 1251 | if (val != (test_pattern[pat] & write & mask)) { |
| 1252 | e_err(drv, "pattern test reg %04X failed: got " \ | 1252 | e_err(drv, "pattern test reg %04X failed: got " |
| 1253 | "0x%08X expected 0x%08X\n", \ | 1253 | "0x%08X expected 0x%08X\n", |
| 1254 | R, val, (register_test_patterns[pat] & W & M)); \ | 1254 | reg, val, (test_pattern[pat] & write & mask)); |
| 1255 | *data = R; \ | 1255 | *data = reg; |
| 1256 | writel(before, adapter->hw.hw_addr + R); \ | 1256 | writel(before, adapter->hw.hw_addr + reg); |
| 1257 | return 1; \ | 1257 | return 1; |
| 1258 | } \ | 1258 | } |
| 1259 | writel(before, adapter->hw.hw_addr + R); \ | 1259 | writel(before, adapter->hw.hw_addr + reg); |
| 1260 | } \ | 1260 | } |
| 1261 | return 0; | ||
| 1261 | } | 1262 | } |
| 1262 | 1263 | ||
| 1263 | #define REG_SET_AND_CHECK(R, M, W) \ | 1264 | static bool reg_set_and_check(struct ixgbe_adapter *adapter, u64 *data, int reg, |
| 1264 | { \ | 1265 | u32 mask, u32 write) |
| 1265 | u32 val, before; \ | 1266 | { |
| 1266 | before = readl(adapter->hw.hw_addr + R); \ | 1267 | u32 val, before; |
| 1267 | writel((W & M), (adapter->hw.hw_addr + R)); \ | 1268 | before = readl(adapter->hw.hw_addr + reg); |
| 1268 | val = readl(adapter->hw.hw_addr + R); \ | 1269 | writel((write & mask), (adapter->hw.hw_addr + reg)); |
| 1269 | if ((W & M) != (val & M)) { \ | 1270 | val = readl(adapter->hw.hw_addr + reg); |
| 1270 | e_err(drv, "set/check reg %04X test failed: got 0x%08X " \ | 1271 | if ((write & mask) != (val & mask)) { |
| 1271 | "expected 0x%08X\n", R, (val & M), (W & M)); \ | 1272 | e_err(drv, "set/check reg %04X test failed: got 0x%08X " |
| 1272 | *data = R; \ | 1273 | "expected 0x%08X\n", reg, (val & mask), (write & mask)); |
| 1273 | writel(before, (adapter->hw.hw_addr + R)); \ | 1274 | *data = reg; |
| 1274 | return 1; \ | 1275 | writel(before, (adapter->hw.hw_addr + reg)); |
| 1275 | } \ | 1276 | return 1; |
| 1276 | writel(before, (adapter->hw.hw_addr + R)); \ | 1277 | } |
| 1278 | writel(before, (adapter->hw.hw_addr + reg)); | ||
| 1279 | return 0; | ||
| 1277 | } | 1280 | } |
| 1278 | 1281 | ||
| 1282 | #define REG_PATTERN_TEST(reg, mask, write) \ | ||
| 1283 | do { \ | ||
| 1284 | if (reg_pattern_test(adapter, data, reg, mask, write)) \ | ||
| 1285 | return 1; \ | ||
| 1286 | } while (0) \ | ||
| 1287 | |||
| 1288 | |||
| 1289 | #define REG_SET_AND_CHECK(reg, mask, write) \ | ||
| 1290 | do { \ | ||
| 1291 | if (reg_set_and_check(adapter, data, reg, mask, write)) \ | ||
| 1292 | return 1; \ | ||
| 1293 | } while (0) \ | ||
| 1294 | |||
| 1279 | static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) | 1295 | static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) |
| 1280 | { | 1296 | { |
| 1281 | const struct ixgbe_reg_test *test; | 1297 | const struct ixgbe_reg_test *test; |
| @@ -1326,13 +1342,13 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) | |||
| 1326 | switch (test->test_type) { | 1342 | switch (test->test_type) { |
| 1327 | case PATTERN_TEST: | 1343 | case PATTERN_TEST: |
| 1328 | REG_PATTERN_TEST(test->reg + (i * 0x40), | 1344 | REG_PATTERN_TEST(test->reg + (i * 0x40), |
| 1329 | test->mask, | 1345 | test->mask, |
| 1330 | test->write); | 1346 | test->write); |
| 1331 | break; | 1347 | break; |
| 1332 | case SET_READ_TEST: | 1348 | case SET_READ_TEST: |
| 1333 | REG_SET_AND_CHECK(test->reg + (i * 0x40), | 1349 | REG_SET_AND_CHECK(test->reg + (i * 0x40), |
| 1334 | test->mask, | 1350 | test->mask, |
| 1335 | test->write); | 1351 | test->write); |
| 1336 | break; | 1352 | break; |
| 1337 | case WRITE_NO_TEST: | 1353 | case WRITE_NO_TEST: |
| 1338 | writel(test->write, | 1354 | writel(test->write, |
| @@ -1341,18 +1357,18 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) | |||
| 1341 | break; | 1357 | break; |
| 1342 | case TABLE32_TEST: | 1358 | case TABLE32_TEST: |
| 1343 | REG_PATTERN_TEST(test->reg + (i * 4), | 1359 | REG_PATTERN_TEST(test->reg + (i * 4), |
| 1344 | test->mask, | 1360 | test->mask, |
| 1345 | test->write); | 1361 | test->write); |
| 1346 | break; | 1362 | break; |
| 1347 | case TABLE64_TEST_LO: | 1363 | case TABLE64_TEST_LO: |
| 1348 | REG_PATTERN_TEST(test->reg + (i * 8), | 1364 | REG_PATTERN_TEST(test->reg + (i * 8), |
| 1349 | test->mask, | 1365 | test->mask, |
| 1350 | test->write); | 1366 | test->write); |
| 1351 | break; | 1367 | break; |
| 1352 | case TABLE64_TEST_HI: | 1368 | case TABLE64_TEST_HI: |
| 1353 | REG_PATTERN_TEST((test->reg + 4) + (i * 8), | 1369 | REG_PATTERN_TEST((test->reg + 4) + (i * 8), |
| 1354 | test->mask, | 1370 | test->mask, |
| 1355 | test->write); | 1371 | test->write); |
| 1356 | break; | 1372 | break; |
| 1357 | } | 1373 | } |
| 1358 | } | 1374 | } |
