49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Copyright (c) 2008-2016 Solarflare Communications Inc.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * All rights reserved.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Redistribution and use in source and binary forms, with or without
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * modification, are permitted provided that the following conditions are met:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * 1. Redistributions of source code must retain the above copyright notice,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * this list of conditions and the following disclaimer.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * 2. Redistributions in binary form must reproduce the above copyright notice,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * this list of conditions and the following disclaimer in the documentation
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * and/or other materials provided with the distribution.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * The views and conclusions contained in the software and documentation are
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * those of the authors and should not be interpreted as representing official
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * policies, either expressed or implied, of the FreeBSD Project.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/types.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/ddi.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/sunddi.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/pci.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include <sys/pcie.h>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/* PCIe 3.0 link speeds */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#ifndef PCIE_LINKCAP_MAX_SPEED_5
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#define PCIE_LINKCAP_MAX_SPEED_5 0x2
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#endif
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#ifndef PCIE_LINKSTS_SPEED_5
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#define PCIE_LINKSTS_SPEED_5 0x2
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#endif
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#ifndef PCIE_LINKCAP_MAX_SPEED_8
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#define PCIE_LINKCAP_MAX_SPEED_8 0x3
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#endif
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#ifndef PCIE_LINKSTS_SPEED_8
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#define PCIE_LINKSTS_SPEED_8 0x3
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#endif
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include "sfxge.h"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_pci_cap_find(sfxge_t *sp, uint8_t cap_id, off_t *offp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore off_t off;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint16_t stat;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore stat = pci_config_get16(sp->s_pci_handle, PCI_CONF_STAT);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (!(stat & PCI_STAT_CAP)) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOTSUP;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore for (off = pci_config_get8(sp->s_pci_handle, PCI_CONF_CAP_PTR);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore off != PCI_CAP_NEXT_PTR_NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore off = pci_config_get8(sp->s_pci_handle, off + PCI_CAP_NEXT_PTR)) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (cap_id == pci_config_get8(sp->s_pci_handle,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore off + PCI_CAP_ID))
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto done;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENOENT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredone:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *offp = off;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_pci_init(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore off_t off;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint16_t pciecap;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint16_t devctl;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint16_t linksts;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint16_t max_payload_size;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint16_t max_read_request;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int rc;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#if EFSYS_OPT_MCDI_LOGGING
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int *pci_regs;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint_t pci_nregs = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * We need the PCI bus address to format MCDI logging output in the
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * same way as on other platforms.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * It appears there's no straightforward way to extract the address
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * from a "dev_info_t" structure, though.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * The "reg" property is supported by all PCIe devices, and contains
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * an arbitrary length array of elements describing logical
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * resources. Each element contains a 5-tuple of 32bit values,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * where the first 32bit value contains the bus/dev/fn slot
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * information.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * See pci(4) and the definition of "struct pci_phys_spec" in sys/pci.h
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, sp->s_dip,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_PROP_DONTPASS, "reg", (int **)&pci_regs, &pci_nregs) !=
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_PROP_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENODEV;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_bus_addr = pci_regs[0];
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_prop_free(pci_regs);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#endif
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (pci_config_setup(sp->s_dip, &(sp->s_pci_handle)) != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore rc = ENODEV;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pci_venid = pci_config_get16(sp->s_pci_handle, PCI_CONF_VENID);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pci_devid = pci_config_get16(sp->s_pci_handle, PCI_CONF_DEVID);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = efx_family(sp->s_pci_venid, sp->s_pci_devid,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore &sp->s_family)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((rc = sfxge_pci_cap_find(sp, PCI_CAP_ID_PCI_E, &off)) != 0)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto fail3;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore pciecap = pci_config_get16(sp->s_pci_handle, off + PCIE_PCIECAP);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT3U((pciecap & PCIE_PCIECAP_VER_MASK), >=, PCIE_PCIECAP_VER_1_0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore linksts = pci_config_get16(sp->s_pci_handle, off + PCIE_LINKSTS);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore switch (linksts & PCIE_LINKSTS_NEG_WIDTH_MASK) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore case PCIE_LINKSTS_NEG_WIDTH_X1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_nlanes = 1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore case PCIE_LINKSTS_NEG_WIDTH_X2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_nlanes = 2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore case PCIE_LINKSTS_NEG_WIDTH_X4:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_nlanes = 4;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore case PCIE_LINKSTS_NEG_WIDTH_X8:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_nlanes = 8;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore default:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT(B_FALSE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore switch (linksts & PCIE_LINKSTS_SPEED_MASK) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore case PCIE_LINKSTS_SPEED_2_5:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_linkspeed = 1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore case PCIE_LINKSTS_SPEED_5:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_linkspeed = 2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore case PCIE_LINKSTS_SPEED_8:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_linkspeed = 3;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore default:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ASSERT(B_FALSE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore break;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore devctl = pci_config_get16(sp->s_pci_handle, off + PCIE_DEVCTL);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore max_payload_size = (devctl & PCIE_DEVCTL_MAX_PAYLOAD_MASK)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore >> PCIE_DEVCTL_MAX_PAYLOAD_SHIFT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore max_read_request = (devctl & PCIE_DEVCTL_MAX_READ_REQ_MASK)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore >> PCIE_DEVCTL_MAX_READ_REQ_SHIFT;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_NOTE,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore SFXGE_CMN_ERR "PCIe MRR: %d TLP: %d Link: %s Lanes: x%d",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 128 << max_read_request,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 128 << max_payload_size,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (sp->s_pcie_linkspeed == 1) ? "2.5G" :
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (sp->s_pcie_linkspeed == 2) ? "5.0G" :
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (sp->s_pcie_linkspeed == 3) ? "8.0G" :
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "UNKNOWN",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_nlanes);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail3:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail3);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE(fail2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore pci_config_teardown(&(sp->s_pci_handle));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pci_handle = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorefail1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DTRACE_PROBE1(fail1, int, rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (rc);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_pcie_check_link(sfxge_t *sp, unsigned int full_nlanes,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned int full_speed)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((sp->s_pcie_linkspeed < full_speed) ||
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (sp->s_pcie_nlanes < full_nlanes))
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev_err(sp->s_dip, CE_NOTE,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore SFXGE_CMN_ERR "This device requires %d PCIe lanes "
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "at %s link speed to reach full bandwidth.",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore full_nlanes,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (full_speed == 1) ? "2.5G" :
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (full_speed == 2) ? "5.0G" :
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (full_speed == 3) ? "8.0G" :
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "UNKNOWN");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoresfxge_pci_fini(sfxge_t *sp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_nlanes = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pcie_linkspeed = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore pci_config_teardown(&(sp->s_pci_handle));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore sp->s_pci_handle = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}