brintos

brintos / linux-shallow public Read only

0
0
Text · 4.9 KiB · cc62197 Raw
187 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c)  2020 Intel Corporation */3 4#include "igc.h"5#include "igc_diag.h"6 7static struct igc_reg_test reg_test[] = {8	{ IGC_FCAL,	1,	PATTERN_TEST,	0xFFFFFFFF,	0xFFFFFFFF },9	{ IGC_FCAH,	1,	PATTERN_TEST,	0x0000FFFF,	0xFFFFFFFF },10	{ IGC_FCT,	1,	PATTERN_TEST,	0x0000FFFF,	0xFFFFFFFF },11	{ IGC_RDBAH(0), 4,	PATTERN_TEST,	0xFFFFFFFF,	0xFFFFFFFF },12	{ IGC_RDBAL(0),	4,	PATTERN_TEST,	0xFFFFFF80,	0xFFFFFF80 },13	{ IGC_RDLEN(0),	4,	PATTERN_TEST,	0x000FFF80,	0x000FFFFF },14	{ IGC_RDT(0),	4,	PATTERN_TEST,	0x0000FFFF,	0x0000FFFF },15	{ IGC_FCRTH,	1,	PATTERN_TEST,	0x0003FFF0,	0x0003FFF0 },16	{ IGC_FCTTV,	1,	PATTERN_TEST,	0x0000FFFF,	0x0000FFFF },17	{ IGC_TIPG,	1,	PATTERN_TEST,	0x3FFFFFFF,	0x3FFFFFFF },18	{ IGC_TDBAH(0),	4,	PATTERN_TEST,	0xFFFFFFFF,	0xFFFFFFFF },19	{ IGC_TDBAL(0),	4,	PATTERN_TEST,	0xFFFFFF80,	0xFFFFFF80 },20	{ IGC_TDLEN(0),	4,	PATTERN_TEST,	0x000FFF80,	0x000FFFFF },21	{ IGC_TDT(0),	4,	PATTERN_TEST,	0x0000FFFF,	0x0000FFFF },22	{ IGC_RCTL,	1,	SET_READ_TEST,	0xFFFFFFFF,	0x00000000 },23	{ IGC_RCTL,	1,	SET_READ_TEST,	0x04CFB2FE,	0x003FFFFB },24	{ IGC_RCTL,	1,	SET_READ_TEST,	0x04CFB2FE,	0xFFFFFFFF },25	{ IGC_TCTL,	1,	SET_READ_TEST,	0xFFFFFFFF,	0x00000000 },26	{ IGC_RA,	16,	TABLE64_TEST_LO,27						0xFFFFFFFF,	0xFFFFFFFF },28	{ IGC_RA,	16,	TABLE64_TEST_HI,29						0x900FFFFF,	0xFFFFFFFF },30	{ IGC_MTA,	128,	TABLE32_TEST,31						0xFFFFFFFF,	0xFFFFFFFF },32	{ 0, 0, 0, 0}33};34 35static bool reg_pattern_test(struct igc_adapter *adapter, u64 *data, int reg,36			     u32 mask, u32 write)37{38	struct igc_hw *hw = &adapter->hw;39	u32 pat, val, before;40	static const u32 test_pattern[] = {41		0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF42	};43 44	for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) {45		before = rd32(reg);46		wr32(reg, test_pattern[pat] & write);47		val = rd32(reg);48		if (val != (test_pattern[pat] & write & mask)) {49			netdev_err(adapter->netdev,50				   "pattern test reg %04X failed: got 0x%08X expected 0x%08X",51				   reg, val, test_pattern[pat] & write & mask);52			*data = reg;53			wr32(reg, before);54			return false;55		}56		wr32(reg, before);57	}58	return true;59}60 61static bool reg_set_and_check(struct igc_adapter *adapter, u64 *data, int reg,62			      u32 mask, u32 write)63{64	struct igc_hw *hw = &adapter->hw;65	u32 val, before;66 67	before = rd32(reg);68	wr32(reg, write & mask);69	val = rd32(reg);70	if ((write & mask) != (val & mask)) {71		netdev_err(adapter->netdev,72			   "set/check reg %04X test failed: got 0x%08X expected 0x%08X",73			   reg, (val & mask), (write & mask));74		*data = reg;75		wr32(reg, before);76		return false;77	}78	wr32(reg, before);79	return true;80}81 82bool igc_reg_test(struct igc_adapter *adapter, u64 *data)83{84	struct igc_reg_test *test = reg_test;85	struct igc_hw *hw = &adapter->hw;86	u32 value, before, after;87	u32 i, toggle, b = false;88 89	/* Because the status register is such a special case,90	 * we handle it separately from the rest of the register91	 * tests.  Some bits are read-only, some toggle, and some92	 * are writeable.93	 */94	toggle = 0x6800D3;95	before = rd32(IGC_STATUS);96	value = before & toggle;97	wr32(IGC_STATUS, toggle);98	after = rd32(IGC_STATUS) & toggle;99	if (value != after) {100		netdev_err(adapter->netdev,101			   "failed STATUS register test got: 0x%08X expected: 0x%08X",102			   after, value);103		*data = 1;104		return false;105	}106	/* restore previous status */107	wr32(IGC_STATUS, before);108 109	/* Perform the remainder of the register test, looping through110	 * the test table until we either fail or reach the null entry.111	 */112	while (test->reg) {113		for (i = 0; i < test->array_len; i++) {114			switch (test->test_type) {115			case PATTERN_TEST:116				b = reg_pattern_test(adapter, data,117						     test->reg + (i * 0x40),118						     test->mask,119						     test->write);120				break;121			case SET_READ_TEST:122				b = reg_set_and_check(adapter, data,123						      test->reg + (i * 0x40),124						      test->mask,125						      test->write);126				break;127			case TABLE64_TEST_LO:128				b = reg_pattern_test(adapter, data,129						     test->reg + (i * 8),130						     test->mask,131						     test->write);132				break;133			case TABLE64_TEST_HI:134				b = reg_pattern_test(adapter, data,135						     test->reg + 4 + (i * 8),136						     test->mask,137						     test->write);138				break;139			case TABLE32_TEST:140				b = reg_pattern_test(adapter, data,141						     test->reg + (i * 4),142						     test->mask,143						     test->write);144				break;145			}146			if (!b)147				return false;148		}149		test++;150	}151	*data = 0;152	return true;153}154 155bool igc_eeprom_test(struct igc_adapter *adapter, u64 *data)156{157	struct igc_hw *hw = &adapter->hw;158 159	*data = 0;160 161	if (hw->nvm.ops.validate(hw) != IGC_SUCCESS) {162		*data = 1;163		return false;164	}165 166	return true;167}168 169bool igc_link_test(struct igc_adapter *adapter, u64 *data)170{171	bool link_up;172 173	*data = 0;174 175	/* add delay to give enough time for autonegotioation to finish */176	if (adapter->hw.mac.autoneg)177		ssleep(5);178 179	link_up = igc_has_link(adapter);180	if (!link_up) {181		*data = 1;182		return false;183	}184 185	return true;186}187