Skip to content

Commit

Permalink
igb: update testing done by ethtool
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alexander Duyck authored and David S. Miller committed Feb 7, 2009
1 parent 7d8eb29 commit 2753f4c
Showing 1 changed file with 61 additions and 26 deletions.
87 changes: 61 additions & 26 deletions drivers/net/igb/igb_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,23 +855,26 @@ static struct igb_reg_test reg_test_82576[] = {
{ E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_RDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_RDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
/* Enable all four RX queues before testing. */
{ E1000_RXDCTL(0), 0x100, 1, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
{ E1000_RDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_RDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
/* Enable all RX queues before testing. */
{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
{ E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
/* RDH is read-only for 82576, only test RDT. */
{ E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RDT(4), 0x40, 12, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
{ E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, 0 },
{ E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
{ E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
{ E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_TDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_TDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_TDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_TDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_TDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_TDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
Expand Down Expand Up @@ -918,12 +921,13 @@ static struct igb_reg_test reg_test_82575[] = {
static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
int reg, u32 mask, u32 write)
{
struct e1000_hw *hw = &adapter->hw;
u32 pat, val;
u32 _test[] =
{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
writel((_test[pat] & write), (adapter->hw.hw_addr + reg));
val = readl(adapter->hw.hw_addr + reg);
wr32(reg, (_test[pat] & write));
val = rd32(reg);
if (val != (_test[pat] & write & mask)) {
dev_err(&adapter->pdev->dev, "pattern test reg %04X "
"failed: got 0x%08X expected 0x%08X\n",
Expand All @@ -938,9 +942,10 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
int reg, u32 mask, u32 write)
{
struct e1000_hw *hw = &adapter->hw;
u32 val;
writel((write & mask), (adapter->hw.hw_addr + reg));
val = readl(adapter->hw.hw_addr + reg);
wr32(reg, write & mask);
val = rd32(reg);
if ((write & mask) != (val & mask)) {
dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:"
" got 0x%08X expected 0x%08X\n", reg,
Expand Down Expand Up @@ -1006,12 +1011,14 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
for (i = 0; i < test->array_len; i++) {
switch (test->test_type) {
case PATTERN_TEST:
REG_PATTERN_TEST(test->reg + (i * test->reg_offset),
REG_PATTERN_TEST(test->reg +
(i * test->reg_offset),
test->mask,
test->write);
break;
case SET_READ_TEST:
REG_SET_AND_CHECK(test->reg + (i * test->reg_offset),
REG_SET_AND_CHECK(test->reg +
(i * test->reg_offset),
test->mask,
test->write);
break;
Expand Down Expand Up @@ -1083,16 +1090,17 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
{
struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
u32 mask, i = 0, shared_int = true;
u32 mask, ics_mask, i = 0, shared_int = true;
u32 irq = adapter->pdev->irq;

*data = 0;

/* Hook up test interrupt handler just for this test */
if (adapter->msix_entries) {
if (adapter->msix_entries)
/* NOTE: we don't test MSI-X interrupts here, yet */
return 0;
} else if (adapter->flags & IGB_FLAG_HAS_MSI) {

if (adapter->flags & IGB_FLAG_HAS_MSI) {
shared_int = false;
if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
*data = 1;
Expand All @@ -1108,16 +1116,31 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
}
dev_info(&adapter->pdev->dev, "testing %s interrupt\n",
(shared_int ? "shared" : "unshared"));

/* Disable all the interrupts */
wr32(E1000_IMC, 0xFFFFFFFF);
msleep(10);

/* Define all writable bits for ICS */
switch(hw->mac.type) {
case e1000_82575:
ics_mask = 0x37F47EDD;
break;
case e1000_82576:
ics_mask = 0x77D4FBFD;
break;
default:
ics_mask = 0x7FFFFFFF;
break;
}

/* Test each interrupt */
for (; i < 10; i++) {
for (; i < 31; i++) {
/* Interrupt to test */
mask = 1 << i;

if (!(mask & ics_mask))
continue;

if (!shared_int) {
/* Disable the interrupt to be reported in
* the cause register and then force the same
Expand All @@ -1126,8 +1149,12 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
* test failed.
*/
adapter->test_icr = 0;
wr32(E1000_IMC, ~mask & 0x00007FFF);
wr32(E1000_ICS, ~mask & 0x00007FFF);

/* Flush any pending interrupts */
wr32(E1000_ICR, ~0);

wr32(E1000_IMC, mask);
wr32(E1000_ICS, mask);
msleep(10);

if (adapter->test_icr & mask) {
Expand All @@ -1143,6 +1170,10 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
* test failed.
*/
adapter->test_icr = 0;

/* Flush any pending interrupts */
wr32(E1000_ICR, ~0);

wr32(E1000_IMS, mask);
wr32(E1000_ICS, mask);
msleep(10);
Expand All @@ -1160,19 +1191,23 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
* test failed.
*/
adapter->test_icr = 0;
wr32(E1000_IMC, ~mask & 0x00007FFF);
wr32(E1000_ICS, ~mask & 0x00007FFF);

/* Flush any pending interrupts */
wr32(E1000_ICR, ~0);

wr32(E1000_IMC, ~mask);
wr32(E1000_ICS, ~mask);
msleep(10);

if (adapter->test_icr) {
if (adapter->test_icr & mask) {
*data = 5;
break;
}
}
}

/* Disable all the interrupts */
wr32(E1000_IMC, 0xFFFFFFFF);
wr32(E1000_IMC, ~0);
msleep(10);

/* Unhook test interrupt handler */
Expand Down Expand Up @@ -1450,7 +1485,7 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter)
E1000_CTRL_TFCE |
E1000_CTRL_LRST);
reg |= E1000_CTRL_SLU |
E1000_CTRL_FD;
E1000_CTRL_FD;
wr32(E1000_CTRL, reg);

/* Unset switch control to serdes energy detect */
Expand Down

0 comments on commit 2753f4c

Please sign in to comment.