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