15f5c71ccSAndrew Rybchenko /*- 2929c7febSAndrew Rybchenko * Copyright (c) 2015-2016 Solarflare Communications Inc. 35f5c71ccSAndrew Rybchenko * All rights reserved. 45f5c71ccSAndrew Rybchenko * 55f5c71ccSAndrew Rybchenko * Redistribution and use in source and binary forms, with or without 65f5c71ccSAndrew Rybchenko * modification, are permitted provided that the following conditions are met: 75f5c71ccSAndrew Rybchenko * 85f5c71ccSAndrew Rybchenko * 1. Redistributions of source code must retain the above copyright notice, 95f5c71ccSAndrew Rybchenko * this list of conditions and the following disclaimer. 105f5c71ccSAndrew Rybchenko * 2. Redistributions in binary form must reproduce the above copyright notice, 115f5c71ccSAndrew Rybchenko * this list of conditions and the following disclaimer in the documentation 125f5c71ccSAndrew Rybchenko * and/or other materials provided with the distribution. 135f5c71ccSAndrew Rybchenko * 145f5c71ccSAndrew Rybchenko * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 155f5c71ccSAndrew Rybchenko * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 165f5c71ccSAndrew Rybchenko * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 175f5c71ccSAndrew Rybchenko * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 185f5c71ccSAndrew Rybchenko * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 195f5c71ccSAndrew Rybchenko * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 205f5c71ccSAndrew Rybchenko * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 215f5c71ccSAndrew Rybchenko * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 225f5c71ccSAndrew Rybchenko * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 235f5c71ccSAndrew Rybchenko * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 245f5c71ccSAndrew Rybchenko * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 255f5c71ccSAndrew Rybchenko * 265f5c71ccSAndrew Rybchenko * The views and conclusions contained in the software and documentation are 275f5c71ccSAndrew Rybchenko * those of the authors and should not be interpreted as representing official 285f5c71ccSAndrew Rybchenko * policies, either expressed or implied, of the FreeBSD Project. 295f5c71ccSAndrew Rybchenko */ 305f5c71ccSAndrew Rybchenko 315f5c71ccSAndrew Rybchenko #include <sys/cdefs.h> 325f5c71ccSAndrew Rybchenko __FBSDID("$FreeBSD$"); 335f5c71ccSAndrew Rybchenko 345f5c71ccSAndrew Rybchenko #include "efx.h" 355f5c71ccSAndrew Rybchenko #include "efx_impl.h" 36dcb49ebaSAndrew Rybchenko 375f5c71ccSAndrew Rybchenko 385f5c71ccSAndrew Rybchenko #if EFSYS_OPT_MEDFORD 395f5c71ccSAndrew Rybchenko 406de7c598SAndrew Rybchenko static __checkReturn efx_rc_t 41f6d61784SAndrew Rybchenko medford_nic_get_required_pcie_bandwidth( 42f6d61784SAndrew Rybchenko __in efx_nic_t *enp, 43f6d61784SAndrew Rybchenko __out uint32_t *bandwidth_mbpsp) 44f6d61784SAndrew Rybchenko { 45f6d61784SAndrew Rybchenko uint32_t bandwidth; 46f6d61784SAndrew Rybchenko efx_rc_t rc; 47f6d61784SAndrew Rybchenko 48*c42b6a35SAndrew Rybchenko if ((rc = ef10_nic_get_port_mode_bandwidth(enp, 49f6d61784SAndrew Rybchenko &bandwidth)) != 0) 50f6d61784SAndrew Rybchenko goto fail1; 51f6d61784SAndrew Rybchenko 52f6d61784SAndrew Rybchenko *bandwidth_mbpsp = bandwidth; 53f6d61784SAndrew Rybchenko 54f6d61784SAndrew Rybchenko return (0); 55f6d61784SAndrew Rybchenko 56f6d61784SAndrew Rybchenko fail1: 57f6d61784SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc); 58f6d61784SAndrew Rybchenko 59f6d61784SAndrew Rybchenko return (rc); 60f6d61784SAndrew Rybchenko } 61f6d61784SAndrew Rybchenko 62cfa023ebSAndrew Rybchenko __checkReturn efx_rc_t 63cfa023ebSAndrew Rybchenko medford_board_cfg( 64cfa023ebSAndrew Rybchenko __in efx_nic_t *enp) 65cfa023ebSAndrew Rybchenko { 66cfa023ebSAndrew Rybchenko efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 6778e5c87cSAndrew Rybchenko uint32_t sysclk, dpcpu_clk; 686de7c598SAndrew Rybchenko uint32_t end_padding; 69f6d61784SAndrew Rybchenko uint32_t bandwidth; 70cfa023ebSAndrew Rybchenko efx_rc_t rc; 715f5c71ccSAndrew Rybchenko 72cfa023ebSAndrew Rybchenko /* 73e26f5dacSAndrew Rybchenko * Enable firmware workarounds for hardware errata. 74e26f5dacSAndrew Rybchenko * Expected responses are: 75e26f5dacSAndrew Rybchenko * - 0 (zero): 76e26f5dacSAndrew Rybchenko * Success: workaround enabled or disabled as requested. 77e26f5dacSAndrew Rybchenko * - MC_CMD_ERR_ENOSYS (reported as ENOTSUP): 78e26f5dacSAndrew Rybchenko * Firmware does not support the MC_CMD_WORKAROUND request. 79e26f5dacSAndrew Rybchenko * (assume that the workaround is not supported). 80e26f5dacSAndrew Rybchenko * - MC_CMD_ERR_ENOENT (reported as ENOENT): 81e26f5dacSAndrew Rybchenko * Firmware does not support the requested workaround. 82e26f5dacSAndrew Rybchenko * - MC_CMD_ERR_EPERM (reported as EACCES): 83e26f5dacSAndrew Rybchenko * Unprivileged function cannot enable/disable workarounds. 84e26f5dacSAndrew Rybchenko * 85e26f5dacSAndrew Rybchenko * See efx_mcdi_request_errcode() for MCDI error translations. 86e26f5dacSAndrew Rybchenko */ 87e26f5dacSAndrew Rybchenko 88e26f5dacSAndrew Rybchenko 89cfa023ebSAndrew Rybchenko if (EFX_PCI_FUNCTION_IS_VF(encp)) { 90cfa023ebSAndrew Rybchenko /* 911c057dc0SAndrew Rybchenko * Interrupt testing does not work for VFs. See bug50084 and 921c057dc0SAndrew Rybchenko * bug71432 comment 21. 93cfa023ebSAndrew Rybchenko */ 94cfa023ebSAndrew Rybchenko encp->enc_bug41750_workaround = B_TRUE; 95cfa023ebSAndrew Rybchenko } 96cfa023ebSAndrew Rybchenko 97cfa023ebSAndrew Rybchenko /* Chained multicast is always enabled on Medford */ 98cfa023ebSAndrew Rybchenko encp->enc_bug26807_workaround = B_TRUE; 99cfa023ebSAndrew Rybchenko 100e26f5dacSAndrew Rybchenko /* 101e26f5dacSAndrew Rybchenko * If the bug61265 workaround is enabled, then interrupt holdoff timers 102e26f5dacSAndrew Rybchenko * cannot be controlled by timer table writes, so MCDI must be used 103e26f5dacSAndrew Rybchenko * (timer table writes can still be used for wakeup timers). 104e26f5dacSAndrew Rybchenko */ 105e26f5dacSAndrew Rybchenko rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG61265, B_TRUE, 106e26f5dacSAndrew Rybchenko NULL); 107e26f5dacSAndrew Rybchenko if ((rc == 0) || (rc == EACCES)) 108e26f5dacSAndrew Rybchenko encp->enc_bug61265_workaround = B_TRUE; 109e26f5dacSAndrew Rybchenko else if ((rc == ENOTSUP) || (rc == ENOENT)) 110e26f5dacSAndrew Rybchenko encp->enc_bug61265_workaround = B_FALSE; 111e26f5dacSAndrew Rybchenko else 112e5f6f32fSAndrew Rybchenko goto fail1; 113e26f5dacSAndrew Rybchenko 1145037810fSAndrew Rybchenko /* Checksums for TSO sends can be incorrect on Medford. */ 1155037810fSAndrew Rybchenko encp->enc_bug61297_workaround = B_TRUE; 1165037810fSAndrew Rybchenko 11778e5c87cSAndrew Rybchenko /* Get clock frequencies (in MHz). */ 11878e5c87cSAndrew Rybchenko if ((rc = efx_mcdi_get_clock(enp, &sysclk, &dpcpu_clk)) != 0) 119e5f6f32fSAndrew Rybchenko goto fail2; 120cfa023ebSAndrew Rybchenko 121cfa023ebSAndrew Rybchenko /* 12278e5c87cSAndrew Rybchenko * The Medford timer quantum is 1536 dpcpu_clk cycles, documented for 12378e5c87cSAndrew Rybchenko * the EV_TMR_VAL field of EV_TIMER_TBL. Scale for MHz and ns units. 124cfa023ebSAndrew Rybchenko */ 12578e5c87cSAndrew Rybchenko encp->enc_evq_timer_quantum_ns = 1536000UL / dpcpu_clk; /* 1536 cycles */ 126cfa023ebSAndrew Rybchenko encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns << 127cfa023ebSAndrew Rybchenko FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000; 128cfa023ebSAndrew Rybchenko 129cfa023ebSAndrew Rybchenko /* Alignment for receive packet DMA buffers */ 130cfa023ebSAndrew Rybchenko encp->enc_rx_buf_align_start = 1; 131cfa023ebSAndrew Rybchenko 1326de7c598SAndrew Rybchenko /* Get the RX DMA end padding alignment configuration */ 133ab72be51SAndrew Rybchenko if ((rc = efx_mcdi_get_rxdp_config(enp, &end_padding)) != 0) { 134ab72be51SAndrew Rybchenko if (rc != EACCES) 135deeaf87fSAndrew Rybchenko goto fail3; 136ab72be51SAndrew Rybchenko 137ab72be51SAndrew Rybchenko /* Assume largest tail padding size supported by hardware */ 138ab72be51SAndrew Rybchenko end_padding = 256; 139ab72be51SAndrew Rybchenko } 1406de7c598SAndrew Rybchenko encp->enc_rx_buf_align_end = end_padding; 141cfa023ebSAndrew Rybchenko 142cfa023ebSAndrew Rybchenko /* 143d343a7f4SAndrew Rybchenko * The maximum supported transmit queue size is 2048. TXQs with 4096 144d343a7f4SAndrew Rybchenko * descriptors are not supported as the top bit is used for vfifo 145d343a7f4SAndrew Rybchenko * stuffing. 146d343a7f4SAndrew Rybchenko */ 147d343a7f4SAndrew Rybchenko encp->enc_txq_max_ndescs = 2048; 148d343a7f4SAndrew Rybchenko 1494f58306cSAndrew Rybchenko EFX_STATIC_ASSERT(MEDFORD_PIOBUF_NBUFS <= EF10_MAX_PIOBUF_NBUFS); 150cfa023ebSAndrew Rybchenko encp->enc_piobuf_limit = MEDFORD_PIOBUF_NBUFS; 151cfa023ebSAndrew Rybchenko encp->enc_piobuf_size = MEDFORD_PIOBUF_SIZE; 152cfa023ebSAndrew Rybchenko encp->enc_piobuf_min_alloc_size = MEDFORD_MIN_PIO_ALLOC_SIZE; 153cfa023ebSAndrew Rybchenko 154cfa023ebSAndrew Rybchenko /* 155739ebba6SAndrew Rybchenko * Medford stores a single global copy of VPD, not per-PF as on 156739ebba6SAndrew Rybchenko * Huntington. 157739ebba6SAndrew Rybchenko */ 158739ebba6SAndrew Rybchenko encp->enc_vpd_is_global = B_TRUE; 159739ebba6SAndrew Rybchenko 160f6d61784SAndrew Rybchenko rc = medford_nic_get_required_pcie_bandwidth(enp, &bandwidth); 161f6d61784SAndrew Rybchenko if (rc != 0) 16226fcca57SAndrew Rybchenko goto fail4; 163f6d61784SAndrew Rybchenko encp->enc_required_pcie_bandwidth_mbps = bandwidth; 164f6d61784SAndrew Rybchenko encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN3; 165f6d61784SAndrew Rybchenko 166cfa023ebSAndrew Rybchenko return (0); 167cfa023ebSAndrew Rybchenko 168cfa023ebSAndrew Rybchenko fail4: 169cfa023ebSAndrew Rybchenko EFSYS_PROBE(fail4); 170cfa023ebSAndrew Rybchenko fail3: 171cfa023ebSAndrew Rybchenko EFSYS_PROBE(fail3); 172cfa023ebSAndrew Rybchenko fail2: 173cfa023ebSAndrew Rybchenko EFSYS_PROBE(fail2); 174cfa023ebSAndrew Rybchenko fail1: 175cfa023ebSAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc); 176cfa023ebSAndrew Rybchenko 177cfa023ebSAndrew Rybchenko return (rc); 178cfa023ebSAndrew Rybchenko } 1795f5c71ccSAndrew Rybchenko 1805f5c71ccSAndrew Rybchenko #endif /* EFSYS_OPT_MEDFORD */ 181