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