Esempio n. 1
0
int main(int argc, char** argv){

    char buf[BUFLEN];
    char *dev = calloc(10, 1);

    struct netdev netdev;

    CLEAR(buf);

    tun_init(dev);
    netdev_init(&netdev, "10.0.0.4", "00:0c:29:6d:50:25");

    arp_init();

    while(1) {
        if (tun_read(buf, BUFLEN) < 0) {
            print_error("ERR: Read from tun_fd: %s\n", strerror(errno));
        }

        print_hexdump(buf, BUFLEN);

        struct eth_hdr *hdr = init_eth_hdr(buf);

        handle_frame(&netdev, hdr);
    }
}
Esempio n. 2
0
static struct vport *netdev_create(const struct vport_parms *parms)
{
    struct vport *vport;
    struct netdev_vport *netdev_vport;
    int err;

    vport = ovs_vport_alloc(sizeof(struct netdev_vport),
                            &ovs_netdev_vport_ops, parms);
    if (IS_ERR(vport)) {
        err = PTR_ERR(vport);
        goto error;
    }

    netdev_vport = netdev_vport_priv(vport);

    netdev_vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), parms->name);
    if (!netdev_vport->dev) {
        err = -ENODEV;
        goto error_free_vport;
    }

    if (netdev_vport->dev->flags & IFF_LOOPBACK ||
            netdev_vport->dev->type != ARPHRD_ETHER ||
            ovs_is_internal_dev(netdev_vport->dev)) {
        err = -EINVAL;
        goto error_put;
    }

    rtnl_lock();
    err = netdev_master_upper_dev_link(netdev_vport->dev,
                                       get_dpdev(vport->dp));
    if (err)
        goto error_unlock;

    err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook,
                                     vport);
    if (err)
        goto error_master_upper_dev_unlink;

    dev_set_promiscuity(netdev_vport->dev, 1);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
    dev_disable_lro(netdev_vport->dev);
#endif
    netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH;
    rtnl_unlock();

    netdev_init();
    return vport;

error_master_upper_dev_unlink:
    netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
error_unlock:
    rtnl_unlock();
error_put:
    dev_put(netdev_vport->dev);
error_free_vport:
    ovs_vport_free(vport);
error:
    return ERR_PTR(err);
}
Esempio n. 3
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. 4
0
void sock_init(void)
{
	struct socket *s = sockets;
	uint8_t n = 0;
	while (s < sockets + NSOCKET)
		(s++)->s_num = n++;
	netdev_init();
}
Esempio n. 5
0
void device_init(void)
{
  int i;
  zrtc_init();
  /* Add 64 swaps (4MB) to use the entire J drive */
  for (i = 0; i < MAX_SWAPS; i++)
    swapmap_add(i);
  netdev_init();
}
Esempio n. 6
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. 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
int uipdriver_init(void)
{
  /* Internal initalization */

  timer_set(&g_periodic_timer, 500);
  netdev_init();

  /* Register the device with the OS so that socket IOCTLs can be performed */

  (void)netdev_register(&g_sim_dev);
  return OK;
}
Esempio n. 10
0
int main(void) {
    tlsf_create_with_pool(_tlsf_heap, sizeof(_tlsf_heap));

    printf("%s started\n", APPLICATION_NAME);
    xtimer_init();
    msg_init_queue(main_msg_queue, MAIN_MSG_QUEUE_SIZE);
    netdev_init();
    stack_init();
    exp_run();
    printf("%s stopped\n", APPLICATION_NAME);
    return 0;
}
Esempio n. 11
0
int netdriver_init(void)
{
  /* Internal initalization */

  timer_set(&g_periodic_timer, 500);
  netdev_init();

  /* Set callbacks */

  g_sim_dev.d_buf    = g_pktbuf;         /* Single packet buffer */
  g_sim_dev.d_ifup   = netdriver_ifup;
  g_sim_dev.d_ifdown = netdriver_ifdown;

  /* Register the device with the OS so that socket IOCTLs can be performed */

  (void)netdev_register(&g_sim_dev, NET_LL_ETHERNET);
  return OK;
}
Esempio n. 12
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. 13
0
/**
 * e1000_probe - Initial configuration of e1000 NIC
 *
 * @v pci	PCI device
 * @v id	PCI IDs
 *
 * @ret rc	Return status code
 **/
