0001
0002
0003
0004 #include "igc.h"
0005 #include "igc_diag.h"
0006
0007 static struct igc_reg_test reg_test[] = {
0008 { IGC_FCAL, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
0009 { IGC_FCAH, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
0010 { IGC_FCT, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
0011 { IGC_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
0012 { IGC_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
0013 { IGC_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
0014 { IGC_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
0015 { IGC_FCRTH, 1, PATTERN_TEST, 0x0003FFF0, 0x0003FFF0 },
0016 { IGC_FCTTV, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
0017 { IGC_TIPG, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
0018 { IGC_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
0019 { IGC_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
0020 { IGC_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
0021 { IGC_TDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
0022 { IGC_RCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
0023 { IGC_RCTL, 1, SET_READ_TEST, 0x04CFB2FE, 0x003FFFFB },
0024 { IGC_RCTL, 1, SET_READ_TEST, 0x04CFB2FE, 0xFFFFFFFF },
0025 { IGC_TCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
0026 { IGC_RA, 16, TABLE64_TEST_LO,
0027 0xFFFFFFFF, 0xFFFFFFFF },
0028 { IGC_RA, 16, TABLE64_TEST_HI,
0029 0x900FFFFF, 0xFFFFFFFF },
0030 { IGC_MTA, 128, TABLE32_TEST,
0031 0xFFFFFFFF, 0xFFFFFFFF },
0032 { 0, 0, 0, 0}
0033 };
0034
0035 static bool reg_pattern_test(struct igc_adapter *adapter, u64 *data, int reg,
0036 u32 mask, u32 write)
0037 {
0038 struct igc_hw *hw = &adapter->hw;
0039 u32 pat, val, before;
0040 static const u32 test_pattern[] = {
0041 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
0042 };
0043
0044 for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) {
0045 before = rd32(reg);
0046 wr32(reg, test_pattern[pat] & write);
0047 val = rd32(reg);
0048 if (val != (test_pattern[pat] & write & mask)) {
0049 netdev_err(adapter->netdev,
0050 "pattern test reg %04X failed: got 0x%08X expected 0x%08X",
0051 reg, val, test_pattern[pat] & write & mask);
0052 *data = reg;
0053 wr32(reg, before);
0054 return false;
0055 }
0056 wr32(reg, before);
0057 }
0058 return true;
0059 }
0060
0061 static bool reg_set_and_check(struct igc_adapter *adapter, u64 *data, int reg,
0062 u32 mask, u32 write)
0063 {
0064 struct igc_hw *hw = &adapter->hw;
0065 u32 val, before;
0066
0067 before = rd32(reg);
0068 wr32(reg, write & mask);
0069 val = rd32(reg);
0070 if ((write & mask) != (val & mask)) {
0071 netdev_err(adapter->netdev,
0072 "set/check reg %04X test failed: got 0x%08X expected 0x%08X",
0073 reg, (val & mask), (write & mask));
0074 *data = reg;
0075 wr32(reg, before);
0076 return false;
0077 }
0078 wr32(reg, before);
0079 return true;
0080 }
0081
0082 bool igc_reg_test(struct igc_adapter *adapter, u64 *data)
0083 {
0084 struct igc_reg_test *test = reg_test;
0085 struct igc_hw *hw = &adapter->hw;
0086 u32 value, before, after;
0087 u32 i, toggle, b = false;
0088
0089
0090
0091
0092
0093
0094 toggle = 0x6800D3;
0095 before = rd32(IGC_STATUS);
0096 value = before & toggle;
0097 wr32(IGC_STATUS, toggle);
0098 after = rd32(IGC_STATUS) & toggle;
0099 if (value != after) {
0100 netdev_err(adapter->netdev,
0101 "failed STATUS register test got: 0x%08X expected: 0x%08X",
0102 after, value);
0103 *data = 1;
0104 return false;
0105 }
0106
0107 wr32(IGC_STATUS, before);
0108
0109
0110
0111
0112 while (test->reg) {
0113 for (i = 0; i < test->array_len; i++) {
0114 switch (test->test_type) {
0115 case PATTERN_TEST:
0116 b = reg_pattern_test(adapter, data,
0117 test->reg + (i * 0x40),
0118 test->mask,
0119 test->write);
0120 break;
0121 case SET_READ_TEST:
0122 b = reg_set_and_check(adapter, data,
0123 test->reg + (i * 0x40),
0124 test->mask,
0125 test->write);
0126 break;
0127 case TABLE64_TEST_LO:
0128 b = reg_pattern_test(adapter, data,
0129 test->reg + (i * 8),
0130 test->mask,
0131 test->write);
0132 break;
0133 case TABLE64_TEST_HI:
0134 b = reg_pattern_test(adapter, data,
0135 test->reg + 4 + (i * 8),
0136 test->mask,
0137 test->write);
0138 break;
0139 case TABLE32_TEST:
0140 b = reg_pattern_test(adapter, data,
0141 test->reg + (i * 4),
0142 test->mask,
0143 test->write);
0144 break;
0145 }
0146 if (!b)
0147 return false;
0148 }
0149 test++;
0150 }
0151 *data = 0;
0152 return true;
0153 }
0154
0155 bool igc_eeprom_test(struct igc_adapter *adapter, u64 *data)
0156 {
0157 struct igc_hw *hw = &adapter->hw;
0158
0159 *data = 0;
0160
0161 if (hw->nvm.ops.validate(hw) != IGC_SUCCESS) {
0162 *data = 1;
0163 return false;
0164 }
0165
0166 return true;
0167 }
0168
0169 bool igc_link_test(struct igc_adapter *adapter, u64 *data)
0170 {
0171 bool link_up;
0172
0173 *data = 0;
0174
0175
0176 if (adapter->hw.mac.autoneg)
0177 ssleep(5);
0178
0179 link_up = igc_has_link(adapter);
0180 if (!link_up) {
0181 *data = 1;
0182 return false;
0183 }
0184
0185 return true;
0186 }