Beispiel #1
0
/**
 * e1000_close - Disables a network interface
 *
 * @v netdev	network interface device structure
 *
 **/
static void
e1000_close ( struct net_device *netdev )
{
	struct e1000_adapter *adapter = netdev_priv ( netdev );
	struct e1000_hw *hw = &adapter->hw;
	uint32_t rctl;
	uint32_t icr;

	DBG ( "e1000_close\n" );
	
	/* Acknowledge interrupts */
	icr = E1000_READ_REG ( hw, ICR );

	e1000_irq_disable ( adapter );

	/* disable receives */
	rctl = E1000_READ_REG ( hw, RCTL );
	E1000_WRITE_REG ( hw, RCTL, rctl & ~E1000_RCTL_EN );
	E1000_WRITE_FLUSH ( hw );

	e1000_reset_hw ( hw );

	e1000_free_tx_resources ( adapter );
	e1000_free_rx_resources ( adapter );
}
Beispiel #2
0
/*
 * Stop the card.
 */
static void
e1000_stop(void)
{
	e1000_t *e;

	e = &e1000_state;

	E1000_DEBUG(3, ("%s: stop()\n", e->name));

	e1000_reset_hw(e);
}
Beispiel #3
0
/*
 * Initialize the hardware.  Return the ethernet address.
 */
static void
e1000_init_hw(e1000_t * e, ether_addr_t * addr)
{
	int r, i;

	e->irq_hook = e->irq;

	/*
	 * Set the interrupt handler and policy.  Do not automatically
	 * reenable interrupts.  Return the IRQ line number on interrupts.
	 */
	if ((r = sys_irqsetpolicy(e->irq, 0, &e->irq_hook)) != OK)
		panic("sys_irqsetpolicy failed: %d", r);
	if ((r = sys_irqenable(&e->irq_hook)) != OK)
		panic("sys_irqenable failed: %d", r);

	/* Reset hardware. */
	e1000_reset_hw(e);

	/*
	 * Initialize appropriately, according to section 14.3 General
	 * Configuration of Intel's Gigabit Ethernet Controllers Software
	 * Developer's Manual.
	 */
	e1000_reg_set(e, E1000_REG_CTRL,
	    E1000_REG_CTRL_ASDE | E1000_REG_CTRL_SLU);
	e1000_reg_unset(e, E1000_REG_CTRL, E1000_REG_CTRL_LRST);
	e1000_reg_unset(e, E1000_REG_CTRL, E1000_REG_CTRL_PHY_RST);
	e1000_reg_unset(e, E1000_REG_CTRL, E1000_REG_CTRL_ILOS);
	e1000_reg_write(e, E1000_REG_FCAL, 0);
	e1000_reg_write(e, E1000_REG_FCAH, 0);
	e1000_reg_write(e, E1000_REG_FCT, 0);
	e1000_reg_write(e, E1000_REG_FCTTV, 0);
	e1000_reg_unset(e, E1000_REG_CTRL, E1000_REG_CTRL_VME);

	/* Clear Multicast Table Array (MTA). */
	for (i = 0; i < 128; i++)
		e1000_reg_write(e, E1000_REG_MTA + i * 4, 0);

	/* Initialize statistics registers. */
	for (i = 0; i < 64; i++)
		e1000_reg_write(e, E1000_REG_CRCERRS + i * 4, 0);

	/* Acquire MAC address and set up RX/TX buffers. */
	e1000_init_addr(e, addr);
	e1000_init_buf(e);

	/* Enable interrupts. */
	e1000_reg_set(e, E1000_REG_IMS, E1000_REG_IMS_LSC | E1000_REG_IMS_RXO |
	    E1000_REG_IMS_RXT | E1000_REG_IMS_TXQE | E1000_REG_IMS_TXDW);
}
Beispiel #4
0
/**
 * e1000_reset - Put e1000 NIC in known initial state
 *
 * @v adapter	e1000 private structure
 **/
void e1000_reset ( struct e1000_adapter *adapter )
{
    struct e1000_mac_info *mac = &adapter->hw.mac;
    u32 pba = 0;

    DBG ( "e1000_reset\n" );

    switch (mac->type) {
    case e1000_82542:
    case e1000_82543:
    case e1000_82544:
    case e1000_82540:
    case e1000_82541:
    case e1000_82541_rev_2:
        pba = E1000_PBA_48K;
        break;
    case e1000_82545:
    case e1000_82545_rev_3:
    case e1000_82546:
    case e1000_82546_rev_3:
        pba = E1000_PBA_48K;
        break;
    case e1000_82547:
    case e1000_82547_rev_2:
        pba = E1000_PBA_30K;
        break;
    case e1000_ep80579:
        pba = E1000_PBA_48K;
        break;
    case e1000_undefined:
    case e1000_num_macs:
        break;
    }

    E1000_WRITE_REG ( &adapter->hw, E1000_PBA, pba );

    /* Allow time for pending master requests to run */
    e1000_reset_hw ( &adapter->hw );

    if ( mac->type >= e1000_82544 )
        E1000_WRITE_REG ( &adapter->hw, E1000_WUC, 0 );

    if ( e1000_init_hw ( &adapter->hw ) )
        DBG ( "Hardware Error\n" );

    e1000_reset_adaptive ( &adapter->hw );
    e1000_get_phy_info ( &adapter->hw );

    e1000_init_manageability ( adapter );
}
Beispiel #5
0
/**
 * e1000_remove - Device Removal Routine
 *
 * @v pdev PCI device information struct
 *
 **/
