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