Esempio n. 1
0
/**
 * Remove device
 *
 * @v func		USB function
 */
static void smsc95xx_remove ( struct usb_function *func ) {
	struct net_device *netdev = usb_func_get_drvdata ( func );

	unregister_netdev ( netdev );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Esempio n. 2
0
/**
 * Detach driver from device
 *
 * @v efidev		EFI device
  */
void snpnet_stop ( struct efi_device *efidev ) {
    EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
    struct net_device *netdev = efidev_get_drvdata ( efidev );
    struct snp_nic *snp = netdev->priv;
    EFI_HANDLE device = efidev->device;
    EFI_STATUS efirc;
    int rc;

    /* Unregister network device */
    unregister_netdev ( netdev );

    /* Stop SNP protocol */
    if ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) {
        rc = -EEFI ( efirc );
        DBGC ( device, "SNP %s could not stop: %s\n",
               efi_handle_name ( device ), strerror ( rc ) );
        /* Nothing we can do about this */
    }

    /* Free network device */
    list_del ( &snp->dev.siblings );
    netdev_nullify ( netdev );
    netdev_put ( netdev );

    /* Close SNP protocol */
    bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
                        efi_image_handle, device );
}
Esempio n. 3
0
/** Remove the device */
static void af_packet_nic_remove ( struct linux_device *device )
{
	struct net_device *netdev = linux_get_drvdata(device);
	unregister_netdev(netdev);
	netdev_nullify(netdev);
	netdev_put(netdev);
}
Esempio n. 4
0
/**
 * Probe PCI device
 *
 * @v pci		PCI device
 * @ret rc		Return status code
 */
static int intelx_probe ( struct pci_device *pci ) {
	struct net_device *netdev;
	struct intel_nic *intel;
	int rc;

	/* Allocate and initialise net device */
	netdev = alloc_etherdev ( sizeof ( *intel ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &intelx_operations );
	intel = netdev->priv;
	pci_set_drvdata ( pci, netdev );
	netdev->dev = &pci->dev;
	memset ( intel, 0, sizeof ( *intel ) );
	intel->port = PCI_FUNC ( pci->busdevfn );
	intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELX_TD );
	intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELX_RD );

	/* Fix up PCI device */
	adjust_pci_device ( pci );

	/* Map registers */
	intel->regs = ioremap ( pci->membase, INTEL_BAR_SIZE );
	if ( ! intel->regs ) {
		rc = -ENODEV;
		goto err_ioremap;
	}

	/* Reset the NIC */
	if ( ( rc = intelx_reset ( intel ) ) != 0 )
		goto err_reset;

	/* Fetch MAC address */
	if ( ( rc = intelx_fetch_mac ( intel, netdev->hw_addr ) ) != 0 )
		goto err_fetch_mac;

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register_netdev;

	/* Set initial link state */
	intelx_check_link ( netdev );

	return 0;

	unregister_netdev ( netdev );
 err_register_netdev:
 err_fetch_mac:
	intelx_reset ( intel );
 err_reset:
	iounmap ( intel->regs );
 err_ioremap:
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}
Esempio n. 5
0
/**
 * Probe PCI device
 *
 * @v pci		PCI device
 * @ret rc		Return status code
 */
