1a551c94aSIdo Barnea/*******************************************************************************
2a551c94aSIdo Barnea
3a551c94aSIdo BarneaCopyright (c) 2013 - 2015, Intel Corporation
4a551c94aSIdo BarneaAll rights reserved.
5a551c94aSIdo Barnea
6a551c94aSIdo BarneaRedistribution and use in source and binary forms, with or without
7a551c94aSIdo Barneamodification, are permitted provided that the following conditions are met:
8a551c94aSIdo Barnea
9a551c94aSIdo Barnea 1. Redistributions of source code must retain the above copyright notice,
10a551c94aSIdo Barnea    this list of conditions and the following disclaimer.
11a551c94aSIdo Barnea
12a551c94aSIdo Barnea 2. Redistributions in binary form must reproduce the above copyright
13a551c94aSIdo Barnea    notice, this list of conditions and the following disclaimer in the
14a551c94aSIdo Barnea    documentation and/or other materials provided with the distribution.
15a551c94aSIdo Barnea
16a551c94aSIdo Barnea 3. Neither the name of the Intel Corporation nor the names of its
17a551c94aSIdo Barnea    contributors may be used to endorse or promote products derived from
18a551c94aSIdo Barnea    this software without specific prior written permission.
19a551c94aSIdo Barnea
20a551c94aSIdo BarneaTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21a551c94aSIdo BarneaAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22a551c94aSIdo BarneaIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23a551c94aSIdo BarneaARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24a551c94aSIdo BarneaLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25a551c94aSIdo BarneaCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26a551c94aSIdo BarneaSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27a551c94aSIdo BarneaINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28a551c94aSIdo BarneaCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29a551c94aSIdo BarneaARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30a551c94aSIdo BarneaPOSSIBILITY OF SUCH DAMAGE.
31a551c94aSIdo Barnea
32a551c94aSIdo Barnea***************************************************************************/
33a551c94aSIdo Barnea
34a551c94aSIdo Barnea#include "i40e_diag.h"
35a551c94aSIdo Barnea#include "i40e_prototype.h"
36a551c94aSIdo Barnea
37a551c94aSIdo Barnea/**
38a551c94aSIdo Barnea * i40e_diag_set_loopback
39a551c94aSIdo Barnea * @hw: pointer to the hw struct
40a551c94aSIdo Barnea * @mode: loopback mode
41a551c94aSIdo Barnea *
42a551c94aSIdo Barnea * Set chosen loopback mode
43a551c94aSIdo Barnea **/
44a551c94aSIdo Barneaenum i40e_status_code i40e_diag_set_loopback(struct i40e_hw *hw,
45a551c94aSIdo Barnea					     enum i40e_lb_mode mode)
46a551c94aSIdo Barnea{
47a551c94aSIdo Barnea	enum i40e_status_code ret_code = I40E_SUCCESS;
48a551c94aSIdo Barnea
49a551c94aSIdo Barnea	if (i40e_aq_set_lb_modes(hw, mode, NULL))
50a551c94aSIdo Barnea		ret_code = I40E_ERR_DIAG_TEST_FAILED;
51a551c94aSIdo Barnea
52a551c94aSIdo Barnea	return ret_code;
53a551c94aSIdo Barnea}
54a551c94aSIdo Barnea
55a551c94aSIdo Barnea/**
56a551c94aSIdo Barnea * i40e_diag_reg_pattern_test
57a551c94aSIdo Barnea * @hw: pointer to the hw struct
58a551c94aSIdo Barnea * @reg: reg to be tested
59a551c94aSIdo Barnea * @mask: bits to be touched
60a551c94aSIdo Barnea **/
61a551c94aSIdo Barneastatic enum i40e_status_code i40e_diag_reg_pattern_test(struct i40e_hw *hw,
62a551c94aSIdo Barnea							u32 reg, u32 mask)
63a551c94aSIdo Barnea{
64a551c94aSIdo Barnea	const u32 patterns[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
65a551c94aSIdo Barnea	u32 pat, val, orig_val;
66a551c94aSIdo Barnea	int i;
67a551c94aSIdo Barnea
68a551c94aSIdo Barnea	orig_val = rd32(hw, reg);
69a551c94aSIdo Barnea	for (i = 0; i < ARRAY_SIZE(patterns); i++) {
70a551c94aSIdo Barnea		pat = patterns[i];
71a551c94aSIdo Barnea		wr32(hw, reg, (pat & mask));
72a551c94aSIdo Barnea		val = rd32(hw, reg);
73a551c94aSIdo Barnea		if ((val & mask) != (pat & mask)) {
74a551c94aSIdo Barnea			return I40E_ERR_DIAG_TEST_FAILED;
75a551c94aSIdo Barnea		}
76a551c94aSIdo Barnea	}
77a551c94aSIdo Barnea
78a551c94aSIdo Barnea	wr32(hw, reg, orig_val);
79a551c94aSIdo Barnea	val = rd32(hw, reg);
80a551c94aSIdo Barnea	if (val != orig_val) {
81a551c94aSIdo Barnea		return I40E_ERR_DIAG_TEST_FAILED;
82a551c94aSIdo Barnea	}
83a551c94aSIdo Barnea
84a551c94aSIdo Barnea	return I40E_SUCCESS;
85a551c94aSIdo Barnea}
86a551c94aSIdo Barnea
87a551c94aSIdo Barneastruct i40e_diag_reg_test_info i40e_reg_list[] = {
88a551c94aSIdo Barnea	/* offset               mask         elements   stride */
89a551c94aSIdo Barnea	{I40E_QTX_CTL(0),       0x0000FFBF, 1, I40E_QTX_CTL(1) - I40E_QTX_CTL(0)},
90a551c94aSIdo Barnea	{I40E_PFINT_ITR0(0),    0x00000FFF, 3, I40E_PFINT_ITR0(1) - I40E_PFINT_ITR0(0)},
91a551c94aSIdo Barnea	{I40E_PFINT_ITRN(0, 0), 0x00000FFF, 1, I40E_PFINT_ITRN(0, 1) - I40E_PFINT_ITRN(0, 0)},
92a551c94aSIdo Barnea	{I40E_PFINT_ITRN(1, 0), 0x00000FFF, 1, I40E_PFINT_ITRN(1, 1) - I40E_PFINT_ITRN(1, 0)},
93a551c94aSIdo Barnea	{I40E_PFINT_ITRN(2, 0), 0x00000FFF, 1, I40E_PFINT_ITRN(2, 1) - I40E_PFINT_ITRN(2, 0)},
94a551c94aSIdo Barnea	{I40E_PFINT_STAT_CTL0,  0x0000000C, 1, 0},
95a551c94aSIdo Barnea	{I40E_PFINT_LNKLST0,    0x00001FFF, 1, 0},
96a551c94aSIdo Barnea	{I40E_PFINT_LNKLSTN(0), 0x000007FF, 1, I40E_PFINT_LNKLSTN(1) - I40E_PFINT_LNKLSTN(0)},
97a551c94aSIdo Barnea	{I40E_QINT_TQCTL(0),    0x000000FF, 1, I40E_QINT_TQCTL(1) - I40E_QINT_TQCTL(0)},
98a551c94aSIdo Barnea	{I40E_QINT_RQCTL(0),    0x000000FF, 1, I40E_QINT_RQCTL(1) - I40E_QINT_RQCTL(0)},
99a551c94aSIdo Barnea	{I40E_PFINT_ICR0_ENA,   0xF7F20000, 1, 0},
100a551c94aSIdo Barnea	{ 0 }
101a551c94aSIdo Barnea};
102a551c94aSIdo Barnea
103a551c94aSIdo Barnea/**
104a551c94aSIdo Barnea * i40e_diag_reg_test
105a551c94aSIdo Barnea * @hw: pointer to the hw struct
106a551c94aSIdo Barnea *
107a551c94aSIdo Barnea * Perform registers diagnostic test
108a551c94aSIdo Barnea **/
109a551c94aSIdo Barneaenum i40e_status_code i40e_diag_reg_test(struct i40e_hw *hw)
110a551c94aSIdo Barnea{
111a551c94aSIdo Barnea	enum i40e_status_code ret_code = I40E_SUCCESS;
112a551c94aSIdo Barnea	u32 reg, mask;
113a551c94aSIdo Barnea	u32 i, j;
114a551c94aSIdo Barnea
115a551c94aSIdo Barnea	for (i = 0; i40e_reg_list[i].offset != 0 &&
116a551c94aSIdo Barnea					     ret_code == I40E_SUCCESS; i++) {
117a551c94aSIdo Barnea
118a551c94aSIdo Barnea		/* set actual reg range for dynamically allocated resources */
119a551c94aSIdo Barnea		if (i40e_reg_list[i].offset == I40E_QTX_CTL(0) &&
120a551c94aSIdo Barnea		    hw->func_caps.num_tx_qp != 0)
121a551c94aSIdo Barnea			i40e_reg_list[i].elements = hw->func_caps.num_tx_qp;
122a551c94aSIdo Barnea		if ((i40e_reg_list[i].offset == I40E_PFINT_ITRN(0, 0) ||
123a551c94aSIdo Barnea		     i40e_reg_list[i].offset == I40E_PFINT_ITRN(1, 0) ||
124a551c94aSIdo Barnea		     i40e_reg_list[i].offset == I40E_PFINT_ITRN(2, 0) ||
125a551c94aSIdo Barnea		     i40e_reg_list[i].offset == I40E_QINT_TQCTL(0) ||
126a551c94aSIdo Barnea		     i40e_reg_list[i].offset == I40E_QINT_RQCTL(0)) &&
127a551c94aSIdo Barnea		    hw->func_caps.num_msix_vectors != 0)
128a551c94aSIdo Barnea			i40e_reg_list[i].elements =
129a551c94aSIdo Barnea				hw->func_caps.num_msix_vectors - 1;
130a551c94aSIdo Barnea
131a551c94aSIdo Barnea		/* test register access */
132a551c94aSIdo Barnea		mask = i40e_reg_list[i].mask;
133a551c94aSIdo Barnea		for (j = 0; j < i40e_reg_list[i].elements &&
134a551c94aSIdo Barnea			    ret_code == I40E_SUCCESS; j++) {
135a551c94aSIdo Barnea			reg = i40e_reg_list[i].offset
136a551c94aSIdo Barnea				+ (j * i40e_reg_list[i].stride);
137a551c94aSIdo Barnea			ret_code = i40e_diag_reg_pattern_test(hw, reg, mask);
138a551c94aSIdo Barnea		}
139a551c94aSIdo Barnea	}
140a551c94aSIdo Barnea
141a551c94aSIdo Barnea	return ret_code;
142a551c94aSIdo Barnea}
143a551c94aSIdo Barnea
144a551c94aSIdo Barnea/**
145a551c94aSIdo Barnea * i40e_diag_eeprom_test
146a551c94aSIdo Barnea * @hw: pointer to the hw struct
147a551c94aSIdo Barnea *
148a551c94aSIdo Barnea * Perform EEPROM diagnostic test
149a551c94aSIdo Barnea **/
150a551c94aSIdo Barneaenum i40e_status_code i40e_diag_eeprom_test(struct i40e_hw *hw)
151a551c94aSIdo Barnea{
152a551c94aSIdo Barnea	enum i40e_status_code ret_code;
153a551c94aSIdo Barnea	u16 reg_val;
154a551c94aSIdo Barnea
155a551c94aSIdo Barnea	/* read NVM control word and if NVM valid, validate EEPROM checksum*/
156a551c94aSIdo Barnea	ret_code = i40e_read_nvm_word(hw, I40E_SR_NVM_CONTROL_WORD, &reg_val);
157a551c94aSIdo Barnea	if ((ret_code == I40E_SUCCESS) &&
158a551c94aSIdo Barnea	    ((reg_val & I40E_SR_CONTROL_WORD_1_MASK) ==
159a551c94aSIdo Barnea	     BIT(I40E_SR_CONTROL_WORD_1_SHIFT)))
160a551c94aSIdo Barnea		return i40e_validate_nvm_checksum(hw, NULL);
161a551c94aSIdo Barnea	else
162a551c94aSIdo Barnea		return I40E_ERR_DIAG_TEST_FAILED;
163a551c94aSIdo Barnea}
164a551c94aSIdo Barnea
165a551c94aSIdo Barnea/**
166a551c94aSIdo Barnea * i40e_diag_fw_alive_test
167a551c94aSIdo Barnea * @hw: pointer to the hw struct
168a551c94aSIdo Barnea *
169a551c94aSIdo Barnea * Perform FW alive diagnostic test
170a551c94aSIdo Barnea **/
171a551c94aSIdo Barneaenum i40e_status_code i40e_diag_fw_alive_test(struct i40e_hw *hw)
172a551c94aSIdo Barnea{
173a551c94aSIdo Barnea	UNREFERENCED_1PARAMETER(hw);
174a551c94aSIdo Barnea	return I40E_SUCCESS;
175a551c94aSIdo Barnea}
176