The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sfxge/common/efx_sram.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2007-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         __checkReturn   efx_rc_t
   40 efx_sram_buf_tbl_set(
   41         __in            efx_nic_t *enp,
   42         __in            uint32_t id,
   43         __in            efsys_mem_t *esmp,
   44         __in            size_t n)
   45 {
   46         efx_qword_t qword;
   47         uint32_t start = id;
   48         uint32_t stop = start + n;
   49         efsys_dma_addr_t addr;
   50         efx_oword_t oword;
   51         unsigned int count;
   52         efx_rc_t rc;
   53 
   54         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
   55         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
   56 
   57 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
   58         if (enp->en_family == EFX_FAMILY_HUNTINGTON ||
   59             enp->en_family == EFX_FAMILY_MEDFORD ||
   60             enp->en_family == EFX_FAMILY_MEDFORD2) {
   61                 /*
   62                  * FIXME: the efx_sram_buf_tbl_*() functionality needs to be
   63                  * pulled inside the Falcon/Siena queue create/destroy code,
   64                  * and then the original functions can be removed (see bug30834
   65                  * comment #1).  But, for now, we just ensure that they are
   66                  * no-ops for EF10, to allow bringing up existing drivers
   67                  * without modification.
   68                  */
   69 
   70                 return (0);
   71         }
   72 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
   73 
   74         if (stop >= EFX_BUF_TBL_SIZE) {
   75                 rc = EFBIG;
   76                 goto fail1;
   77         }
   78 
   79         /* Add the entries into the buffer table */
   80         addr = EFSYS_MEM_ADDR(esmp);
   81         for (id = start; id != stop; id++) {
   82                 EFX_POPULATE_QWORD_5(qword,
   83                     FRF_AZ_IP_DAT_BUF_SIZE, 0, FRF_AZ_BUF_ADR_REGION, 0,
   84                     FRF_AZ_BUF_ADR_FBUF_DW0,
   85                     (uint32_t)((addr >> 12) & 0xffffffff),
   86                     FRF_AZ_BUF_ADR_FBUF_DW1,
   87                     (uint32_t)((addr >> 12) >> 32),
   88                     FRF_AZ_BUF_OWNER_ID_FBUF, 0);
   89 
   90                 EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_FULL_TBL,
   91                                     id, &qword);
   92 
   93                 addr += EFX_BUF_SIZE;
   94         }
   95 
   96         EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1);
   97 
   98         /* Flush the write buffer */
   99         EFX_POPULATE_OWORD_2(oword, FRF_AZ_BUF_UPD_CMD, 1,
  100             FRF_AZ_BUF_CLR_CMD, 0);
  101         EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword);
  102 
  103         /* Poll for the last entry being written to the buffer table */
  104         EFSYS_ASSERT3U(id, ==, stop);
  105         addr -= EFX_BUF_SIZE;
  106 
  107         count = 0;
  108         do {
  109                 EFSYS_PROBE1(wait, unsigned int, count);
  110 
  111                 /* Spin for 1 ms */
  112                 EFSYS_SPIN(1000);
  113 
  114                 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL,
  115                                     id - 1, &qword);
  116 
  117                 if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) ==
  118                     (uint32_t)((addr >> 12) & 0xffffffff) &&
  119                     EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) ==
  120                     (uint32_t)((addr >> 12) >> 32))
  121                         goto verify;
  122 
  123         } while (++count < 100);
  124 
  125         rc = ETIMEDOUT;
  126         goto fail2;
  127 
  128 verify:
  129         /* Verify the rest of the entries in the buffer table */
  130         while (--id != start) {
  131                 addr -= EFX_BUF_SIZE;
  132 
  133                 /* Read the buffer table entry */
  134                 EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL,
  135                                     id - 1, &qword);
  136 
  137                 if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) !=
  138                     (uint32_t)((addr >> 12) & 0xffffffff) ||
  139                     EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) !=
  140                     (uint32_t)((addr >> 12) >> 32)) {
  141                         rc = EFAULT;
  142                         goto fail3;
  143                 }
  144         }
  145 
  146         return (0);
  147 
  148 fail3:
  149         EFSYS_PROBE(fail3);
  150 
  151         id = stop;
  152 
  153 fail2:
  154         EFSYS_PROBE(fail2);
  155 
  156         EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0,
  157             FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, id - 1,
  158             FRF_AZ_BUF_CLR_START_ID, start);
  159         EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword);
  160 
  161 fail1:
  162         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  163 
  164         return (rc);
  165 }
  166 
  167                 void
  168 efx_sram_buf_tbl_clear(
  169         __in    efx_nic_t *enp,
  170         __in    uint32_t id,
  171         __in    size_t n)
  172 {
  173         efx_oword_t oword;
  174         uint32_t start = id;
  175         uint32_t stop = start + n;
  176 
  177         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  178         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
  179 
  180 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
  181         if (enp->en_family == EFX_FAMILY_HUNTINGTON ||
  182             enp->en_family == EFX_FAMILY_MEDFORD ||
  183             enp->en_family == EFX_FAMILY_MEDFORD2) {
  184                 /*
  185                  * FIXME: the efx_sram_buf_tbl_*() functionality needs to be
  186                  * pulled inside the Falcon/Siena queue create/destroy code,
  187                  * and then the original functions can be removed (see bug30834
  188                  * comment #1).  But, for now, we just ensure that they are
  189                  * no-ops for EF10, to allow bringing up existing drivers
  190                  * without modification.
  191                  */
  192 
  193                 return;
  194         }
  195 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
  196 
  197         EFSYS_ASSERT3U(stop, <, EFX_BUF_TBL_SIZE);
  198 
  199         EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1);
  200 
  201         EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0,
  202             FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, stop - 1,
  203             FRF_AZ_BUF_CLR_START_ID, start);
  204         EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword);
  205 }
  206 
  207 #if EFSYS_OPT_DIAG
  208 
  209 static                  void
  210 efx_sram_byte_increment_set(
  211         __in            size_t row,
  212         __in            boolean_t negate,
  213         __out           efx_qword_t *eqp)
  214 {
  215         size_t offset = row * FR_AZ_SRM_DBG_REG_STEP;
  216         unsigned int index;
  217 
  218         _NOTE(ARGUNUSED(negate))
  219 
  220         for (index = 0; index < sizeof (efx_qword_t); index++)
  221                 eqp->eq_u8[index] = offset + index;
  222 }
  223 
  224 static                  void
  225 efx_sram_all_the_same_set(
  226         __in            size_t row,
  227         __in            boolean_t negate,
  228         __out           efx_qword_t *eqp)
  229 {
  230         _NOTE(ARGUNUSED(row))
  231 
  232         if (negate)
  233                 EFX_SET_QWORD(*eqp);
  234         else
  235                 EFX_ZERO_QWORD(*eqp);
  236 }
  237 
  238 static                  void
  239 efx_sram_bit_alternate_set(
  240         __in            size_t row,
  241         __in            boolean_t negate,
  242         __out           efx_qword_t *eqp)
  243 {
  244         _NOTE(ARGUNUSED(row))
  245 
  246         EFX_POPULATE_QWORD_2(*eqp,
  247             EFX_DWORD_0, (negate) ? 0x55555555 : 0xaaaaaaaa,
  248             EFX_DWORD_1, (negate) ? 0x55555555 : 0xaaaaaaaa);
  249 }
  250 
  251 static                  void
  252 efx_sram_byte_alternate_set(
  253         __in            size_t row,
  254         __in            boolean_t negate,
  255         __out           efx_qword_t *eqp)
  256 {
  257         _NOTE(ARGUNUSED(row))
  258 
  259         EFX_POPULATE_QWORD_2(*eqp,
  260             EFX_DWORD_0, (negate) ? 0x00ff00ff : 0xff00ff00,
  261             EFX_DWORD_1, (negate) ? 0x00ff00ff : 0xff00ff00);
  262 }
  263 
  264 static                  void
  265 efx_sram_byte_changing_set(
  266         __in            size_t row,
  267         __in            boolean_t negate,
  268         __out           efx_qword_t *eqp)
  269 {
  270         size_t offset = row * FR_AZ_SRM_DBG_REG_STEP;
  271         unsigned int index;
  272 
  273         for (index = 0; index < sizeof (efx_qword_t); index++) {
  274                 uint8_t byte;
  275 
  276                 if (offset / 256 == 0)
  277                         byte = (uint8_t)((offset % 257) % 256);
  278                 else
  279                         byte = (uint8_t)(~((offset - 8) % 257) % 256);
  280 
  281                 eqp->eq_u8[index] = (negate) ? ~byte : byte;
  282         }
  283 }
  284 
  285 static                  void
  286 efx_sram_bit_sweep_set(
  287         __in            size_t row,
  288         __in            boolean_t negate,
  289         __out           efx_qword_t *eqp)
  290 {
  291         size_t offset = row * FR_AZ_SRM_DBG_REG_STEP;
  292 
  293         if (negate) {
  294                 EFX_SET_QWORD(*eqp);
  295                 EFX_CLEAR_QWORD_BIT(*eqp, (offset / sizeof (efx_qword_t)) % 64);
  296         } else {
  297                 EFX_ZERO_QWORD(*eqp);
  298                 EFX_SET_QWORD_BIT(*eqp, (offset / sizeof (efx_qword_t)) % 64);
  299         }
  300 }
  301 
  302 efx_sram_pattern_fn_t   __efx_sram_pattern_fns[] = {
  303         efx_sram_byte_increment_set,
  304         efx_sram_all_the_same_set,
  305         efx_sram_bit_alternate_set,
  306         efx_sram_byte_alternate_set,
  307         efx_sram_byte_changing_set,
  308         efx_sram_bit_sweep_set
  309 };
  310 
  311         __checkReturn   efx_rc_t
  312 efx_sram_test(
  313         __in            efx_nic_t *enp,
  314         __in            efx_pattern_type_t type)
  315 {
  316         efx_sram_pattern_fn_t func;
  317 
  318         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  319 
  320         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
  321 
  322         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
  323         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
  324         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
  325 
  326         /* SRAM testing is only available on Siena. */
  327         if (enp->en_family != EFX_FAMILY_SIENA)
  328                 return (0);
  329 
  330         /* Select pattern generator */
  331         EFSYS_ASSERT3U(type, <, EFX_PATTERN_NTYPES);
  332         func = __efx_sram_pattern_fns[type];
  333 
  334         return (siena_sram_test(enp, func));
  335 }
  336 
  337 #endif  /* EFSYS_OPT_DIAG */

Cache object: d3cf8742490211d4cadafc6d74f6c6ec


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.