1 /*
   2  * Copyright 2007-2013 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 
  26 #include "efsys.h"
  27 #include "efx.h"
  28 #include "efx_types.h"
  29 #include "efx_regs.h"
  30 #include "efx_impl.h"
  31 
  32 #if EFSYS_OPT_FALCON
  33 
  34 static  __checkReturn   int
  35 falcon_sram_reset(
  36         __in            efx_nic_t *enp)
  37 {
  38         efx_oword_t oword;
  39         unsigned int count;
  40         int rc;
  41 
  42         /* Initiate SRAM reset */
  43         EFX_POPULATE_OWORD_3(oword,
  44                             FRF_AZ_SRM_NUM_BANK,
  45                             enp->en_u.falcon.enu_sram_num_bank,
  46                             FRF_AZ_SRM_BANK_SIZE,
  47                             enp->en_u.falcon.enu_sram_bank_size,
  48                             FRF_AZ_SRM_INIT_EN, 1);
  49         EFX_BAR_WRITEO(enp, FR_AZ_SRM_CFG_REG, &oword);
  50 
  51         /* Wait for SRAM reset to complete */
  52         count = 0;
  53         do {
  54                 EFSYS_PROBE1(wait, unsigned int, count);
  55 
  56                 /* Spin for 1 ms */
  57                 EFSYS_SPIN(1000);
  58 
  59                 /* Check for reset complete */
  60                 EFX_BAR_READO(enp, FR_AZ_SRM_CFG_REG, &oword);
  61                 if (EFX_OWORD_FIELD(oword, FRF_AZ_SRM_INIT_EN) == 0)
  62                         goto done;
  63         } while (++count < 100);
  64 
  65         rc = ETIMEDOUT;
  66         goto fail1;
  67 
  68 done:
  69         return (0);
  70 
  71 fail1:
  72         EFSYS_PROBE1(fail1, int, rc);
  73 
  74         return (rc);
  75 }
  76 
  77         __checkReturn   int
  78 falcon_sram_init(
  79         __in            efx_nic_t *enp)
  80 {
  81         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
  82         efx_oword_t oword;
  83         uint32_t tx_base, rx_base;
  84         int rc;
  85 
  86         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  87         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
  88 
  89         /* Position the descriptor caches */
  90         if (enp->en_u.falcon.enu_internal_sram) {
  91                 tx_base = 0x130000;
  92                 rx_base = 0x100000;
  93         } else {
  94                 rx_base = encp->enc_buftbl_limit * 8;
  95                 tx_base = rx_base + (encp->enc_rxq_limit * 64 * 8);
  96         }
  97 
  98         /* Select internal SRAM */
  99         EFX_BAR_READO(enp, FR_AB_NIC_STAT_REG, &oword);
 100         EFX_SET_OWORD_FIELD(oword, FRF_AB_ONCHIP_SRAM,
 101             enp->en_u.falcon.enu_internal_sram ? 1 : 0);
 102         EFX_BAR_WRITEO(enp, FR_AB_NIC_STAT_REG, &oword);
 103 
 104         /* Sleep/Wake any external SRAM */
 105         EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
 106         EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO1_OEN, 1);
 107         EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO1_OUT,
 108             enp->en_u.falcon.enu_internal_sram ? 1 : 0);
 109         EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
 110 
 111         /* Clear the SRAM contents */
 112         if ((rc = falcon_sram_reset(enp)) != 0)
 113                 goto fail1;
 114 
 115         /* Initialize the buffer table */
 116         EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1);
 117         EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword);
 118 
 119         /* Initialize the transmit descriptor cache */
 120         EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base);
 121         EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword);
 122 
 123         EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, 1); /* 16 descriptors */
 124         EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword);
 125 
 126         /* Initialize the receive descriptor cache */
 127         EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base);
 128         EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword);
 129 
 130         EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, 3); /* 64 descriptors */
 131         EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword);
 132 
 133         /* Set receive descriptor pre-fetch low water mark */
 134         EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56);
 135         EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword);
 136 
 137         /* Set the event queue to use for SRAM updates */
 138         EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0);
 139         EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword);
 140 
 141         return (0);
 142 
 143 fail1:
 144         EFSYS_PROBE1(fail1, int, rc);
 145 
 146         return (rc);
 147 }
 148 
 149 #if EFSYS_OPT_DIAG
 150 
 151         __checkReturn   int
 152 falcon_sram_test(
 153         __in            efx_nic_t *enp,
 154         __in            efx_sram_pattern_fn_t func)
 155 {
 156         efx_qword_t qword;
 157         efx_qword_t verify;
 158         size_t rows = 0x1000;
 159         unsigned int rptr;
 160         unsigned int wptr;
 161         int rc;
 162 
 163         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 164 
 165         /*
 166          * Write the pattern through the SRAM debug aperture. Write
 167          * in 64 entry batches, waiting 1us in between each batch
 168          * to guarantee not to overflow the SRAM fifo
 169          */
 170         for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
 171                 func(wptr, B_FALSE, &qword);
 172                 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_SRM_DBG_REG, wptr, &qword);
 173 
 174                 if ((wptr - rptr) < 64 && wptr < rows - 1)
 175                         continue;
 176 
 177                 EFSYS_SPIN(1);
 178 
 179                 for (; rptr <= wptr; ++rptr) {
 180                         func(rptr, B_FALSE, &qword);
 181                         EFX_BAR_TBL_READQ(enp, FR_AZ_SRM_DBG_REG, rptr,
 182                             &verify);
 183 
 184                         if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
 185                                 rc = EFAULT;
 186                                 goto fail1;
 187                         }
 188                 }
 189         }
 190 
 191         /* And do the same negated */
 192         for (wptr = 0, rptr = 0; wptr < rows; ++wptr) {
 193                 func(wptr, B_TRUE, &qword);
 194                 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_SRM_DBG_REG, wptr, &qword);
 195 
 196                 if ((wptr - rptr) < 64 && wptr < rows - 1)
 197                         continue;
 198 
 199                 EFSYS_SPIN(1);
 200 
 201                 for (; rptr <= wptr; ++rptr) {
 202                         func(rptr, B_TRUE, &qword);
 203                         EFX_BAR_TBL_READQ(enp, FR_AZ_SRM_DBG_REG, rptr,
 204                             &verify);
 205 
 206                         if (!EFX_QWORD_IS_EQUAL(verify, qword)) {
 207                                 rc = EFAULT;
 208                                 goto fail2;
 209                         }
 210                 }
 211         }
 212 
 213         return (0);
 214 
 215 fail2:
 216         EFSYS_PROBE(fail2);
 217 fail1:
 218         EFSYS_PROBE1(fail1, int, rc);
 219 
 220         return (rc);
 221 }
 222 
 223 #endif  /* EFSYS_OPT_DIAG */
 224 
 225                 void
 226 falcon_sram_fini(
 227         __in    efx_nic_t *enp)
 228 {
 229         efx_oword_t oword;
 230 
 231         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 232         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
 233 
 234         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
 235         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
 236         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
 237 
 238         /* Allow the GPIO1 pin to float */
 239         EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
 240         EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO1_OEN, 0);
 241         EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
 242 }
 243 
 244 #endif  /* EFS_OPT_FALCON */