int hfi1_init_dd()

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;
}