int e1000_probe ( struct pci_device *pdev )
{
	int i, err;
	struct net_device *netdev;
	struct e1000_adapter *adapter;
	unsigned long mmio_start, mmio_len;

	DBG ( "e1000_probe\n" );

	err = -ENOMEM;

	/* Allocate net device ( also allocates memory for netdev->priv
	   and makes netdev-priv point to it ) */
	netdev = alloc_etherdev ( sizeof ( struct e1000_adapter ) );
	if ( ! netdev )
		goto err_alloc_etherdev;

	/* Associate e1000-specific network operations operations with
	 * generic network device layer */
	netdev_init ( netdev, &e1000_operations );

	/* Associate this network device with given PCI device */
	pci_set_drvdata ( pdev, netdev );
	netdev->dev = &pdev->dev;

	/* Initialize driver private storage */
	adapter = netdev_priv ( netdev );
        memset ( adapter, 0, ( sizeof ( *adapter ) ) );

	adapter->pdev       = pdev;

	adapter->ioaddr     = pdev->ioaddr;
        adapter->hw.io_base = pdev->ioaddr;

        adapter->irqno      = pdev->irq;
	adapter->netdev     = netdev;
	adapter->hw.back    = adapter;

	adapter->tx_ring_size = sizeof ( *adapter->tx_base ) * NUM_TX_DESC;
	adapter->rx_ring_size = sizeof ( *adapter->rx_base ) * NUM_RX_DESC;

	mmio_start = pci_bar_start ( pdev, PCI_BASE_ADDRESS_0 );
	mmio_len   = pci_bar_size  ( pdev, PCI_BASE_ADDRESS_0 );

	DBG ( "mmio_start: %#08lx\n", mmio_start );
	DBG ( "mmio_len: %#08lx\n", mmio_len );

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

	err = -EIO;

	adapter->hw.hw_addr = ioremap ( mmio_start, mmio_len );
	DBG ( "adapter->hw.hw_addr: %p\n", adapter->hw.hw_addr );

	if ( ! adapter->hw.hw_addr )
		goto err_ioremap;

	/* Hardware features, flags and workarounds */
	if (adapter->hw.mac.type >= e1000_82540) {
		adapter->flags |= E1000_FLAG_HAS_SMBUS;
		adapter->flags |= E1000_FLAG_HAS_INTR_MODERATION;
	}

	if (adapter->hw.mac.type == e1000_82543)
		adapter->flags |= E1000_FLAG_BAD_TX_CARRIER_STATS_FD;

	adapter->hw.phy.autoneg_wait_to_complete = true;
	adapter->hw.mac.adaptive_ifs = true;

	/* setup the private structure */
	if ( ( err = e1000_sw_init ( adapter ) ) )
		goto err_sw_init;

	if ((err = e1000_init_mac_params(&adapter->hw)))
		goto err_hw_init;

	if ((err = e1000_init_nvm_params(&adapter->hw)))
		goto err_hw_init;

        /* Force auto-negotiated speed and duplex */
        adapter->hw.mac.autoneg = 1;

	if ((err = e1000_init_phy_params(&adapter->hw)))
		goto err_hw_init;

	DBG ( "adapter->hw.mac.type: %#08x\n", adapter->hw.mac.type );

	/* before reading the EEPROM, reset the controller to
	 * put the device in a known good starting state
	 */
	err = e1000_reset_hw ( &adapter->hw );
	if ( err < 0 ) {
		DBG ( "Hardware Initialization Failed\n" );
		goto err_reset;
	}
	/* make sure the NVM is good */

	if ( e1000_validate_nvm_checksum(&adapter->hw) < 0 ) {
		DBG ( "The NVM Checksum Is Not Valid\n" );
		err = -EIO;
		goto err_eeprom;
	}

	/* copy the MAC address out of the EEPROM */
	if ( e1000_read_mac_addr ( &adapter->hw ) )
		DBG ( "EEPROM Read Error\n" );

        memcpy ( netdev->hw_addr, adapter->hw.mac.perm_addr, ETH_ALEN );

	/* reset the hardware with the new settings */
	e1000_reset ( adapter );

	if ( ( err = register_netdev ( netdev ) ) != 0)
		goto err_register;

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

	for (i = 0; i < 6; i++)
		DBG ("%02x%s", netdev->ll_addr[i], i == 5 ? "\n" : ":");

	DBG ( "e1000_probe succeeded!\n" );

	/* No errors, return success */
	return 0;

/* Error return paths */
err_reset:
err_register:
err_hw_init:
err_eeprom:
	if (!e1000_check_reset_block(&adapter->hw))
		e1000_phy_hw_reset(&adapter->hw);
	if (adapter->hw.flash_address)
		iounmap(adapter->hw.flash_address);
err_sw_init:
	iounmap ( adapter->hw.hw_addr );
err_ioremap:
	netdev_put ( netdev );
err_alloc_etherdev:
	return err;
}
Esempio n. 14
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. 15
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. 16
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. 17
0
/**
 * This is the architecture-independent kernel entry point. Before it is
 * called, architecture-specific code has done the bare minimum initialization
 * necessary. This function initializes the kernel and its various subsystems.
 * It calls back to architecture-specific code at several well defined points,
 * which all architectures must implement (e.g., setup_arch()).
 *
 * \callgraph
 */
