/**
 *  e1000_setup_init_funcs - Initializes function pointers
 *  @hw: pointer to the HW structure
 *  @init_device: true will initialize the rest of the function pointers
 *		  getting the device ready for use.  false will only set
 *		  MAC type and the function pointers for the other init
 *		  functions.  Passing false will not generate any hardware
 *		  reads or writes.
 *
 *  This function must be called by a driver in order to use the rest
 *  of the 'shared' code files. Called by drivers only.
 **/
s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
{
	s32 ret_val;

	/* Can't do much good without knowing the MAC type. */
	ret_val = e1000_set_mac_type(hw);
	if (ret_val) {
		DEBUGOUT("ERROR: MAC type could not be set properly.\n");
		goto out;
	}

	if (!hw->hw_addr) {
		DEBUGOUT("ERROR: Registers not mapped\n");
		ret_val = -E1000_ERR_CONFIG;
		goto out;
	}

	/*
	 * Init function pointers to generic implementations. We do this first
	 * allowing a driver module to override it afterward.
	 */
	e1000_init_mac_ops_generic(hw);
	e1000_init_nvm_ops_generic(hw);
	e1000_init_mbx_ops_generic(hw);

	/*
	 * Set up the init function pointers. These are functions within the
	 * adapter family file that sets up function pointers for the rest of
	 * the functions in that family.
	 */
	switch (hw->mac.type) {
	case e1000_82575:
	case e1000_82576:
	case e1000_82580:
	case e1000_i350:
	case e1000_i354:
		e1000_init_function_pointers_82575(hw);
		break;
	case e1000_i210:
	case e1000_i211:
		e1000_init_function_pointers_i210(hw);
		break;
	default:
		DEBUGOUT("Hardware not supported\n");
		ret_val = -E1000_ERR_CONFIG;
		break;
	}

	/*
	 * Initialize the rest of the function pointers. These require some
	 * register reads/writes in some cases.
	 */
	if (!(ret_val) && init_device) {
		ret_val = e1000_init_mac_params(hw);
		if (ret_val)
			goto out;

		ret_val = e1000_init_nvm_params(hw);
		if (ret_val)
			goto out;

		ret_val = e1000_init_phy_params(hw);
		if (ret_val)
			goto out;

		ret_val = e1000_init_mbx_params(hw);
		if (ret_val)
			goto out;
	}

out:
	return ret_val;
}
Ejemplo n.º 2
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;
}