static int skeleton_probe ( struct pci_device *pci ) {
	struct net_device *netdev;
	struct skeleton_nic *skel;
	int rc;

	/* Allocate and initialise net device */
	netdev = alloc_etherdev ( sizeof ( *skel ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &skeleton_operations );
	skel = netdev->priv;
	pci_set_drvdata ( pci, netdev );
	netdev->dev = &pci->dev;
	memset ( skel, 0, sizeof ( *skel ) );

	/* Fix up PCI device */
	adjust_pci_device ( pci );

	/* Map registers */
	skel->regs = ioremap ( pci->membase, SKELETON_BAR_SIZE );

	/* Reset the NIC */
	if ( ( rc = skeleton_reset ( skel ) ) != 0 )
		goto err_reset;

	/* Initialise and reset MII interface */
	mii_init ( &skel->mii, &skeleton_mii_operations );
	if ( ( rc = mii_reset ( &skel->mii ) ) != 0 ) {
		DBGC ( skel, "SKELETON %p could not reset MII: %s\n",
		       skel, strerror ( rc ) );
		goto err_mii_reset;
	}

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register_netdev;

	/* Set initial link state */
	skeleton_check_link ( netdev );

	return 0;

	unregister_netdev ( netdev );
 err_register_netdev:
 err_mii_reset:
	skeleton_reset ( skel );
 err_reset:
	iounmap ( skel->regs );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}
Esempio n. 6
0
/**
 * Remove device
 *
 * @v pci	PCI device
 */
static void b44_remove(struct pci_device *pci)
{
	struct net_device *netdev = pci_get_drvdata(pci);
	struct b44_private *bp = netdev_priv(netdev);

	ssb_core_disable(bp);
	unregister_netdev(netdev);
	iounmap(bp->regs);
	netdev_nullify(netdev);
	netdev_put(netdev);
}
Esempio n. 7
0
/** Handle a device request for the af_packet driver */
static int af_packet_nic_probe ( struct linux_device *device,
				 struct linux_device_request *request )
{
	struct linux_setting *if_setting;
	struct net_device *netdev;
	struct af_packet_nic *nic;
	int rc;

	netdev = alloc_etherdev(sizeof(*nic));
	if (! netdev)
		return -ENOMEM;

	netdev_init(netdev, &af_packet_nic_operations);
	nic = netdev->priv;
	linux_set_drvdata(device, netdev);
	netdev->dev = &device->dev;

	memset(nic, 0, sizeof(*nic));

	/* Look for the mandatory if setting */
	if_setting = linux_find_setting("if", &request->settings);

	/* No if setting */
	if (! if_setting) {
		printf("af_packet missing a mandatory if setting\n");
		rc = -EINVAL;
		goto err_settings;
	}

	nic->ifname = if_setting->value;
	snprintf ( device->dev.name, sizeof ( device->dev.name ), "%s",
		   nic->ifname );
	device->dev.desc.bus_type = BUS_TYPE_TAP;
	af_packet_update_properties(netdev);
	if_setting->applied = 1;

	/* Apply rest of the settings */
	linux_apply_settings(&request->settings, &netdev->settings.settings);

	/* Register network device */
	if ((rc = register_netdev(netdev)) != 0)
		goto err_register;

	netdev_link_up(netdev);

	return 0;

err_settings:
	unregister_netdev(netdev);
err_register:
	netdev_nullify(netdev);
	netdev_put(netdev);
	return rc;
}
Esempio n. 8
0
/**
 * Probe PCI device
 *
 * @v pci		PCI device
 * @ret rc		Return status code
 */
static int myson_probe ( struct pci_device *pci ) {
	struct net_device *netdev;
	struct myson_nic *myson;
	union myson_physical_address mac;
	int rc;

	/* Allocate and initialise net device */
	netdev = alloc_etherdev ( sizeof ( *myson ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &myson_operations );
	myson = netdev->priv;
	pci_set_drvdata ( pci, netdev );
	netdev->dev = &pci->dev;
	memset ( myson, 0, sizeof ( *myson ) );
	myson_init_ring ( &myson->tx, MYSON_NUM_TX_DESC, MYSON_TXLBA );
	myson_init_ring ( &myson->rx, MYSON_NUM_RX_DESC, MYSON_RXLBA );

	/* Fix up PCI device */
	adjust_pci_device ( pci );

	/* Map registers */
	myson->regs = ioremap ( pci->membase, MYSON_BAR_SIZE );

	/* Reset the NIC */
	if ( ( rc = myson_reset ( myson ) ) != 0 )
		goto err_reset;

	/* Read MAC address */
	mac.reg.low = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR0 ) );
	mac.reg.high = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR4 ) );
	memcpy ( netdev->hw_addr, mac.raw, ETH_ALEN );

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register_netdev;

	/* Mark as link up; we don't yet handle link state */
	netdev_link_up ( netdev );

	return 0;

	unregister_netdev ( netdev );
 err_register_netdev:
	myson_reset ( myson );
 err_reset:
	iounmap ( myson->regs );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}
Esempio n. 9
0
File: rhine.c Progetto: 42wim/ipxe
/**
 * Remove PCI device
 *
 * @v pci		PCI device
 */