void
start_kernel()
{
	unsigned int cpu;
	unsigned int timeout;
	int status;

	/*
 	 * Parse the kernel boot command line.
 	 * This is where boot-time configurable variables get set,
 	 * e.g., the ones with param() and DRIVER_PARAM() specifiers.
 	 */
	parse_params(lwk_command_line);

	/*
 	 * Initialize the console subsystem.
 	 * printk()'s will be visible after this.
 	 */
	console_init();

	/*
	 * Hello, Dave.
	 */
	printk("%s", lwk_banner);
	printk(KERN_DEBUG "%s\n", lwk_command_line);
	sort_exception_table();
	/*
	 * Do architecture specific initialization.
	 * This detects memory, CPUs, architecture dependent irqs, etc.
	 */
	setup_arch();

	/*
	 * Setup the architecture independent interrupt handling.
	 */
	irq_init();

	/*
	 * Initialize the kernel memory subsystem. Up until now, the simple
	 * boot-time memory allocator (bootmem) has been used for all dynamic
	 * memory allocation. Here, the bootmem allocator is destroyed and all
	 * of the free pages it was managing are added to the kernel memory
	 * pool (kmem) or the user memory pool (umem).
	 *
	 * After this point, any use of the bootmem allocator will cause a
	 * kernel panic. The normal kernel memory subsystem API should be used
	 * instead (e.g., kmem_alloc() and kmem_free()).
	 */
	mem_subsys_init();

	/*
 	 * Initialize the address space management subsystem.
 	 */
	aspace_subsys_init();


	sched_init_runqueue(0); /* This CPUs scheduler state + idle task */
	sched_add_task(current);  /* now safe to call schedule() */

	/*
 	 * Initialize the task scheduling subsystem.
 	 */
	core_timer_init(0);

	/* Start the kernel filesystems */
	kfs_init();

	/*
	 * Initialize the random number generator.
	 */
	rand_init();

	workq_init();

	/*
	 * Boot all of the other CPUs in the system, one at a time.
	 */
	printk(KERN_INFO "Number of CPUs detected: %d\n", num_cpus());
	for_each_cpu_mask(cpu, cpu_present_map) {
		/* The bootstrap CPU (that's us) is already booted. */
		if (cpu == 0) {
			cpu_set(cpu, cpu_online_map);
			continue;
		}

		printk(KERN_DEBUG "Booting CPU %u.\n", cpu);
		arch_boot_cpu(cpu);

		/* Wait for ACK that CPU has booted (5 seconds max). */
		for (timeout = 0; timeout < 50000; timeout++) {
			if (cpu_isset(cpu, cpu_online_map))
				break;
			udelay(100);
		}

		if (!cpu_isset(cpu, cpu_online_map))
			panic("Failed to boot CPU %d.\n", cpu);
	}

	/*
	 * Initialize the PCI subsystem.
	 */
	init_pci();

	/*
	 * Enable external interrupts.
	 */
	local_irq_enable();

#ifdef CONFIG_NETWORK
	/*
	 * Bring up any network devices.
	 */
	netdev_init();
#endif

#ifdef CONFIG_CRAY_GEMINI
	driver_init_list("net", "gemini");
#endif

#ifdef CONFIG_BLOCK_DEVICE
	/**
	 * Initialize the block devices
	 */
	blkdev_init();
#endif


	mcheck_init_late();

	/*
	 * And any modules that need to be started.
	 */
	driver_init_by_name( "module", "*" );

#ifdef CONFIG_KGDB
	/* 
	 * Stop eary (before "late" devices) in KGDB if requested
	 */
        kgdb_initial_breakpoint();
#endif

	/*
	 * Bring up any late init devices.
	 */
	driver_init_by_name( "late", "*" );

	/*
	 * Bring up the Linux compatibility layer, if enabled.
	 */
	linux_init();

#ifdef CONFIG_DEBUG_HW_NOISE
	/* Measure noise/interference in the underlying hardware/VMM */
	extern void measure_noise(int, uint64_t);
	measure_noise(0, 0);
#endif

	/*
	 * Start up user-space...
	 */
	printk(KERN_INFO "Loading initial user-level task (init_task)...\n");
	if ((status = create_init_task()) != 0)
		panic("Failed to create init_task (status=%d).", status);
	current->state = TASK_EXITED;
	schedule();  /* This should not return */
	BUG();
}
Esempio n. 18
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. 19
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. 20
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;
}
Esempio n. 21
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. 22
0
/**
 * Probe device
 *
 * @v pci	PCI device
 * @v id	Matching entry in ID table
 * @ret rc	Return status code
 */