void e1000_remove ( struct pci_device *pdev )
{
	struct net_device *netdev = pci_get_drvdata ( pdev );
	struct e1000_adapter *adapter = netdev_priv ( netdev );

	DBG ( "e1000_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 );
	e1000_reset_hw ( &adapter->hw );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}
Beispiel #6
0
/**
 * e1000_reset - Put e1000 NIC in known initial state
 *
 * @v adapter	e1000 private structure
 **/
static void
e1000_reset ( struct e1000_adapter *adapter )
{
	uint32_t pba = 0;
	uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;

	DBG ( "e1000_reset\n" );

	switch (adapter->hw.mac_type) {
	case e1000_82542_rev2_0:
	case e1000_82542_rev2_1:
	case e1000_82543:
	case e1000_82544:
	case e1000_82540:
	case e1000_82541:
	case e1000_82541_rev_2:
		pba = E1000_PBA_48K;
		break;
	case e1000_82545:
	case e1000_82545_rev_3:
	case e1000_82546:
	case e1000_82546_rev_3:
		pba = E1000_PBA_48K;
		break;
	case e1000_82547:
	case e1000_82547_rev_2:
		pba = E1000_PBA_30K;
		break;
	case e1000_82571:
	case e1000_82572:
	case e1000_80003es2lan:
		pba = E1000_PBA_38K;
		break;
	case e1000_82573:
		pba = E1000_PBA_20K;
		break;
	case e1000_82576:
		pba = E1000_PBA_64K;
		break;
	case e1000_ich8lan:
		pba = E1000_PBA_8K;
	case e1000_undefined:
	case e1000_num_macs:
		break;
	}

	E1000_WRITE_REG ( &adapter->hw, PBA, pba );
	
	/* flow control settings */
	/* Set the FC high water mark to 90% of the FIFO size.
	 * Required to clear last 3 LSB */
	fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;

	/* We can't use 90% on small FIFOs because the remainder
	 * would be less than 1 full frame.  In this case, we size
	 * it to allow at least a full frame above the high water
	 *  mark. */
	if (pba < E1000_PBA_16K)
		fc_high_water_mark = (pba * 1024) - 1600;

	/* This actually applies to < e1000_82575, one revision less than
	 * e1000_82576, but e1000_82575 isn't currently defined in the code */
	if (adapter->hw.mac_type < e1000_82576) {
		/* 8-byte granularity */
		adapter->hw.fc_high_water = fc_high_water_mark & 0xFFF8;
		adapter->hw.fc_low_water = adapter->hw.fc_high_water - 8;
	} else {
		/* 16-byte granularity */
		adapter->hw.fc_high_water = fc_high_water_mark & 0xFFF0;
		adapter->hw.fc_low_water = adapter->hw.fc_high_water - 16;
	}

	if (adapter->hw.mac_type == e1000_80003es2lan ||
	    adapter->hw.mac_type == e1000_82576)
		adapter->hw.fc_pause_time = 0xFFFF;
	else
		adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
	adapter->hw.fc_send_xon = 1;
	adapter->hw.fc = adapter->hw.original_fc;
	/* Allow time for pending master requests to run */

	e1000_reset_hw ( &adapter->hw );

	if ( adapter->hw.mac_type >= e1000_82544 )
		E1000_WRITE_REG ( &adapter->hw, WUC, 0 );

	if ( e1000_init_hw ( &adapter->hw ) )
		DBG ( "Hardware Error\n" );

	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
	if (adapter->hw.mac_type >= e1000_82544 &&
	    adapter->hw.mac_type <= e1000_82547_rev_2 &&
	    adapter->hw.autoneg == 1 &&
	    adapter->hw.autoneg_advertised == ADVERTISE_1000_FULL) {
		uint32_t ctrl = E1000_READ_REG(&adapter->hw, CTRL);
		/* clear phy power management bit if we are in gig only mode,
		 * which if enabled will attempt negotiation to 100Mb, which
		 * can cause a loss of link at power off or driver unload */
		ctrl &= ~E1000_CTRL_SWDPIN3;
		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
	}

	e1000_phy_get_info ( &adapter->hw, &adapter->phy_info );

	if (!adapter->smart_power_down &&
	    (adapter->hw.mac_type == e1000_82571 ||
	     adapter->hw.mac_type == e1000_82572)) {
		uint16_t phy_data = 0;
		/* speed up time to link by disabling smart power down, ignore
		 * the return value of this function because there is nothing
		 * different we would do if it failed */
		e1000_read_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
		                   &phy_data);
		phy_data &= ~IGP02E1000_PM_SPD;
		e1000_write_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
		                    phy_data);
	}
}
Beispiel #7
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;
}