static void rhine_remove ( struct pci_device *pci ) {
	struct net_device *netdev = pci_get_drvdata ( pci );
	struct rhine_nic *nic = netdev->priv;

	/* Unregister network device */
	unregister_netdev ( netdev );

	/* Reset card */
	rhine_reset ( nic );

	/* Free network device */
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Esempio n. 10
0
/**
 * Remove PCI device
 *
 * @v pci		PCI device
 */
static void myson_remove ( struct pci_device *pci ) {
	struct net_device *netdev = pci_get_drvdata ( pci );
	struct myson_nic *myson = netdev->priv;

	/* Unregister network device */
	unregister_netdev ( netdev );

	/* Reset card */
	myson_reset ( myson );

	/* Free network device */
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Esempio n. 11
0
/**
 * Remove PCI device
 *
 * @v pci		PCI device
 */
static void skeleton_remove ( struct pci_device *pci ) {
	struct net_device *netdev = pci_get_drvdata ( pci );
	struct skeleton_nic *skel = netdev->priv;

	/* Unregister network device */
	unregister_netdev ( netdev );

	/* Reset card */
	skeleton_reset ( skel );

	/* Free network device */
	iounmap ( skel->regs );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Esempio n. 12
0
/**
 * Remove Xen device
 *
 * @v xendev		Xen device
 */
static void netfront_remove ( struct xen_device *xendev ) {
	struct net_device *netdev = xen_get_drvdata ( xendev );
	struct netfront_nic *netfront = netdev->priv;
	struct xen_hypervisor *xen = xendev->xen;

	/* Unregister network device */
	unregister_netdev ( netdev );

	/* Free resources */
	xengrant_free ( xen, netfront->refs, NETFRONT_REF_COUNT );

	/* Free network device */
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Esempio n. 13
0
/**
 * Remove PCI device
 *
 * @v pci		PCI device
 */
static void intelxvf_remove ( struct pci_device *pci ) {
	struct net_device *netdev = pci_get_drvdata ( pci );
	struct intel_nic *intel = netdev->priv;

	/* Unregister network device */
	unregister_netdev ( netdev );

	/* Reset the NIC */
	intelxvf_reset ( intel );

	/* Free network device */
	iounmap ( intel->regs );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Esempio n. 14
0
/**
 * e1000e_remove - Device Removal Routine
 *
 * @v pdev PCI device information struct
 *
 **/
void e1000e_remove ( struct pci_device *pdev )
{
	struct net_device *netdev = pci_get_drvdata ( pdev );
	struct e1000_adapter *adapter = netdev_priv ( netdev );

	DBGP ( "e1000e_remove\n" );

	if ( adapter->hw.flash_address )
		iounmap ( adapter->hw.flash_address );
	if  ( adapter->hw.hw_addr )
		iounmap ( adapter->hw.hw_addr );

	unregister_netdev ( netdev );
	e1000e_reset  ( adapter );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Esempio n. 15
0
/**
 * Remove PCI device
 *
 * @v pci		PCI device
 */
static void intelxlvf_remove ( struct pci_device *pci ) {
	struct net_device *netdev = pci_get_drvdata ( pci );
	struct intelxl_nic *intelxl = netdev->priv;

	/* Unregister network device */
	unregister_netdev ( netdev );

	/* Reset the function via admin queue */
	intelxlvf_reset_admin ( intelxl );

	/* Close admin queues */
	intelxl_close_admin ( intelxl );

	/* Disable MSI-X dummy interrupt */
	intelxl_msix_disable ( intelxl, pci );

	/* Reset the function via PCIe FLR */
	intelxlvf_reset_flr ( intelxl, pci );

	/* Free network device */
	iounmap ( intelxl->regs );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Esempio n. 16
0
File: nii.c Progetto: baloo/ipxe
/**
 * Detach driver from device
 *
 * @v efidev		EFI device
 */
void nii_stop ( struct efi_device *efidev ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	struct net_device *netdev = efidev_get_drvdata ( efidev );
	struct nii_nic *nii = netdev->priv;
	EFI_HANDLE device = efidev->device;

	/* Unregister network device */
	unregister_netdev ( netdev );

	/* Stop UNDI */
	nii_stop_undi ( nii );

	/* Close PCI I/O protocols */
	nii_pci_close ( nii );

	/* Close NII protocol */
	bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
			    efi_image_handle, device );

	/* Free network device */
	list_del ( &nii->dev.siblings );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Esempio n. 17
0
/**
 * Probe device
 *
 * @v func		USB function
 * @v config		Configuration descriptor
 * @ret rc		Return status code
 */
static int dm96xx_probe ( struct usb_function *func,
		       struct usb_configuration_descriptor *config ) {
	struct usb_device *usb = func->usb;
	struct net_device *netdev;
	struct dm96xx_device *dm96xx;
	int rc;

	/* Allocate and initialise structure */
	netdev = alloc_etherdev ( sizeof ( *dm96xx ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &dm96xx_operations );
	netdev->dev = &func->dev;
	dm96xx = netdev->priv;
	memset ( dm96xx, 0, sizeof ( *dm96xx ) );
	dm96xx->usb = usb;
	dm96xx->bus = usb->port->hub->bus;
	dm96xx->netdev = netdev;
	usbnet_init ( &dm96xx->usbnet, func, &dm96xx_intr_operations,
		      &dm96xx_in_operations, &dm96xx_out_operations );
	usb_refill_init ( &dm96xx->usbnet.intr, 0, DM96XX_INTR_MAX_FILL );
	usb_refill_init ( &dm96xx->usbnet.in, DM96XX_IN_MTU,
			  DM96XX_IN_MAX_FILL );
	DBGC ( dm96xx, "DM96XX %p on %s\n", dm96xx, func->name );

	/* Describe USB network device */
	if ( ( rc = usbnet_describe ( &dm96xx->usbnet, config ) ) != 0 ) {
		DBGC ( dm96xx, "DM96XX %p could not describe: %s\n",
		       dm96xx, strerror ( rc ) );
		goto err_describe;
	}

	/* Reset device */
	if ( ( rc = dm96xx_reset ( dm96xx ) ) != 0 )
		goto err_reset;

	/* Read MAC address */
	if ( ( rc = dm96xx_read_mac ( dm96xx, netdev->hw_addr ) ) != 0 )
		goto err_read_mac;

	/* Get initial link status */
	if ( ( rc = dm96xx_check_link ( dm96xx ) ) != 0 )
		goto err_check_link;

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register;

	usb_func_set_drvdata ( func, netdev );
	return 0;

	unregister_netdev ( netdev );
 err_register:
 err_check_link:
 err_read_mac:
 err_reset:
 err_describe:
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}
Esempio n. 18
0
File: rhine.c Progetto: 42wim/ipxe
/**
 * Probe PCI device
 *
 * @v pci		PCI device
 * @ret rc		Return status code
 */
static int rhine_probe ( struct pci_device *pci ) {
	struct net_device *netdev;
	struct rhine_nic *rhn;
	uint8_t revision;
	unsigned int i;
	int rc;

	/* Allocate and initialise net device */
	netdev = alloc_etherdev ( sizeof ( *rhn ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &rhine_operations );
	rhn = netdev->priv;
	pci_set_drvdata ( pci, netdev );
	netdev->dev = &pci->dev;
	memset ( rhn, 0, sizeof ( *rhn ) );
	rhine_init_ring ( &rhn->tx, RHINE_TXDESC_NUM, RHINE_TXQUEUE_BASE );
	rhine_init_ring ( &rhn->rx, RHINE_RXDESC_NUM, RHINE_RXQUEUE_BASE );

	/* Fix up PCI device */
	adjust_pci_device ( pci );

	/* Map registers */
	rhn->regs = ioremap ( pci->membase, RHINE_BAR_SIZE );
	rhn->ioaddr = pci->ioaddr;
	DBGC ( rhn, "RHINE %p regs at %08lx, I/O at %04lx\n", rhn,
	       pci->membase, pci->ioaddr );

	/* Reset the NIC */
	if ( ( rc = rhine_reset ( rhn ) ) != 0 )
		goto err_reset;

	/* Reload EEPROM */
	if ( ( rc = rhine_reload_eeprom ( rhn ) ) != 0 )
		goto err_reload_eeprom;

	/* Read card revision and enable MMIO */
	pci_read_config_byte ( pci, PCI_REVISION, &revision );
	DBGC ( rhn, "RHINE %p revision %#02x detected\n", rhn, revision );
	rhine_enable_mmio ( rhn, revision );

	/* Read MAC address */
	for ( i = 0 ; i < ETH_ALEN ; i++ )
		netdev->hw_addr[i] = readb ( rhn->regs + RHINE_MAC + i );

	/* Initialise and reset MII interface */
	mii_init ( &rhn->mii, &rhine_mii_operations );
	if ( ( rc = mii_reset ( &rhn->mii ) ) != 0 ) {
		DBGC ( rhn, "RHINE %p could not reset MII: %s\n",
		       rhn, strerror ( rc ) );
		goto err_mii_reset;
	}
	DBGC ( rhn, "RHINE PHY vendor %04x device %04x\n",
	       rhine_mii_read ( &rhn->mii, 0x02 ),
	       rhine_mii_read ( &rhn->mii, 0x03 ) );

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register_netdev;

	/* Set initial link state */
	rhine_check_link ( netdev );

	return 0;

 err_register_netdev:
 err_mii_reset:
 err_reload_eeprom:
	rhine_reset ( rhn );
 err_reset:
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}
Esempio n. 19
0
/**
 * Probe Xen device
 *
 * @v xendev		Xen device
 * @ret rc		Return status code
 */
static int netfront_probe ( struct xen_device *xendev ) {
	struct xen_hypervisor *xen = xendev->xen;
	struct net_device *netdev;
	struct netfront_nic *netfront;
	int rc;

	/* Allocate and initialise structure */
	netdev = alloc_etherdev ( sizeof ( *netfront ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &netfront_operations );
	netdev->dev = &xendev->dev;
	netfront = netdev->priv;
	netfront->xendev = xendev;
	DBGC ( netfront, "NETFRONT %s backend=\"%s\" in domain %ld\n",
	       xendev->key, xendev->backend, xendev->backend_id );

	/* Allocate grant references and initialise descriptor rings */
	if ( ( rc = xengrant_alloc ( xen, netfront->refs,
				     NETFRONT_REF_COUNT ) ) != 0 ) {
		DBGC ( netfront, "NETFRONT %s could not allocate grant "
		       "references: %s\n", xendev->key, strerror ( rc ) );
		goto err_grant_alloc;
	}
	netfront_init_ring ( &netfront->tx, "tx-ring-ref",
			     netfront->refs[NETFRONT_REF_TX_RING],
			     NETFRONT_NUM_TX_DESC, netfront->tx_iobufs,
			     &netfront->refs[NETFRONT_REF_TX_BASE],
			     netfront->tx_ids );
	netfront_init_ring ( &netfront->rx, "rx-ring-ref",
			     netfront->refs[NETFRONT_REF_RX_RING],
			     NETFRONT_NUM_RX_DESC, netfront->rx_iobufs,
			     &netfront->refs[NETFRONT_REF_RX_BASE],
			     netfront->rx_ids );

	/* Fetch MAC address */
	if ( ( rc = netfront_read_mac ( netfront, netdev->hw_addr ) ) != 0 )
		goto err_read_mac;

	/* Reset device.  Ignore failures; allow the device to be
	 * registered so that reset errors can be observed by the user
	 * when attempting to open the device.
	 */
	netfront_reset ( netfront );

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register_netdev;

	/* Set initial link state */
	netdev_link_down ( netdev );

	xen_set_drvdata ( xendev, netdev );
	return 0;

	unregister_netdev ( netdev );
 err_register_netdev:
 err_read_mac:
	xengrant_free ( xen, netfront->refs, NETFRONT_REF_COUNT );
 err_grant_alloc:
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}
Esempio n. 20
0
/**
 * Attach driver to device
 *
 * @v efidev		EFI device
 * @ret rc		Return status code
 */
int snpnet_start ( struct efi_device *efidev ) {
    EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
    EFI_HANDLE device = efidev->device;
    EFI_SIMPLE_NETWORK_MODE *mode;
    struct net_device *netdev;
    struct snp_nic *snp;
    void *interface;
    EFI_STATUS efirc;
    int rc;

    /* Open SNP protocol */
    if ( ( efirc = bs->OpenProtocol ( device,
                                      &efi_simple_network_protocol_guid,
                                      &interface, efi_image_handle, device,
                                      ( EFI_OPEN_PROTOCOL_BY_DRIVER |
                                        EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0) {
        rc = -EEFI ( efirc );
        DBGC ( device, "SNP %s cannot open SNP protocol: %s\n",
               efi_handle_name ( device ), strerror ( rc ) );
        DBGC_EFI_OPENERS ( device, device,
                           &efi_simple_network_protocol_guid );
        goto err_open_protocol;
    }

    /* Allocate and initialise structure */
    netdev = alloc_etherdev ( sizeof ( *snp ) );
    if ( ! netdev ) {
        rc = -ENOMEM;
        goto err_alloc;
    }
    netdev_init ( netdev, &snpnet_operations );
    snp = netdev->priv;
    snp->efidev = efidev;
    snp->snp = interface;
    mode = snp->snp->Mode;
    efidev_set_drvdata ( efidev, netdev );

    /* Populate underlying device information */
    efi_device_info ( device, "SNP", &snp->dev );
    snp->dev.driver_name = "SNP";
    snp->dev.parent = &efidev->dev;
    list_add ( &snp->dev.siblings, &efidev->dev.children );
    INIT_LIST_HEAD ( &snp->dev.children );
    netdev->dev = &snp->dev;

    /* Bring to the Started state */
    if ( ( mode->State == EfiSimpleNetworkStopped ) &&
            ( ( efirc = snp->snp->Start ( snp->snp ) ) != 0 ) ) {
        rc = -EEFI ( efirc );
        DBGC ( device, "SNP %s could not start: %s\n",
               efi_handle_name ( device ), strerror ( rc ) );
        goto err_start;
    }
    if ( ( mode->State == EfiSimpleNetworkInitialized ) &&
            ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
        rc = -EEFI ( efirc );
        DBGC ( device, "SNP %s could not shut down: %s\n",
               efi_handle_name ( device ), strerror ( rc ) );
        goto err_shutdown;
    }

    /* Populate network device parameters */
    if ( mode->HwAddressSize != netdev->ll_protocol->hw_addr_len ) {
        DBGC ( device, "SNP %s has invalid hardware address length "
               "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
        rc = -ENOTSUP;
        goto err_hw_addr_len;
    }
    memcpy ( netdev->hw_addr, &mode->PermanentAddress,
             netdev->ll_protocol->hw_addr_len );
    if ( mode->HwAddressSize != netdev->ll_protocol->ll_addr_len ) {
        DBGC ( device, "SNP %s has invalid link-layer address length "
               "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
        rc = -ENOTSUP;
        goto err_ll_addr_len;
    }
    memcpy ( netdev->ll_addr, &mode->CurrentAddress,
             netdev->ll_protocol->ll_addr_len );
    snp->mtu = ( snp->snp->Mode->MaxPacketSize +
                 snp->snp->Mode->MediaHeaderSize );

    /* Register network device */
    if ( ( rc = register_netdev ( netdev ) ) != 0 )
        goto err_register_netdev;
    DBGC ( device, "SNP %s registered as %s\n",
           efi_handle_name ( device ), netdev->name );

    /* Set initial link state */
    if ( snp->snp->Mode->MediaPresentSupported ) {
        snpnet_check_link ( netdev );
    } else {
        netdev_link_up ( netdev );
    }

    return 0;

    unregister_netdev ( netdev );
err_register_netdev:
err_ll_addr_len:
err_hw_addr_len:
err_shutdown:
err_start:
    list_del ( &snp->dev.siblings );
    netdev_nullify ( netdev );
    netdev_put ( netdev );
err_alloc:
    bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
                        efi_image_handle, device );
err_open_protocol:
    return rc;
}
Esempio n. 21
0
/**
 * Probe PCI device
 *
 * @v pci		PCI device
 * @ret rc		Return status code
 */
static int intelxlvf_probe ( struct pci_device *pci ) {
	struct net_device *netdev;
	struct intelxl_nic *intelxl;
	int rc;

	/* Allocate and initialise net device */
	netdev = alloc_etherdev ( sizeof ( *intelxl ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &intelxlvf_operations );
	intelxl = netdev->priv;
	pci_set_drvdata ( pci, netdev );
	netdev->dev = &pci->dev;
	memset ( intelxl, 0, sizeof ( *intelxl ) );
	intelxl->intr = INTELXLVF_VFINT_DYN_CTL0;
	intelxl_init_admin ( &intelxl->command, INTELXLVF_ADMIN,
			     &intelxlvf_admin_command_offsets );
	intelxl_init_admin ( &intelxl->event, INTELXLVF_ADMIN,
			     &intelxlvf_admin_event_offsets );
	intelxlvf_init_ring ( &intelxl->tx, INTELXL_TX_NUM_DESC,
			      sizeof ( intelxl->tx.desc.tx[0] ),
			      INTELXLVF_QTX_TAIL );
	intelxlvf_init_ring ( &intelxl->rx, INTELXL_RX_NUM_DESC,
			      sizeof ( intelxl->rx.desc.rx[0] ),
			      INTELXLVF_QRX_TAIL );

	/* Fix up PCI device */
	adjust_pci_device ( pci );

	/* Map registers */
	intelxl->regs = ioremap ( pci->membase, INTELXLVF_BAR_SIZE );
	if ( ! intelxl->regs ) {
		rc = -ENODEV;
		goto err_ioremap;
	}

	/* Locate PCI Express capability */
	intelxl->exp = pci_find_capability ( pci, PCI_CAP_ID_EXP );
	if ( ! intelxl->exp ) {
		DBGC ( intelxl, "INTELXL %p missing PCIe capability\n",
		       intelxl );
		rc = -ENXIO;
		goto err_exp;
	}

	/* Reset the function via PCIe FLR */
	intelxlvf_reset_flr ( intelxl, pci );

	/* Enable MSI-X dummy interrupt */
	if ( ( rc = intelxl_msix_enable ( intelxl, pci ) ) != 0 )
		goto err_msix;

	/* Open admin queues */
	if ( ( rc = intelxl_open_admin ( intelxl ) ) != 0 )
		goto err_open_admin;

	/* Reset the function via admin queue */
	if ( ( rc = intelxlvf_reset_admin ( intelxl ) ) != 0 )
		goto err_reset_admin;

	/* Get MAC address */
	if ( ( rc = intelxlvf_admin_get_resources ( netdev ) ) != 0 )
		goto err_get_resources;

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register_netdev;

	return 0;

	unregister_netdev ( netdev );
 err_register_netdev:
 err_get_resources:
 err_reset_admin:
	intelxl_close_admin ( intelxl );
 err_open_admin:
	intelxl_msix_disable ( intelxl, pci );
 err_msix:
	intelxlvf_reset_flr ( intelxl, pci );
 err_exp:
	iounmap ( intelxl->regs );
 err_ioremap:
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}
Esempio n. 22
0
/**
 * Probe PCI device
 *
 * @v pci		PCI device
 * @ret rc		Return status code
 */
static int intelxvf_probe ( struct pci_device *pci ) {
	struct net_device *netdev;
	struct intel_nic *intel;
	int rc;

	/* Allocate and initialise net device */
	netdev = alloc_etherdev ( sizeof ( *intel ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &intelxvf_operations );
	intel = netdev->priv;
	pci_set_drvdata ( pci, netdev );
	netdev->dev = &pci->dev;
	memset ( intel, 0, sizeof ( *intel ) );
	intel_init_mbox ( &intel->mbox, INTELXVF_MBCTRL, INTELXVF_MBMEM );
	intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELXVF_TD(0),
			  intel_describe_tx_adv );
	intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELXVF_RD(0),
			  intel_describe_rx );

	/* Fix up PCI device */
	adjust_pci_device ( pci );

	/* Map registers */
	intel->regs = ioremap ( pci->membase, INTELVF_BAR_SIZE );
	if ( ! intel->regs ) {
		rc = -ENODEV;
		goto err_ioremap;
	}

	/* Reset the function */
	intelxvf_reset ( intel );

	/* Send reset message and fetch MAC address */
	if ( ( rc = intelvf_mbox_reset ( intel, netdev->hw_addr ) ) != 0 ) {
		DBGC ( intel, "INTEL %p could not reset and fetch MAC: %s\n",
		       intel, strerror ( rc ) );
		goto err_mbox_reset;
	}

	/* Reset the function (since we will not respond to Control
	 * ("ping") mailbox messages until the network device is opened.
	 */
	intelxvf_reset ( intel );

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register_netdev;

	/* Set initial link state */
	intelxvf_check_link ( netdev );

	return 0;

	unregister_netdev ( netdev );
 err_register_netdev:
 err_mbox_reset:
	intelxvf_reset ( intel );
	iounmap ( intel->regs );
 err_ioremap:
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}
Esempio n. 23
0
/**
 * Probe device
 *
 * @v func		USB function
 * @v config		Configuration descriptor
 * @ret rc		Return status code
 */
static int smsc95xx_probe ( struct usb_function *func,
			    struct usb_configuration_descriptor *config ) {
	struct usb_device *usb = func->usb;
	struct net_device *netdev;
	struct smsc95xx_device *smsc95xx;
	int rc;

	/* Allocate and initialise structure */
	netdev = alloc_etherdev ( sizeof ( *smsc95xx ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &smsc95xx_operations );
	netdev->dev = &func->dev;
	smsc95xx = netdev->priv;
	memset ( smsc95xx, 0, sizeof ( *smsc95xx ) );
	smsc95xx->usb = usb;
	smsc95xx->bus = usb->port->hub->bus;
	smsc95xx->netdev = netdev;
	usbnet_init ( &smsc95xx->usbnet, func, &smsc95xx_intr_operations,
		      &smsc95xx_in_operations, &smsc95xx_out_operations );
	usb_refill_init ( &smsc95xx->usbnet.intr, 0, 0,
			  SMSC95XX_INTR_MAX_FILL );
	usb_refill_init ( &smsc95xx->usbnet.in,
			  ( sizeof ( struct smsc95xx_tx_header ) -
			    sizeof ( struct smsc95xx_rx_header ) ),
			  SMSC95XX_IN_MTU, SMSC95XX_IN_MAX_FILL );
	mii_init ( &smsc95xx->mii, &smsc95xx_mii_operations );
	DBGC ( smsc95xx, "SMSC95XX %p on %s\n", smsc95xx, func->name );

	/* Describe USB network device */
	if ( ( rc = usbnet_describe ( &smsc95xx->usbnet, config ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not describe: %s\n",
		       smsc95xx, strerror ( rc ) );
		goto err_describe;
	}

	/* Reset device */
	if ( ( rc = smsc95xx_reset ( smsc95xx ) ) != 0 )
		goto err_reset;

	/* Read MAC address */
	if ( ( rc = smsc95xx_fetch_mac ( smsc95xx, netdev->hw_addr ) ) != 0 )
		goto err_fetch_mac;

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register;

	usb_func_set_drvdata ( func, netdev );
	return 0;

	unregister_netdev ( netdev );
 err_register:
 err_fetch_mac:
 err_reset:
 err_describe:
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}
Esempio n. 24
0
File: nii.c Progetto: baloo/ipxe
/**
 * Attach driver to device
 *
 * @v efidev		EFI device
 * @ret rc		Return status code
 */
int nii_start ( struct efi_device *efidev ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	EFI_HANDLE device = efidev->device;
	struct net_device *netdev;
	struct nii_nic *nii;
	void *interface;
	EFI_STATUS efirc;
	int rc;

	/* Allocate and initialise structure */
	netdev = alloc_netdev ( sizeof ( *nii ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &nii_operations );
	nii = netdev->priv;
	nii->efidev = efidev;
	netdev->ll_broadcast = nii->broadcast;
	efidev_set_drvdata ( efidev, netdev );

	/* Populate underlying device information */
	efi_device_info ( device, "NII", &nii->dev );
	nii->dev.driver_name = "NII";
	nii->dev.parent = &efidev->dev;
	list_add ( &nii->dev.siblings, &efidev->dev.children );
	INIT_LIST_HEAD ( &nii->dev.children );
	netdev->dev = &nii->dev;

	/* Open NII protocol */
	if ( ( efirc = bs->OpenProtocol ( device, &efi_nii31_protocol_guid,
					  &interface, efi_image_handle, device,
					  ( EFI_OPEN_PROTOCOL_BY_DRIVER |
					    EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
		rc = -EEFI ( efirc );
		DBGC ( nii, "NII %s cannot open NII protocol: %s\n",
		       nii->dev.name, strerror ( rc ) );
		DBGC_EFI_OPENERS ( device, device, &efi_nii31_protocol_guid );
		goto err_open_protocol;
	}
	nii->nii = interface;

	/* Locate UNDI and entry point */
	nii->undi = ( ( void * ) ( intptr_t ) nii->nii->Id );
	if ( ! nii->undi ) {
		DBGC ( nii, "NII %s has no UNDI\n", nii->dev.name );
		rc = -ENODEV;
		goto err_no_undi;
	}
	if ( nii->undi->Implementation & PXE_ROMID_IMP_HW_UNDI ) {
		DBGC ( nii, "NII %s is a mythical hardware UNDI\n",
		       nii->dev.name );
		rc = -ENOTSUP;
		goto err_hw_undi;
	}
	if ( nii->undi->Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR ) {
		nii->issue = ( ( void * ) ( intptr_t ) nii->undi->EntryPoint );
	} else {
		nii->issue = ( ( ( void * ) nii->undi ) +
			       nii->undi->EntryPoint );
	}
	DBGC ( nii, "NII %s using UNDI v%x.%x at %p entry %p\n", nii->dev.name,
	       nii->nii->MajorVer, nii->nii->MinorVer, nii->undi, nii->issue );

	/* Open PCI I/O protocols and locate BARs */
	if ( ( rc = nii_pci_open ( nii ) ) != 0 )
		goto err_pci_open;

	/* Start UNDI */
	if ( ( rc = nii_start_undi ( nii ) ) != 0 )
		goto err_start_undi;

	/* Get initialisation information */
	if ( ( rc = nii_get_init_info ( nii, netdev ) ) != 0 )
		goto err_get_init_info;

	/* Get MAC addresses */
	if ( ( rc = nii_get_station_address ( nii, netdev ) ) != 0 )
		goto err_get_station_address;

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register_netdev;
	DBGC ( nii, "NII %s registered as %s for %p %s\n", nii->dev.name,
	       netdev->name, device, efi_handle_name ( device ) );

	/* Set initial link state (if media detection is not supported) */
	if ( ! nii->media )
		netdev_link_up ( netdev );

	return 0;

	unregister_netdev ( netdev );
 err_register_netdev:
 err_get_station_address:
 err_get_init_info:
	nii_stop_undi ( nii );
 err_start_undi:
	nii_pci_close ( nii );
 err_pci_open:
 err_hw_undi:
 err_no_undi:
	bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
			    efi_image_handle, device );
 err_open_protocol:
	list_del ( &nii->dev.siblings );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}