in hw/hfi1/chip.c [14991:15318]
int hfi1_init_dd(struct hfi1_devdata *dd)
{
struct pci_dev *pdev = dd->pcidev;
struct hfi1_pportdata *ppd;
u64 reg;
int i, ret;
static const char * const inames[] = { /* implementation names */
"RTL silicon",
"RTL VCS simulation",
"RTL FPGA emulation",
"Functional simulator"
};
struct pci_dev *parent = pdev->bus->self;
u32 sdma_engines = chip_sdma_engines(dd);
ppd = dd->pport;
for (i = 0; i < dd->num_pports; i++, ppd++) {
int vl;
/* init common fields */
hfi1_init_pportdata(pdev, ppd, dd, 0, 1);
/* DC supports 4 link widths */
ppd->link_width_supported =
OPA_LINK_WIDTH_1X | OPA_LINK_WIDTH_2X |
OPA_LINK_WIDTH_3X | OPA_LINK_WIDTH_4X;
ppd->link_width_downgrade_supported =
ppd->link_width_supported;
/* start out enabling only 4X */
ppd->link_width_enabled = OPA_LINK_WIDTH_4X;
ppd->link_width_downgrade_enabled =
ppd->link_width_downgrade_supported;
/* link width active is 0 when link is down */
/* link width downgrade active is 0 when link is down */
if (num_vls < HFI1_MIN_VLS_SUPPORTED ||
num_vls > HFI1_MAX_VLS_SUPPORTED) {
dd_dev_err(dd, "Invalid num_vls %u, using %u VLs\n",
num_vls, HFI1_MAX_VLS_SUPPORTED);
num_vls = HFI1_MAX_VLS_SUPPORTED;
}
ppd->vls_supported = num_vls;
ppd->vls_operational = ppd->vls_supported;
/* Set the default MTU. */
for (vl = 0; vl < num_vls; vl++)
dd->vld[vl].mtu = hfi1_max_mtu;
dd->vld[15].mtu = MAX_MAD_PACKET;
/*
* Set the initial values to reasonable default, will be set
* for real when link is up.
*/
ppd->overrun_threshold = 0x4;
ppd->phy_error_threshold = 0xf;
ppd->port_crc_mode_enabled = link_crc_mask;
/* initialize supported LTP CRC mode */
ppd->port_ltp_crc_mode = cap_to_port_ltp(link_crc_mask) << 8;
/* initialize enabled LTP CRC mode */
ppd->port_ltp_crc_mode |= cap_to_port_ltp(link_crc_mask) << 4;
/* start in offline */
ppd->host_link_state = HLS_DN_OFFLINE;
init_vl_arb_caches(ppd);
}
/*
* Do remaining PCIe setup and save PCIe values in dd.
* Any error printing is already done by the init code.
* On return, we have the chip mapped.
*/
ret = hfi1_pcie_ddinit(dd, pdev);
if (ret < 0)
goto bail_free;
/* Save PCI space registers to rewrite after device reset */
ret = save_pci_variables(dd);
if (ret < 0)
goto bail_cleanup;
dd->majrev = (dd->revision >> CCE_REVISION_CHIP_REV_MAJOR_SHIFT)
& CCE_REVISION_CHIP_REV_MAJOR_MASK;
dd->minrev = (dd->revision >> CCE_REVISION_CHIP_REV_MINOR_SHIFT)
& CCE_REVISION_CHIP_REV_MINOR_MASK;
/*
* Check interrupt registers mapping if the driver has no access to
* the upstream component. In this case, it is likely that the driver
* is running in a VM.
*/
if (!parent) {
ret = check_int_registers(dd);
if (ret)
goto bail_cleanup;
}
/*
* obtain the hardware ID - NOT related to unit, which is a
* software enumeration
*/
reg = read_csr(dd, CCE_REVISION2);
dd->hfi1_id = (reg >> CCE_REVISION2_HFI_ID_SHIFT)
& CCE_REVISION2_HFI_ID_MASK;
/* the variable size will remove unwanted bits */
dd->icode = reg >> CCE_REVISION2_IMPL_CODE_SHIFT;
dd->irev = reg >> CCE_REVISION2_IMPL_REVISION_SHIFT;
dd_dev_info(dd, "Implementation: %s, revision 0x%x\n",
dd->icode < ARRAY_SIZE(inames) ?
inames[dd->icode] : "unknown", (int)dd->irev);
/* speeds the hardware can support */
dd->pport->link_speed_supported = OPA_LINK_SPEED_25G;
/* speeds allowed to run at */
dd->pport->link_speed_enabled = dd->pport->link_speed_supported;
/* give a reasonable active value, will be set on link up */
dd->pport->link_speed_active = OPA_LINK_SPEED_25G;
/* fix up link widths for emulation _p */
ppd = dd->pport;
if (dd->icode == ICODE_FPGA_EMULATION && is_emulator_p(dd)) {
ppd->link_width_supported =
ppd->link_width_enabled =
ppd->link_width_downgrade_supported =
ppd->link_width_downgrade_enabled =
OPA_LINK_WIDTH_1X;
}
/* insure num_vls isn't larger than number of sdma engines */
if (HFI1_CAP_IS_KSET(SDMA) && num_vls > sdma_engines) {
dd_dev_err(dd, "num_vls %u too large, using %u VLs\n",
num_vls, sdma_engines);
num_vls = sdma_engines;
ppd->vls_supported = sdma_engines;
ppd->vls_operational = ppd->vls_supported;
}
/*
* Convert the ns parameter to the 64 * cclocks used in the CSR.
* Limit the max if larger than the field holds. If timeout is
* non-zero, then the calculated field will be at least 1.
*
* Must be after icode is set up - the cclock rate depends
* on knowing the hardware being used.
*/
dd->rcv_intr_timeout_csr = ns_to_cclock(dd, rcv_intr_timeout) / 64;
if (dd->rcv_intr_timeout_csr >
RCV_AVAIL_TIME_OUT_TIME_OUT_RELOAD_MASK)
dd->rcv_intr_timeout_csr =
RCV_AVAIL_TIME_OUT_TIME_OUT_RELOAD_MASK;
else if (dd->rcv_intr_timeout_csr == 0 && rcv_intr_timeout)
dd->rcv_intr_timeout_csr = 1;
/* needs to be done before we look for the peer device */
read_guid(dd);
/* set up shared ASIC data with peer device */
ret = init_asic_data(dd);
if (ret)
goto bail_cleanup;
/* obtain chip sizes, reset chip CSRs */
ret = init_chip(dd);
if (ret)
goto bail_cleanup;
/* read in the PCIe link speed information */
ret = pcie_speeds(dd);
if (ret)
goto bail_cleanup;
/* call before get_platform_config(), after init_chip_resources() */
ret = eprom_init(dd);
if (ret)
goto bail_free_rcverr;
/* Needs to be called before hfi1_firmware_init */
get_platform_config(dd);
/* read in firmware */
ret = hfi1_firmware_init(dd);
if (ret)
goto bail_cleanup;
/*
* In general, the PCIe Gen3 transition must occur after the
* chip has been idled (so it won't initiate any PCIe transactions
* e.g. an interrupt) and before the driver changes any registers
* (the transition will reset the registers).
*
* In particular, place this call after:
* - init_chip() - the chip will not initiate any PCIe transactions
* - pcie_speeds() - reads the current link speed
* - hfi1_firmware_init() - the needed firmware is ready to be
* downloaded
*/
ret = do_pcie_gen3_transition(dd);
if (ret)
goto bail_cleanup;
/*
* This should probably occur in hfi1_pcie_init(), but historically
* occurs after the do_pcie_gen3_transition() code.
*/
tune_pcie_caps(dd);
/* start setting dd values and adjusting CSRs */
init_early_variables(dd);
parse_platform_config(dd);
ret = obtain_boardname(dd);
if (ret)
goto bail_cleanup;
snprintf(dd->boardversion, BOARD_VERS_MAX,
"ChipABI %u.%u, ChipRev %u.%u, SW Compat %llu\n",
HFI1_CHIP_VERS_MAJ, HFI1_CHIP_VERS_MIN,
(u32)dd->majrev,
(u32)dd->minrev,
(dd->revision >> CCE_REVISION_SW_SHIFT)
& CCE_REVISION_SW_MASK);
/* alloc VNIC/AIP rx data */
ret = hfi1_alloc_rx(dd);
if (ret)
goto bail_cleanup;
ret = set_up_context_variables(dd);
if (ret)
goto bail_cleanup;
/* set initial RXE CSRs */
ret = init_rxe(dd);
if (ret)
goto bail_cleanup;
/* set initial TXE CSRs */
init_txe(dd);
/* set initial non-RXE, non-TXE CSRs */
init_other(dd);
/* set up KDETH QP prefix in both RX and TX CSRs */
init_kdeth_qp(dd);
ret = hfi1_dev_affinity_init(dd);
if (ret)
goto bail_cleanup;
/* send contexts must be set up before receive contexts */
ret = init_send_contexts(dd);
if (ret)
goto bail_cleanup;
ret = hfi1_create_kctxts(dd);
if (ret)
goto bail_cleanup;
/*
* Initialize aspm, to be done after gen3 transition and setting up
* contexts and before enabling interrupts
*/
aspm_init(dd);
ret = init_pervl_scs(dd);
if (ret)
goto bail_cleanup;
/* sdma init */
for (i = 0; i < dd->num_pports; ++i) {
ret = sdma_init(dd, i);
if (ret)
goto bail_cleanup;
}
/* use contexts created by hfi1_create_kctxts */
ret = set_up_interrupts(dd);
if (ret)
goto bail_cleanup;
ret = hfi1_comp_vectors_set_up(dd);
if (ret)
goto bail_clear_intr;
/* set up LCB access - must be after set_up_interrupts() */
init_lcb_access(dd);
/*
* Serial number is created from the base guid:
* [27:24] = base guid [38:35]
* [23: 0] = base guid [23: 0]
*/
snprintf(dd->serial, SERIAL_MAX, "0x%08llx\n",
(dd->base_guid & 0xFFFFFF) |
((dd->base_guid >> 11) & 0xF000000));
dd->oui1 = dd->base_guid >> 56 & 0xFF;
dd->oui2 = dd->base_guid >> 48 & 0xFF;
dd->oui3 = dd->base_guid >> 40 & 0xFF;
ret = load_firmware(dd); /* asymmetric with dispose_firmware() */
if (ret)
goto bail_clear_intr;
thermal_init(dd);
ret = init_cntrs(dd);
if (ret)
goto bail_clear_intr;
ret = init_rcverr(dd);
if (ret)
goto bail_free_cntrs;
init_completion(&dd->user_comp);
/* The user refcount starts with one to inidicate an active device */
refcount_set(&dd->user_refcount, 1);
goto bail;
bail_free_rcverr:
free_rcverr(dd);
bail_free_cntrs:
free_cntrs(dd);
bail_clear_intr:
hfi1_comp_vectors_clean_up(dd);
msix_clean_up_interrupts(dd);
bail_cleanup:
hfi1_free_rx(dd);
hfi1_pcie_ddcleanup(dd);
bail_free:
hfi1_free_devdata(dd);
bail:
return ret;
}