aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/base/siena_sram.c
blob: c9ef786c2d14f33df105a9f286e3c6970ebb3795 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* SPDX-License-Identifier: BSD-3-Clause
 *
 * Copyright (c) 2009-2018 Solarflare Communications Inc.
 * All rights reserved.
 */

#include "efx.h"
#include "efx_impl.h"

#if EFSYS_OPT_SIENA

			void
siena_sram_init(
	__in		efx_nic_t *enp)
{
	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
	efx_oword_t oword;
	uint32_t rx_base, tx_base;

	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);

	rx_base = encp->enc_buftbl_limit;
	tx_base = rx_base + (encp->enc_rxq_limit *
	    EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));

	/* Initialize the transmit descriptor cache */
	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base);
	EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);

	EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, EFX_TXQ_DC_SIZE);
	EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword);

	/* Initialize the receive descriptor cache */
	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base);
	EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);

	EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, EFX_RXQ_DC_SIZE);
	EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword);

	/* Set receive descriptor pre-fetch low water mark */
	EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56);
	EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword);

	/* Set the event queue to use for SRAM updates */
	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0);
	EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword);
}

#if EFSYS_OPT_DIAG

	__checkReturn	efx_rc_t
siena_sram_test(
	__in		efx_nic_t *enp,
	__in		efx_sram_pattern_fn_t func)
{
	efx_oword_t oword;
	efx_qword_t qword;
	efx_qword_t verify;
	size_t rows;
	unsigned int wptr;
	unsigned int rptr;
	efx_rc_t rc;

	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);

	/* Reconfigure into HALF buffer table mode */
	EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 0);
	EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);

	/*
	 * Move the descriptor caches up to the top of SRAM, and test
	 * all of SRAM below them. We only miss out one row here.
	 */
	rows = SIENA_SRAM_ROWS - 1;
	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rows);
	EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);

	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, rows + 1);
	EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);

	/*
	 * Write the pattern through BUF_HALF_TBL. Write
	 * in 64 entry batches, waiting 1us in between each batch
	 * to guarantee not to overflow the SRAM fifo
	 */
	for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
		func(wptr, B_FALSE, &qword);
		EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);

		if ((wptr - rptr) < 64 && wptr < rows - 1)
			continue;

		EFSYS_SPIN(1);

		for (; rptr <= wptr; ++rptr) {
			func(rptr, B_FALSE, &qword);
			EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
			    &verify);

			if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
				rc = EFAULT;
				goto fail1;
			}
		}
	}

	/* And do the same negated */
	for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
		func(wptr, B_TRUE, &qword);
		EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);

		if ((wptr - rptr) < 64 && wptr < rows - 1)
			continue;

		EFSYS_SPIN(1);

		for (; rptr <= wptr; ++rptr) {
			func(rptr, B_TRUE, &qword);
			EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
			    &verify);

			if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
				rc = EFAULT;
				goto fail2;
			}
		}
	}

	/* Restore back to FULL buffer table mode */
	EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
	EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);

	/*
	 * We don't need to reconfigure SRAM again because the API
	 * requires efx_nic_fini() to be called after an sram test.
	 */
	return (0);

fail2:
	EFSYS_PROBE(fail2);
fail1:
	EFSYS_PROBE1(fail1, efx_rc_t, rc);

	/* Restore back to FULL buffer table mode */
	EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
	EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);

	return (rc);
}

#endif	/* EFSYS_OPT_DIAG */

#endif	/* EFSYS_OPT_SIENA */