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/siena_nic.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) 2009-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 #include "mcdi_mon.h"
   39 
   40 #if EFSYS_OPT_SIENA
   41 
   42 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
   43 
   44 static  __checkReturn           efx_rc_t
   45 siena_nic_get_partn_mask(
   46         __in                    efx_nic_t *enp,
   47         __out                   unsigned int *maskp)
   48 {
   49         efx_mcdi_req_t req;
   50         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN,
   51                 MC_CMD_NVRAM_TYPES_OUT_LEN);
   52         efx_rc_t rc;
   53 
   54         req.emr_cmd = MC_CMD_NVRAM_TYPES;
   55         req.emr_in_buf = payload;
   56         req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
   57         req.emr_out_buf = payload;
   58         req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
   59 
   60         efx_mcdi_execute(enp, &req);
   61 
   62         if (req.emr_rc != 0) {
   63                 rc = req.emr_rc;
   64                 goto fail1;
   65         }
   66 
   67         if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
   68                 rc = EMSGSIZE;
   69                 goto fail2;
   70         }
   71 
   72         *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
   73 
   74         return (0);
   75 
   76 fail2:
   77         EFSYS_PROBE(fail2);
   78 fail1:
   79         EFSYS_PROBE1(fail1, efx_rc_t, rc);
   80 
   81         return (rc);
   82 }
   83 
   84 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
   85 
   86 static  __checkReturn   efx_rc_t
   87 siena_board_cfg(
   88         __in            efx_nic_t *enp)
   89 {
   90         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
   91         uint8_t mac_addr[6];
   92         efx_dword_t capabilities;
   93         uint32_t board_type;
   94         uint32_t nevq, nrxq, ntxq;
   95         efx_rc_t rc;
   96 
   97         /* Siena has a fixed 8Kbyte VI window size */
   98         EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K  == 8192);
   99         encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K;
  100 
  101         /* External port identifier using one-based port numbering */
  102         encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
  103 
  104         /* Board configuration */
  105         if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
  106                     &capabilities, mac_addr)) != 0)
  107                 goto fail1;
  108 
  109         EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
  110 
  111         encp->enc_board_type = board_type;
  112 
  113         /*
  114          * There is no possibility to determine the number of PFs on Siena
  115          * by issuing MCDI request, and it is not an easy task to find the
  116          * value based on the board type, so 'enc_hw_pf_count' is set to 1
  117          */
  118         encp->enc_hw_pf_count = 1;
  119 
  120         /* Additional capabilities */
  121         encp->enc_clk_mult = 1;
  122         if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
  123                 enp->en_features |= EFX_FEATURE_TURBO;
  124 
  125                 if (EFX_DWORD_FIELD(capabilities,
  126                         MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
  127                         encp->enc_clk_mult = 2;
  128                 }
  129         }
  130 
  131         encp->enc_evq_timer_quantum_ns =
  132                 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
  133         encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
  134                 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
  135 
  136         /* When hash header insertion is enabled, Siena inserts 16 bytes */
  137         encp->enc_rx_prefix_size = 16;
  138 
  139         /* Alignment for receive packet DMA buffers */
  140         encp->enc_rx_buf_align_start = 1;
  141         encp->enc_rx_buf_align_end = 1;
  142 
  143         /* Alignment for WPTR updates */
  144         encp->enc_rx_push_align = 1;
  145 
  146 #if EFSYS_OPT_RX_SCALE
  147         /* There is one RSS context per function */
  148         encp->enc_rx_scale_max_exclusive_contexts = 1;
  149 
  150         encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR);
  151         encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ);
  152 
  153         /*
  154          * It is always possible to use port numbers
  155          * as the input data for hash computation.
  156          */
  157         encp->enc_rx_scale_l4_hash_supported = B_TRUE;
  158 
  159         /* There is no support for additional RSS modes */
  160         encp->enc_rx_scale_additional_modes_supported = B_FALSE;
  161 #endif /* EFSYS_OPT_RX_SCALE */
  162 
  163         encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
  164         /* Fragments must not span 4k boundaries. */
  165         encp->enc_tx_dma_desc_boundary = 4096;
  166 
  167         /* Resource limits */
  168         rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
  169         if (rc != 0) {
  170                 if (rc != ENOTSUP)
  171                         goto fail2;
  172 
  173                 nevq = 1024;
  174                 nrxq = EFX_RXQ_LIMIT_TARGET;
  175                 ntxq = EFX_TXQ_LIMIT_TARGET;
  176         }
  177         encp->enc_evq_limit = nevq;
  178         encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
  179         encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
  180 
  181         encp->enc_txq_max_ndescs = 4096;
  182 
  183         encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
  184             (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
  185             (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
  186 
  187         encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
  188         encp->enc_fw_assisted_tso_enabled = B_FALSE;
  189         encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
  190         encp->enc_fw_assisted_tso_v2_n_contexts = 0;
  191         encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
  192         encp->enc_rx_packed_stream_supported = B_FALSE;
  193         encp->enc_rx_var_packed_stream_supported = B_FALSE;
  194         encp->enc_rx_es_super_buffer_supported = B_FALSE;
  195         encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE;
  196 
  197         /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
  198         encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
  199         encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
  200 
  201         encp->enc_nvram_update_verify_result_supported = B_FALSE;
  202 
  203         encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS;
  204 
  205         encp->enc_filter_action_flag_supported = B_FALSE;
  206         encp->enc_filter_action_mark_supported = B_FALSE;
  207         encp->enc_filter_action_mark_max = 0;
  208 
  209         return (0);
  210 
  211 fail2:
  212         EFSYS_PROBE(fail2);
  213 fail1:
  214         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  215 
  216         return (rc);
  217 }
  218 
  219 static  __checkReturn   efx_rc_t
  220 siena_phy_cfg(
  221         __in            efx_nic_t *enp)
  222 {
  223 #if EFSYS_OPT_PHY_STATS
  224         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
  225 #endif  /* EFSYS_OPT_PHY_STATS */
  226         efx_rc_t rc;
  227 
  228         /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
  229         if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
  230                 goto fail1;
  231 
  232 #if EFSYS_OPT_PHY_STATS
  233         /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
  234         siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
  235                             NULL, &encp->enc_phy_stat_mask, NULL);
  236 #endif  /* EFSYS_OPT_PHY_STATS */
  237 
  238         return (0);
  239 
  240 fail1:
  241         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  242 
  243         return (rc);
  244 }
  245 
  246 #define SIENA_BIU_MAGIC0        0x01234567
  247 #define SIENA_BIU_MAGIC1        0xfedcba98
  248 
  249 static  __checkReturn   efx_rc_t
  250 siena_nic_biu_test(
  251         __in            efx_nic_t *enp)
  252 {
  253         efx_oword_t oword;
  254         efx_rc_t rc;
  255 
  256         /*
  257          * Write magic values to scratch registers 0 and 1, then
  258          * verify that the values were written correctly.  Interleave
  259          * the accesses to ensure that the BIU is not just reading
  260          * back the cached value that was last written.
  261          */
  262         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
  263         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
  264 
  265         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
  266         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
  267 
  268         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
  269         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
  270                 rc = EIO;
  271                 goto fail1;
  272         }
  273 
  274         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
  275         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
  276                 rc = EIO;
  277                 goto fail2;
  278         }
  279 
  280         /*
  281          * Perform the same test, with the values swapped.  This
  282          * ensures that subsequent tests don't start with the correct
  283          * values already written into the scratch registers.
  284          */
  285         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1);
  286         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
  287 
  288         EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0);
  289         EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
  290 
  291         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
  292         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) {
  293                 rc = EIO;
  294                 goto fail3;
  295         }
  296 
  297         EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
  298         if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) {
  299                 rc = EIO;
  300                 goto fail4;
  301         }
  302 
  303         return (0);
  304 
  305 fail4:
  306         EFSYS_PROBE(fail4);
  307 fail3:
  308         EFSYS_PROBE(fail3);
  309 fail2:
  310         EFSYS_PROBE(fail2);
  311 fail1:
  312         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  313 
  314         return (rc);
  315 }
  316 
  317         __checkReturn   efx_rc_t
  318 siena_nic_probe(
  319         __in            efx_nic_t *enp)
  320 {
  321         efx_port_t *epp = &(enp->en_port);
  322         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
  323         siena_link_state_t sls;
  324         unsigned int mask;
  325         efx_oword_t oword;
  326         efx_rc_t rc;
  327 
  328         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
  329 
  330         /* Test BIU */
  331         if ((rc = siena_nic_biu_test(enp)) != 0)
  332                 goto fail1;
  333 
  334         /* Clear the region register */
  335         EFX_POPULATE_OWORD_4(oword,
  336             FRF_AZ_ADR_REGION0, 0,
  337             FRF_AZ_ADR_REGION1, (1 << 16),
  338             FRF_AZ_ADR_REGION2, (2 << 16),
  339             FRF_AZ_ADR_REGION3, (3 << 16));
  340         EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
  341 
  342         /* Read clear any assertion state */
  343         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
  344                 goto fail2;
  345 
  346         /* Exit the assertion handler */
  347         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
  348                 goto fail3;
  349 
  350         /* Wrestle control from the BMC */
  351         if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
  352                 goto fail4;
  353 
  354         if ((rc = siena_board_cfg(enp)) != 0)
  355                 goto fail5;
  356 
  357         if ((rc = siena_phy_cfg(enp)) != 0)
  358                 goto fail6;
  359 
  360         /* Obtain the default PHY advertised capabilities */
  361         if ((rc = siena_nic_reset(enp)) != 0)
  362                 goto fail7;
  363         if ((rc = siena_phy_get_link(enp, &sls)) != 0)
  364                 goto fail8;
  365         epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
  366         epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
  367 
  368 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
  369         if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
  370                 goto fail9;
  371         enp->en_u.siena.enu_partn_mask = mask;
  372 #endif
  373 
  374 #if EFSYS_OPT_MAC_STATS
  375         /* Wipe the MAC statistics */
  376         if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
  377                 goto fail10;
  378 #endif
  379 
  380 #if EFSYS_OPT_LOOPBACK
  381         if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
  382                 goto fail11;
  383 #endif
  384 
  385 #if EFSYS_OPT_MON_STATS
  386         if ((rc = mcdi_mon_cfg_build(enp)) != 0)
  387                 goto fail12;
  388 #endif
  389 
  390         encp->enc_features = enp->en_features;
  391 
  392         return (0);
  393 
  394 #if EFSYS_OPT_MON_STATS
  395 fail12:
  396         EFSYS_PROBE(fail12);
  397 #endif
  398 #if EFSYS_OPT_LOOPBACK
  399 fail11:
  400         EFSYS_PROBE(fail11);
  401 #endif
  402 #if EFSYS_OPT_MAC_STATS
  403 fail10:
  404         EFSYS_PROBE(fail10);
  405 #endif
  406 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
  407 fail9:
  408         EFSYS_PROBE(fail9);
  409 #endif
  410 fail8:
  411         EFSYS_PROBE(fail8);
  412 fail7:
  413         EFSYS_PROBE(fail7);
  414 fail6:
  415         EFSYS_PROBE(fail6);
  416 fail5:
  417         EFSYS_PROBE(fail5);
  418 fail4:
  419         EFSYS_PROBE(fail4);
  420 fail3:
  421         EFSYS_PROBE(fail3);
  422 fail2:
  423         EFSYS_PROBE(fail2);
  424 fail1:
  425         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  426 
  427         return (rc);
  428 }
  429 
  430         __checkReturn   efx_rc_t
  431 siena_nic_reset(
  432         __in            efx_nic_t *enp)
  433 {
  434         efx_mcdi_req_t req;
  435         efx_rc_t rc;
  436 
  437         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
  438 
  439         /* siena_nic_reset() is called to recover from BADASSERT failures. */
  440         if ((rc = efx_mcdi_read_assertion(enp)) != 0)
  441                 goto fail1;
  442         if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
  443                 goto fail2;
  444 
  445         /*
  446          * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
  447          * for backwards compatibility with PORT_RESET_IN_LEN.
  448          */
  449         EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
  450 
  451         req.emr_cmd = MC_CMD_ENTITY_RESET;
  452         req.emr_in_buf = NULL;
  453         req.emr_in_length = 0;
  454         req.emr_out_buf = NULL;
  455         req.emr_out_length = 0;
  456 
  457         efx_mcdi_execute(enp, &req);
  458 
  459         if (req.emr_rc != 0) {
  460                 rc = req.emr_rc;
  461                 goto fail3;
  462         }
  463 
  464         return (0);
  465 
  466 fail3:
  467         EFSYS_PROBE(fail3);
  468 fail2:
  469         EFSYS_PROBE(fail2);
  470 fail1:
  471         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  472 
  473         return (0);
  474 }
  475 
  476 static                  void
  477 siena_nic_rx_cfg(
  478         __in            efx_nic_t *enp)
  479 {
  480         efx_oword_t oword;
  481 
  482         /*
  483          * RX_INGR_EN is always enabled on Siena, because we rely on
  484          * the RX parser to be resiliant to missing SOP/EOP.
  485          */
  486         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
  487         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
  488         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
  489 
  490         /* Disable parsing of additional 802.1Q in Q packets */
  491         EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
  492         EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
  493         EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
  494 }
  495 
  496 static                  void
  497 siena_nic_usrev_dis(
  498         __in            efx_nic_t *enp)
  499 {
  500         efx_oword_t     oword;
  501 
  502         EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
  503         EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
  504 }
  505 
  506         __checkReturn   efx_rc_t
  507 siena_nic_init(
  508         __in            efx_nic_t *enp)
  509 {
  510         efx_rc_t rc;
  511 
  512         EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
  513 
  514         /* Enable reporting of some events (e.g. link change) */
  515         if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
  516                 goto fail1;
  517 
  518         siena_sram_init(enp);
  519 
  520         /* Configure Siena's RX block */
  521         siena_nic_rx_cfg(enp);
  522 
  523         /* Disable USR_EVents for now */
  524         siena_nic_usrev_dis(enp);
  525 
  526         /* bug17057: Ensure set_link is called */
  527         if ((rc = siena_phy_reconfigure(enp)) != 0)
  528                 goto fail2;
  529 
  530         enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
  531 
  532         return (0);
  533 
  534 fail2:
  535         EFSYS_PROBE(fail2);
  536 fail1:
  537         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  538 
  539         return (rc);
  540 }
  541 
  542                         void
  543 siena_nic_fini(
  544         __in            efx_nic_t *enp)
  545 {
  546         _NOTE(ARGUNUSED(enp))
  547 }
  548 
  549                         void
  550 siena_nic_unprobe(
  551         __in            efx_nic_t *enp)
  552 {
  553 #if EFSYS_OPT_MON_STATS
  554         mcdi_mon_cfg_free(enp);
  555 #endif /* EFSYS_OPT_MON_STATS */
  556         (void) efx_mcdi_drv_attach(enp, B_FALSE);
  557 }
  558 
  559 #if EFSYS_OPT_DIAG
  560 
  561 static siena_register_set_t __siena_registers[] = {
  562         { FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
  563         { FR_CZ_USR_EV_CFG_OFST, 0, 1 },
  564         { FR_AZ_RX_CFG_REG_OFST, 0, 1 },
  565         { FR_AZ_TX_CFG_REG_OFST, 0, 1 },
  566         { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
  567         { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
  568         { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
  569         { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
  570         { FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
  571         { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
  572         { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
  573         { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
  574         { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
  575 };
  576 
  577 static const uint32_t __siena_register_masks[] = {
  578         0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
  579         0x000103FF, 0x00000000, 0x00000000, 0x00000000,
  580         0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
  581         0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
  582         0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
  583         0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
  584         0x00000003, 0x00000000, 0x00000000, 0x00000000,
  585         0x000003FF, 0x00000000, 0x00000000, 0x00000000,
  586         0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
  587         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
  588         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
  589         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
  590         0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
  591 };
  592 
  593 static siena_register_set_t __siena_tables[] = {
  594         { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
  595             FR_AZ_RX_FILTER_TBL0_ROWS },
  596         { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
  597             FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
  598         { FR_AZ_RX_DESC_PTR_TBL_OFST,
  599             FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
  600         { FR_AZ_TX_DESC_PTR_TBL_OFST,
  601             FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
  602         { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
  603         { FR_CZ_TX_FILTER_TBL0_OFST,
  604             FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
  605         { FR_CZ_TX_MAC_FILTER_TBL0_OFST,
  606             FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
  607 };
  608 
  609 static const uint32_t __siena_table_masks[] = {
  610         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
  611         0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
  612         0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
  613         0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
  614         0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
  615         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
  616         0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
  617 };
  618 
  619         __checkReturn   efx_rc_t
  620 siena_nic_test_registers(
  621         __in            efx_nic_t *enp,
  622         __in            siena_register_set_t *rsp,
  623         __in            size_t count)
  624 {
  625         unsigned int bit;
  626         efx_oword_t original;
  627         efx_oword_t reg;
  628         efx_oword_t buf;
  629         efx_rc_t rc;
  630 
  631         while (count > 0) {
  632                 /* This function is only suitable for registers */
  633                 EFSYS_ASSERT(rsp->rows == 1);
  634 
  635                 /* bit sweep on and off */
  636                 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
  637                             B_TRUE);
  638                 for (bit = 0; bit < 128; bit++) {
  639                         /* Is this bit in the mask? */
  640                         if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
  641                                 continue;
  642 
  643                         /* Test this bit can be set in isolation */
  644                         reg = original;
  645                         EFX_AND_OWORD(reg, rsp->mask);
  646                         EFX_SET_OWORD_BIT(reg, bit);
  647 
  648                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
  649                                     B_TRUE);
  650                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
  651                                     B_TRUE);
  652 
  653                         EFX_AND_OWORD(buf, rsp->mask);
  654                         if (memcmp(&reg, &buf, sizeof (reg))) {
  655                                 rc = EIO;
  656                                 goto fail1;
  657                         }
  658 
  659                         /* Test this bit can be cleared in isolation */
  660                         EFX_OR_OWORD(reg, rsp->mask);
  661                         EFX_CLEAR_OWORD_BIT(reg, bit);
  662 
  663                         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
  664                                     B_TRUE);
  665                         EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
  666                                     B_TRUE);
  667 
  668                         EFX_AND_OWORD(buf, rsp->mask);
  669                         if (memcmp(&reg, &buf, sizeof (reg))) {
  670                                 rc = EIO;
  671                                 goto fail2;
  672                         }
  673                 }
  674 
  675                 /* Restore the old value */
  676                 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
  677                             B_TRUE);
  678 
  679                 --count;
  680                 ++rsp;
  681         }
  682 
  683         return (0);
  684 
  685 fail2:
  686         EFSYS_PROBE(fail2);
  687 fail1:
  688         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  689 
  690         /* Restore the old value */
  691         EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
  692 
  693         return (rc);
  694 }
  695 
  696         __checkReturn   efx_rc_t
  697 siena_nic_test_tables(
  698         __in            efx_nic_t *enp,
  699         __in            siena_register_set_t *rsp,
  700         __in            efx_pattern_type_t pattern,
  701         __in            size_t count)
  702 {
  703         efx_sram_pattern_fn_t func;
  704         unsigned int index;
  705         unsigned int address;
  706         efx_oword_t reg;
  707         efx_oword_t buf;
  708         efx_rc_t rc;
  709 
  710         EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
  711         func = __efx_sram_pattern_fns[pattern];
  712 
  713         while (count > 0) {
  714                 /* Write */
  715                 address = rsp->address;
  716                 for (index = 0; index < rsp->rows; ++index) {
  717                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
  718                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
  719                         EFX_AND_OWORD(reg, rsp->mask);
  720                         EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
  721 
  722                         address += rsp->step;
  723                 }
  724 
  725                 /* Read */
  726                 address = rsp->address;
  727                 for (index = 0; index < rsp->rows; ++index) {
  728                         func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
  729                         func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
  730                         EFX_AND_OWORD(reg, rsp->mask);
  731                         EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
  732                         if (memcmp(&reg, &buf, sizeof (reg))) {
  733                                 rc = EIO;
  734                                 goto fail1;
  735                         }
  736 
  737                         address += rsp->step;
  738                 }
  739 
  740                 ++rsp;
  741                 --count;
  742         }
  743 
  744         return (0);
  745 
  746 fail1:
  747         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  748 
  749         return (rc);
  750 }
  751 
  752         __checkReturn   efx_rc_t
  753 siena_nic_register_test(
  754         __in            efx_nic_t *enp)
  755 {
  756         siena_register_set_t *rsp;
  757         const uint32_t *dwordp;
  758         unsigned int nitems;
  759         unsigned int count;
  760         efx_rc_t rc;
  761 
  762         /* Fill out the register mask entries */
  763         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
  764                     == EFX_ARRAY_SIZE(__siena_registers) * 4);
  765 
  766         nitems = EFX_ARRAY_SIZE(__siena_registers);
  767         dwordp = __siena_register_masks;
  768         for (count = 0; count < nitems; ++count) {
  769                 rsp = __siena_registers + count;
  770                 rsp->mask.eo_u32[0] = *dwordp++;
  771                 rsp->mask.eo_u32[1] = *dwordp++;
  772                 rsp->mask.eo_u32[2] = *dwordp++;
  773                 rsp->mask.eo_u32[3] = *dwordp++;
  774         }
  775 
  776         /* Fill out the register table entries */
  777         EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
  778                     == EFX_ARRAY_SIZE(__siena_tables) * 4);
  779 
  780         nitems = EFX_ARRAY_SIZE(__siena_tables);
  781         dwordp = __siena_table_masks;
  782         for (count = 0; count < nitems; ++count) {
  783                 rsp = __siena_tables + count;
  784                 rsp->mask.eo_u32[0] = *dwordp++;
  785                 rsp->mask.eo_u32[1] = *dwordp++;
  786                 rsp->mask.eo_u32[2] = *dwordp++;
  787                 rsp->mask.eo_u32[3] = *dwordp++;
  788         }
  789 
  790         if ((rc = siena_nic_test_registers(enp, __siena_registers,
  791             EFX_ARRAY_SIZE(__siena_registers))) != 0)
  792                 goto fail1;
  793 
  794         if ((rc = siena_nic_test_tables(enp, __siena_tables,
  795             EFX_PATTERN_BYTE_ALTERNATE,
  796             EFX_ARRAY_SIZE(__siena_tables))) != 0)
  797                 goto fail2;
  798 
  799         if ((rc = siena_nic_test_tables(enp, __siena_tables,
  800             EFX_PATTERN_BYTE_CHANGING,
  801             EFX_ARRAY_SIZE(__siena_tables))) != 0)
  802                 goto fail3;
  803 
  804         if ((rc = siena_nic_test_tables(enp, __siena_tables,
  805             EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
  806                 goto fail4;
  807 
  808         return (0);
  809 
  810 fail4:
  811         EFSYS_PROBE(fail4);
  812 fail3:
  813         EFSYS_PROBE(fail3);
  814 fail2:
  815         EFSYS_PROBE(fail2);
  816 fail1:
  817         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  818 
  819         return (rc);
  820 }
  821 
  822 #endif  /* EFSYS_OPT_DIAG */
  823 
  824 #endif  /* EFSYS_OPT_SIENA */

Cache object: 88b7675d51d4cb0f2f37782860561a38


[ 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.