static int b44_probe(struct pci_device *pci, const struct pci_device_id *id)
{
	struct net_device *netdev;
	struct b44_private *bp;
	int rc;

	/*
	 * Bail out if more than 1GB of physical RAM is installed.
	 * This limitation will be removed later when dma mapping
	 * is merged into mainline.
	 */
	if (!phys_ram_within_limit(B44_30BIT_DMA_MASK)) {
		DBG("Sorry, this version of the driver does not\n"
		    "support systems with more than 1GB of RAM.\n");
		return -ENOMEM;
	}

	/* Set up netdev */
	netdev = alloc_etherdev(sizeof(*bp));
	if (!netdev)
		return -ENOMEM;

	netdev_init(netdev, &b44_operations);
	pci_set_drvdata(pci, netdev);
	netdev->dev = &pci->dev;

	/* Set up private data */
	bp = netdev_priv(netdev);
	memset(bp, 0, sizeof(*bp));
	bp->netdev = netdev;
	bp->pci = pci;

	/* Map device registers */
	bp->regs = ioremap(pci->membase, B44_REGS_SIZE);
	if (!bp->regs) {
		netdev_put(netdev);
		return -ENOMEM;
	}

	/* Enable PCI bus mastering */
	adjust_pci_device(pci);

	b44_load_mac_and_phy_addr(bp);

	/* Link management currently not implemented */
	netdev_link_up(netdev);

	rc = register_netdev(netdev);
	if (rc != 0) {
		iounmap(bp->regs);
		netdev_put(netdev);
		return rc;
	}

	b44_chip_reset(bp, B44_CHIP_RESET_FULL);

	DBG("b44 %s (%04x:%04x) regs=%p MAC=%s\n", id->name, id->vendor,
	    id->device, bp->regs, eth_ntoa(netdev->ll_addr));

	return 0;
}
Esempio n. 23
0
/**
 * e1000_probe - Initial configuration of e1000 NIC
 *
 * @v pci	PCI device
 * @v id	PCI IDs
 *
 * @ret rc	Return status code
 **/
