Exemple #1
0
static int
vtpci_attach(device_t dev)
{
	struct vtpci_softc *sc;
	device_t child;
	int rid;

	sc = device_get_softc(dev);
	sc->vtpci_dev = dev;

	pci_enable_busmaster(dev);

	rid = PCIR_BAR(0);
	sc->vtpci_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
	    RF_ACTIVE);
	if (sc->vtpci_res == NULL) {
		device_printf(dev, "cannot map I/O space\n");
		return (ENXIO);
	}

	if (pci_find_extcap(dev, PCIY_MSI, NULL) != 0)
		sc->vtpci_flags |= VIRTIO_PCI_FLAG_NO_MSI;

	if (pci_find_extcap(dev, PCIY_MSIX, NULL) == 0) {
		rid = PCIR_BAR(1);
		sc->vtpci_msix_res = bus_alloc_resource_any(dev,
		    SYS_RES_MEMORY, &rid, RF_ACTIVE);
	}

	if (sc->vtpci_msix_res == NULL)
		sc->vtpci_flags |= VIRTIO_PCI_FLAG_NO_MSIX;

	vtpci_reset(sc);

	/* Tell the host we've noticed this device. */
	vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_ACK);

	if ((child = device_add_child(dev, NULL, -1)) == NULL) {
		device_printf(dev, "cannot create child device\n");
		vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_FAILED);
		vtpci_detach(dev);
		return (ENOMEM);
	}

	sc->vtpci_child_dev = child;
	vtpci_probe_and_attach_child(sc);

	return (0);
}
Exemple #2
0
static int
siba_bwn_find_extcap(device_t dev, device_t child, int capability,
    int *capreg)
{

	return (pci_find_extcap(dev, capability, capreg));
}
Exemple #3
0
static int
pci_hostb_find_extcap(device_t dev, device_t child, int capability,
    int *capreg)
{

	return (pci_find_extcap(dev, capability, capreg));
}
Exemple #4
0
/*
 * Write the PCI Express capabilities
 */
int32_t
e1000_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
	device_t dev = ((struct e1000_osdep *)hw->back)->dev;
	u32	offset;

	pci_find_extcap(dev, PCIY_EXPRESS, &offset);
	pci_write_config(dev, offset + reg, *value, 2);
	return (E1000_SUCCESS);
}
Exemple #5
0
int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask)
{
	device_t root;
	int pos;
	u32 lnkcap = 0, lnkcap2 = 0;

	*mask = 0;
	if (!drm_device_is_pcie(dev))
		return -EINVAL;

	root = device_get_parent(dev->device);

	pos = 0;
	pci_find_extcap(root, PCIY_EXPRESS, &pos);
	if (!pos)
		return -EINVAL;

	/* we've been informed via and serverworks don't make the cut */
	if (pci_get_vendor(root) == PCI_VENDOR_ID_VIA ||
	    pci_get_vendor(root) == PCI_VENDOR_ID_SERVERWORKS)
		return -EINVAL;

	lnkcap = pci_read_config(root, pos + PCIER_LINKCAP, 4);
	lnkcap2 = pci_read_config(root, pos + PCIER_LINK_CAP2, 4);

	lnkcap &= PCIEM_LNKCAP_SPEED_MASK;
	lnkcap2 &= 0xfe;

#define	PCI_EXP_LNKCAP2_SLS_2_5GB 0x02	/* Supported Link Speed 2.5GT/s */
#define	PCI_EXP_LNKCAP2_SLS_5_0GB 0x04	/* Supported Link Speed 5.0GT/s */
#define	PCI_EXP_LNKCAP2_SLS_8_0GB 0x08	/* Supported Link Speed 8.0GT/s */

	if (lnkcap2) { /* PCIE GEN 3.0 */
		if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB)
			*mask |= DRM_PCIE_SPEED_25;
		if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
			*mask |= DRM_PCIE_SPEED_50;
		if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
			*mask |= DRM_PCIE_SPEED_80;
	} else {
		if (lnkcap & 1)
			*mask |= DRM_PCIE_SPEED_25;
		if (lnkcap & 2)
			*mask |= DRM_PCIE_SPEED_50;
	}

	DRM_INFO("probing gen 2 caps for device %x:%x = %x/%x\n", pci_get_vendor(root), pci_get_device(root), lnkcap, lnkcap2);
	return 0;
}
Exemple #6
0
/**
 * @brief 		Function to get the PCI capabilities
 * @param sc		software handle to the device
 */
