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