cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

i40e_diag.c (3801B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright(c) 2013 - 2018 Intel Corporation. */
      3
      4#include "i40e_diag.h"
      5#include "i40e_prototype.h"
      6
      7/**
      8 * i40e_diag_reg_pattern_test
      9 * @hw: pointer to the hw struct
     10 * @reg: reg to be tested
     11 * @mask: bits to be touched
     12 **/
     13static i40e_status i40e_diag_reg_pattern_test(struct i40e_hw *hw,
     14							u32 reg, u32 mask)
     15{
     16	static const u32 patterns[] = {
     17		0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
     18	};
     19	u32 pat, val, orig_val;
     20	int i;
     21
     22	orig_val = rd32(hw, reg);
     23	for (i = 0; i < ARRAY_SIZE(patterns); i++) {
     24		pat = patterns[i];
     25		wr32(hw, reg, (pat & mask));
     26		val = rd32(hw, reg);
     27		if ((val & mask) != (pat & mask)) {
     28			i40e_debug(hw, I40E_DEBUG_DIAG,
     29				   "%s: reg pattern test failed - reg 0x%08x pat 0x%08x val 0x%08x\n",
     30				   __func__, reg, pat, val);
     31			return I40E_ERR_DIAG_TEST_FAILED;
     32		}
     33	}
     34
     35	wr32(hw, reg, orig_val);
     36	val = rd32(hw, reg);
     37	if (val != orig_val) {
     38		i40e_debug(hw, I40E_DEBUG_DIAG,
     39			   "%s: reg restore test failed - reg 0x%08x orig_val 0x%08x val 0x%08x\n",
     40			   __func__, reg, orig_val, val);
     41		return I40E_ERR_DIAG_TEST_FAILED;
     42	}
     43
     44	return 0;
     45}
     46
     47struct i40e_diag_reg_test_info i40e_reg_list[] = {
     48	/* offset               mask         elements   stride */
     49	{I40E_QTX_CTL(0),       0x0000FFBF, 1,
     50		I40E_QTX_CTL(1) - I40E_QTX_CTL(0)},
     51	{I40E_PFINT_ITR0(0),    0x00000FFF, 3,
     52		I40E_PFINT_ITR0(1) - I40E_PFINT_ITR0(0)},
     53	{I40E_PFINT_ITRN(0, 0), 0x00000FFF, 1,
     54		I40E_PFINT_ITRN(0, 1) - I40E_PFINT_ITRN(0, 0)},
     55	{I40E_PFINT_ITRN(1, 0), 0x00000FFF, 1,
     56		I40E_PFINT_ITRN(1, 1) - I40E_PFINT_ITRN(1, 0)},
     57	{I40E_PFINT_ITRN(2, 0), 0x00000FFF, 1,
     58		I40E_PFINT_ITRN(2, 1) - I40E_PFINT_ITRN(2, 0)},
     59	{I40E_PFINT_STAT_CTL0,  0x0000000C, 1, 0},
     60	{I40E_PFINT_LNKLST0,    0x00001FFF, 1, 0},
     61	{I40E_PFINT_LNKLSTN(0), 0x000007FF, 1,
     62		I40E_PFINT_LNKLSTN(1) - I40E_PFINT_LNKLSTN(0)},
     63	{I40E_QINT_TQCTL(0),    0x000000FF, 1,
     64		I40E_QINT_TQCTL(1) - I40E_QINT_TQCTL(0)},
     65	{I40E_QINT_RQCTL(0),    0x000000FF, 1,
     66		I40E_QINT_RQCTL(1) - I40E_QINT_RQCTL(0)},
     67	{I40E_PFINT_ICR0_ENA,   0xF7F20000, 1, 0},
     68	{ 0 }
     69};
     70
     71/**
     72 * i40e_diag_reg_test
     73 * @hw: pointer to the hw struct
     74 *
     75 * Perform registers diagnostic test
     76 **/
     77i40e_status i40e_diag_reg_test(struct i40e_hw *hw)
     78{
     79	i40e_status ret_code = 0;
     80	u32 reg, mask;
     81	u32 i, j;
     82
     83	for (i = 0; i40e_reg_list[i].offset != 0 &&
     84					     !ret_code; i++) {
     85
     86		/* set actual reg range for dynamically allocated resources */
     87		if (i40e_reg_list[i].offset == I40E_QTX_CTL(0) &&
     88		    hw->func_caps.num_tx_qp != 0)
     89			i40e_reg_list[i].elements = hw->func_caps.num_tx_qp;
     90		if ((i40e_reg_list[i].offset == I40E_PFINT_ITRN(0, 0) ||
     91		     i40e_reg_list[i].offset == I40E_PFINT_ITRN(1, 0) ||
     92		     i40e_reg_list[i].offset == I40E_PFINT_ITRN(2, 0) ||
     93		     i40e_reg_list[i].offset == I40E_QINT_TQCTL(0) ||
     94		     i40e_reg_list[i].offset == I40E_QINT_RQCTL(0)) &&
     95		    hw->func_caps.num_msix_vectors != 0)
     96			i40e_reg_list[i].elements =
     97				hw->func_caps.num_msix_vectors - 1;
     98
     99		/* test register access */
    100		mask = i40e_reg_list[i].mask;
    101		for (j = 0; j < i40e_reg_list[i].elements && !ret_code; j++) {
    102			reg = i40e_reg_list[i].offset +
    103			      (j * i40e_reg_list[i].stride);
    104			ret_code = i40e_diag_reg_pattern_test(hw, reg, mask);
    105		}
    106	}
    107
    108	return ret_code;
    109}
    110
    111/**
    112 * i40e_diag_eeprom_test
    113 * @hw: pointer to the hw struct
    114 *
    115 * Perform EEPROM diagnostic test
    116 **/
    117i40e_status i40e_diag_eeprom_test(struct i40e_hw *hw)
    118{
    119	i40e_status ret_code;
    120	u16 reg_val;
    121
    122	/* read NVM control word and if NVM valid, validate EEPROM checksum*/
    123	ret_code = i40e_read_nvm_word(hw, I40E_SR_NVM_CONTROL_WORD, &reg_val);
    124	if (!ret_code &&
    125	    ((reg_val & I40E_SR_CONTROL_WORD_1_MASK) ==
    126	     BIT(I40E_SR_CONTROL_WORD_1_SHIFT)))
    127		return i40e_validate_nvm_checksum(hw, NULL);
    128	else
    129		return I40E_ERR_DIAG_TEST_FAILED;
    130}