static
void oce_get_pci_capabilities(POCE_SOFTC sc)
{
	uint32_t val;

#if __FreeBSD_version >= 1000000
	#define pci_find_extcap pci_find_cap
#endif

	if (pci_find_extcap(sc->dev, PCIY_PCIX, &val) == 0) {
		if (val != 0) 
			sc->flags |= OCE_FLAGS_PCIX;
	}

	if (pci_find_extcap(sc->dev, PCIY_EXPRESS, &val) == 0) {
		if (val != 0) {
			uint16_t link_status =
			    pci_read_config(sc->dev, val + 0x12, 2);

			sc->flags |= OCE_FLAGS_PCIE;
			sc->pcie_link_speed = link_status & 0xf;
			sc->pcie_link_width = (link_status >> 4) & 0x3f;
		}
	}
Exemple #7
0
/*
 * Set the ARI_EN bit in the lowest-numbered PCI function with the SR-IOV
 * capability.  This bit is only writeable on the lowest-numbered PF but
 * affects all PFs on the device.
 */
static int
pci_iov_set_ari(device_t bus)
{
	device_t lowest;
	device_t *devlist;
	int i, error, devcount, lowest_func, lowest_pos, iov_pos, dev_func;
	uint16_t iov_ctl;

	/* If ARI is disabled on the downstream port there is nothing to do. */
	if (!PCIB_ARI_ENABLED(device_get_parent(bus)))
		return (0);

	error = device_get_children(bus, &devlist, &devcount);

	if (error != 0)
		return (error);

	lowest = NULL;
	for (i = 0; i < devcount; i++) {
		if (pci_find_extcap(devlist[i], PCIZ_SRIOV, &iov_pos) == 0) {
			dev_func = pci_get_function(devlist[i]);
			if (lowest == NULL || dev_func < lowest_func) {
				lowest = devlist[i];
				lowest_func = dev_func;
				lowest_pos = iov_pos;
			}
		}
	}
	free(devlist, M_TEMP);

	/*
	 * If we called this function some device must have the SR-IOV
	 * capability.
	 */
	KASSERT(lowest != NULL,
	    ("Could not find child of %s with SR-IOV capability",
	    device_get_nameunit(bus)));

	iov_ctl = pci_read_config(lowest, lowest_pos + PCIR_SRIOV_CTL, 2);
	iov_ctl |= PCIM_SRIOV_ARI_EN;
	pci_write_config(lowest, lowest_pos + PCIR_SRIOV_CTL, iov_ctl, 2);
	if ((pci_read_config(lowest, lowest_pos + PCIR_SRIOV_CTL, 2) &
	    PCIM_SRIOV_ARI_EN) == 0) {
		device_printf(lowest, "failed to enable ARI\n");
		return (ENXIO);
	}
	return (0);
}
static void
cxgb_controller_attach(device_t parent, device_t dev, void *context)
{
    device_t child;
    const struct adapter_info *ai;
    struct adapter *sc;
    struct pci_attach_args *pa = context;
    struct cxgb_attach_args cxgb_args;
    int locs[2];
    int i, error = 0;
    uint32_t vers;
    int port_qsets = 1;
    int reg;
#ifdef MSI_SUPPORTED
    int msi_needed;
#endif

    sc = device_private(dev);
    sc->dev = dev;
    memcpy(&sc->pa, pa, sizeof(struct pci_attach_args));
    sc->msi_count = 0;
    ai = cxgb_get_adapter_info(pa);

    /*
     * XXX not really related but a recent addition
     */
#ifdef MSI_SUPPORTED
    /* find the PCIe link width and set max read request to 4KB*/
    if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
        uint16_t lnk, pectl;
        lnk = pci_read_config(dev, reg + 0x12, 2);
        sc->link_width = (lnk >> 4) & 0x3f;

        pectl = pci_read_config(dev, reg + 0x8, 2);
        pectl = (pectl & ~0x7000) | (5 << 12);
        pci_write_config(dev, reg + 0x8, pectl, 2);
    }
/* Returns 1 if AGP or 0 if not. */
static int
drm_device_find_capability(struct drm_device *dev, int cap)
{
#if __FreeBSD_version >= 602102

	return (pci_find_extcap(dev->device, cap, NULL) == 0);
#else
	/* Code taken from agp.c.  IWBNI that was a public interface. */
	u_int32_t status;
	u_int8_t ptr, next;

	/*
	 * Check the CAP_LIST bit of the PCI status register first.
	 */
	status = pci_read_config(dev->device, PCIR_STATUS, 2);
	if (!(status & 0x10))
		return 0;

	/*
	 * Traverse the capabilities list.
	 */
	for (ptr = pci_read_config(dev->device, AGP_CAPPTR, 1);
	     ptr != 0;
	     ptr = next) {
		u_int32_t capid = pci_read_config(dev->device, ptr, 4);
		next = AGP_CAPID_GET_NEXT_PTR(capid);

		/*
		 * If this capability entry ID is cap, then we are done.
		 */
		if (AGP_CAPID_GET_CAP_ID(capid) == cap)
			return 1;
	}

	return 0;
#endif
}
Exemple #10
0
int
pci_iov_attach_method(device_t bus, device_t dev, nvlist_t *pf_schema,
    nvlist_t *vf_schema)
{
	device_t pcib;
	struct pci_devinfo *dinfo;
	struct pcicfg_iov *iov;
	nvlist_t *schema;
	uint32_t version;
	int error;
	int iov_pos;

	dinfo = device_get_ivars(dev);
	pcib = device_get_parent(bus);
	schema = NULL;
	
	error = pci_find_extcap(dev, PCIZ_SRIOV, &iov_pos);

	if (error != 0)
		return (error);

	version = pci_read_config(dev, iov_pos, 4); 
	if (PCI_EXTCAP_VER(version) != 1) {
		if (bootverbose)
			device_printf(dev, 
			    "Unsupported version of SR-IOV (%d) detected\n",
			    PCI_EXTCAP_VER(version));

		return (ENXIO);
	}

	iov = malloc(sizeof(*dinfo->cfg.iov), M_SRIOV, M_WAITOK | M_ZERO);

	mtx_lock(&Giant);
	if (dinfo->cfg.iov != NULL) {
		error = EBUSY;
		goto cleanup;
	}
	iov->iov_pos = iov_pos;

	schema = pci_iov_build_schema(&pf_schema, &vf_schema);
	if (schema == NULL) {
		error = ENOMEM;
		goto cleanup;
	}

	error = pci_iov_validate_schema(schema);
	if (error != 0)
		goto cleanup;
	iov->iov_schema = schema;

	iov->iov_cdev = make_dev(&iov_cdevsw, device_get_unit(dev),
	    UID_ROOT, GID_WHEEL, 0600, "iov/%s", device_get_nameunit(dev));

	if (iov->iov_cdev == NULL) {
		error = ENOMEM;
		goto cleanup;
	}
	
	dinfo->cfg.iov = iov;
	iov->iov_cdev->si_drv1 = dinfo;
	mtx_unlock(&Giant);

	return (0);

cleanup:
	nvlist_destroy(schema);
	nvlist_destroy(pf_schema);
	nvlist_destroy(vf_schema);
	free(iov, M_SRIOV);
	mtx_unlock(&Giant);
	return (error);
}
Exemple #11
0
/* Returns 1 if AGP or 0 if not. */
static int
drm_device_find_capability(struct drm_device *dev, int cap)
{
	return (pci_find_extcap(dev->device, cap, NULL) == 0);
}