int e1000e_probe ( struct pci_device *pdev,
	      const struct pci_device_id *ent)
{
	int i, err;
	struct net_device *netdev;
	struct e1000_adapter *adapter;
	unsigned long mmio_start, mmio_len;
	unsigned long flash_start, flash_len;
	struct e1000_hw *hw;
	const struct e1000_info *ei = e1000_info_tbl[ent->driver_data];

	DBGP ( "e1000_probe\n" );

	err = -ENOMEM;

	/* Allocate net device ( also allocates memory for netdev->priv
	   and makes netdev-priv point to it ) */
	netdev = alloc_etherdev ( sizeof ( struct e1000_adapter ) );
	if ( ! netdev ) {
                DBG ( "err_alloc_etherdev\n" );
		goto err_alloc_etherdev;
        }

	/* Associate e1000-specific network operations operations with
	 * generic network device layer */
	netdev_init ( netdev, &e1000e_operations );

	/* Associate this network device with given PCI device */
	pci_set_drvdata ( pdev, netdev );
	netdev->dev = &pdev->dev;

	/* Initialize driver private storage */
	adapter = netdev_priv ( netdev );
	memset ( adapter, 0, ( sizeof ( *adapter ) ) );

	adapter->pdev	    = pdev;

	adapter->ioaddr	    = pdev->ioaddr;
	adapter->hw.io_base = pdev->ioaddr;

	hw		    = &adapter->hw;
	hw->device_id	    = pdev->device;

	adapter->irqno	    = pdev->irq;
	adapter->netdev	    = netdev;
	adapter->hw.back    = adapter;

	adapter->ei	    = ei;
	adapter->pba	    = ei->pba;
	adapter->flags	    = ei->flags;
	adapter->flags2	    = ei->flags2;

	adapter->hw.adapter  = adapter;
	adapter->hw.mac.type = ei->mac;
	adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;

	adapter->tx_ring_size = sizeof ( *adapter->tx_base ) * NUM_TX_DESC;
	adapter->rx_ring_size = sizeof ( *adapter->rx_base ) * NUM_RX_DESC;

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

	err = -EIO;

	mmio_start = pci_bar_start ( pdev, PCI_BASE_ADDRESS_0 );
	mmio_len   = pci_bar_size  ( pdev, PCI_BASE_ADDRESS_0 );

	DBG ( "mmio_start: %#08lx\n", mmio_start );
	DBG ( "mmio_len: %#08lx\n", mmio_len );

	adapter->hw.hw_addr = ioremap ( mmio_start, mmio_len );
	DBG ( "adapter->hw.hw_addr: %p\n", adapter->hw.hw_addr );

	if ( ! adapter->hw.hw_addr ) {
                DBG ( "err_ioremap\n" );
		goto err_ioremap;
        }

	/* Flash BAR mapping depends on mac_type */
	if ( ( adapter->flags & FLAG_HAS_FLASH) && ( pdev->ioaddr ) ) {
		flash_start = pci_bar_start ( pdev, PCI_BASE_ADDRESS_1 );
		flash_len = pci_bar_size ( pdev, PCI_BASE_ADDRESS_1 );
		adapter->hw.flash_address = ioremap ( flash_start, flash_len );
		if ( ! adapter->hw.flash_address ) {
                        DBG ( "err_flashmap\n" );
			goto err_flashmap;
		}
	}

	/* setup adapter struct */
	err = e1000e_sw_init ( adapter );
	if (err) {
                DBG ( "err_sw_init\n" );
		goto err_sw_init;
        }

	if (ei->get_variants) {
		err = ei->get_variants(adapter);
		if (err) {
                        DBG ( "err_hw_initr\n" );
			goto err_hw_init;
                }
	}

	/* Copper options */
	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
		adapter->hw.phy.mdix = AUTO_ALL_MODES;
		adapter->hw.phy.disable_polarity_correction = 0;
		adapter->hw.phy.ms_type = e1000_ms_hw_default;
	}

	DBG ( "adapter->hw.mac.type: %#08x\n", adapter->hw.mac.type );

	/* Force auto-negotiation */
	adapter->hw.mac.autoneg = 1;
	adapter->fc_autoneg = 1;
	adapter->hw.phy.autoneg_wait_to_complete = true;
	adapter->hw.mac.adaptive_ifs = true;
	adapter->hw.fc.requested_mode = e1000_fc_default;
	adapter->hw.fc.current_mode = e1000_fc_default;

	/*
	 * before reading the NVM, reset the controller to
	 * put the device in a known good starting state
	 */
	adapter->hw.mac.ops.reset_hw(&adapter->hw);

	/*
	 * systems with ASPM and others may see the checksum fail on the first
	 * attempt. Let's give it a few tries
	 */
	for (i = 0;; i++) {
		if (e1000e_validate_nvm_checksum(&adapter->hw) >= 0)
			break;
		if (i == 2) {
			DBG("The NVM Checksum Is Not Valid\n");
			err = -EIO;
			goto err_eeprom;
		}
	}

	/* copy the MAC address out of the EEPROM */
	if ( e1000e_read_mac_addr ( &adapter->hw ) )
		DBG ( "EEPROM Read Error\n" );

	memcpy ( netdev->hw_addr, adapter->hw.mac.perm_addr, ETH_ALEN );

	/* reset the hardware with the new settings */
	e1000e_reset ( adapter );

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

	if ( ( err = register_netdev ( netdev ) ) != 0) {
                DBG ( "err_register\n" );
		goto err_register;
        }

	for (i = 0; i < 6; i++)
		DBG ("%02x%s", netdev->ll_addr[i], i == 5 ? "\n" : ":");

	DBG ( "e1000e_probe succeeded!\n" );

	/* No errors, return success */
	return 0;

/* Error return paths */
err_register:
err_hw_init:
err_eeprom:
err_flashmap:
	if (!e1000e_check_reset_block(&adapter->hw))
		e1000e_phy_hw_reset(&adapter->hw);
	if (adapter->hw.flash_address)
		iounmap(adapter->hw.flash_address);
err_sw_init:
	iounmap ( adapter->hw.hw_addr );
err_ioremap:
	netdev_put ( netdev );
err_alloc_etherdev:
	return err;
}