xref: /freebsd/sys/dev/sfxge/common/siena_sram.c (revision 924226fba12cc9a228c73b956e1b7fa24c60b055)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2009-2016 Solarflare Communications Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * The views and conclusions contained in the software and documentation are
29  * those of the authors and should not be interpreted as representing official
30  * policies, either expressed or implied, of the FreeBSD Project.
31  */
32 
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 
36 #include "efx.h"
37 #include "efx_impl.h"
38 
39 #if EFSYS_OPT_SIENA
40 
41 			void
42 siena_sram_init(
43 	__in		efx_nic_t *enp)
44 {
45 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
46 	efx_oword_t oword;
47 	uint32_t rx_base, tx_base;
48 
49 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
50 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
51 
52 	rx_base = encp->enc_buftbl_limit;
53 	tx_base = rx_base + (encp->enc_rxq_limit *
54 	    EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
55 
56 	/* Initialize the transmit descriptor cache */
57 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base);
58 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
59 
60 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, EFX_TXQ_DC_SIZE);
61 	EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword);
62 
63 	/* Initialize the receive descriptor cache */
64 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base);
65 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
66 
67 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, EFX_RXQ_DC_SIZE);
68 	EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword);
69 
70 	/* Set receive descriptor pre-fetch low water mark */
71 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56);
72 	EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword);
73 
74 	/* Set the event queue to use for SRAM updates */
75 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0);
76 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword);
77 }
78 
79 #if EFSYS_OPT_DIAG
80 
81 	__checkReturn	efx_rc_t
82 siena_sram_test(
83 	__in		efx_nic_t *enp,
84 	__in		efx_sram_pattern_fn_t func)
85 {
86 	efx_oword_t oword;
87 	efx_qword_t qword;
88 	efx_qword_t verify;
89 	size_t rows;
90 	unsigned int wptr;
91 	unsigned int rptr;
92 	efx_rc_t rc;
93 
94 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
95 
96 	/* Reconfigure into HALF buffer table mode */
97 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 0);
98 	EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
99 
100 	/*
101 	 * Move the descriptor caches up to the top of SRAM, and test
102 	 * all of SRAM below them. We only miss out one row here.
103 	 */
104 	rows = SIENA_SRAM_ROWS - 1;
105 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rows);
106 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
107 
108 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, rows + 1);
109 	EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
110 
111 	/*
112 	 * Write the pattern through BUF_HALF_TBL. Write
113 	 * in 64 entry batches, waiting 1us in between each batch
114 	 * to guarantee not to overflow the SRAM fifo
115 	 */
116 	for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
117 		func(wptr, B_FALSE, &qword);
118 		EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);
119 
120 		if ((wptr - rptr) < 64 && wptr < rows - 1)
121 			continue;
122 
123 		EFSYS_SPIN(1);
124 
125 		for (; rptr <= wptr; ++rptr) {
126 			func(rptr, B_FALSE, &qword);
127 			EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
128 			    &verify);
129 
130 			if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
131 				rc = EFAULT;
132 				goto fail1;
133 			}
134 		}
135 	}
136 
137 	/* And do the same negated */
138 	for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
139 		func(wptr, B_TRUE, &qword);
140 		EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword);
141 
142 		if ((wptr - rptr) < 64 && wptr < rows - 1)
143 			continue;
144 
145 		EFSYS_SPIN(1);
146 
147 		for (; rptr <= wptr; ++rptr) {
148 			func(rptr, B_TRUE, &qword);
149 			EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr,
150 			    &verify);
151 
152 			if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
153 				rc = EFAULT;
154 				goto fail2;
155 			}
156 		}
157 	}
158 
159 	/* Restore back to FULL buffer table mode */
160 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
161 	EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
162 
163 	/*
164 	 * We don't need to reconfigure SRAM again because the API
165 	 * requires efx_nic_fini() to be called after an sram test.
166 	 */
167 	return (0);
168 
169 fail2:
170 	EFSYS_PROBE(fail2);
171 fail1:
172 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
173 
174 	/* Restore back to FULL buffer table mode */
175 	EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
176 	EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
177 
178 	return (rc);
179 }
180 
181 #endif	/* EFSYS_OPT_DIAG */
182 
183 #endif	/* EFSYS_OPT_SIENA */
184