1168 lines
32 KiB
C
1168 lines
32 KiB
C
|
/*******************************************************************************
|
||
|
|
||
|
Intel PRO/1000 Linux driver
|
||
|
Copyright(c) 1999 - 2006 Intel Corporation.
|
||
|
|
||
|
This program is free software; you can redistribute it and/or modify it
|
||
|
under the terms and conditions of the GNU General Public License,
|
||
|
version 2, as published by the Free Software Foundation.
|
||
|
|
||
|
This program is distributed in the hope it will be useful, but WITHOUT
|
||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||
|
more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License along with
|
||
|
this program; if not, write to the Free Software Foundation, Inc.,
|
||
|
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
|
||
|
The full GNU General Public License is included in this distribution in
|
||
|
the file called "COPYING".
|
||
|
|
||
|
Contact Information:
|
||
|
Linux NICS <linux.nics@intel.com>
|
||
|
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||
|
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||
|
|
||
|
*******************************************************************************/
|
||
|
|
||
|
#include "e1000.h"
|
||
|
|
||
|
static struct pci_device_id e1000_nics[] = {
|
||
|
PCI_ROM(0x8086, 0x1000, "e1000-0x1000", "E1000-0x1000"),
|
||
|
PCI_ROM(0x8086, 0x1001, "e1000-0x1001", "E1000-0x1001"),
|
||
|
PCI_ROM(0x8086, 0x1004, "e1000-0x1004", "E1000-0x1004"),
|
||
|
PCI_ROM(0x8086, 0x1008, "e1000-0x1008", "E1000-0x1008"),
|
||
|
PCI_ROM(0x8086, 0x1009, "e1000-0x1009", "E1000-0x1009"),
|
||
|
PCI_ROM(0x8086, 0x100C, "e1000-0x100C", "E1000-0x100C"),
|
||
|
PCI_ROM(0x8086, 0x100D, "e1000-0x100D", "E1000-0x100D"),
|
||
|
PCI_ROM(0x8086, 0x100E, "e1000-0x100E", "E1000-0x100E"),
|
||
|
PCI_ROM(0x8086, 0x100F, "e1000-0x100F", "E1000-0x100F"),
|
||
|
PCI_ROM(0x8086, 0x1010, "e1000-0x1010", "E1000-0x1010"),
|
||
|
PCI_ROM(0x8086, 0x1011, "e1000-0x1011", "E1000-0x1011"),
|
||
|
PCI_ROM(0x8086, 0x1012, "e1000-0x1012", "E1000-0x1012"),
|
||
|
PCI_ROM(0x8086, 0x1013, "e1000-0x1013", "E1000-0x1013"),
|
||
|
PCI_ROM(0x8086, 0x1014, "e1000-0x1014", "E1000-0x1014"),
|
||
|
PCI_ROM(0x8086, 0x1015, "e1000-0x1015", "E1000-0x1015"),
|
||
|
PCI_ROM(0x8086, 0x1016, "e1000-0x1016", "E1000-0x1016"),
|
||
|
PCI_ROM(0x8086, 0x1017, "e1000-0x1017", "E1000-0x1017"),
|
||
|
PCI_ROM(0x8086, 0x1018, "e1000-0x1018", "E1000-0x1018"),
|
||
|
PCI_ROM(0x8086, 0x1019, "e1000-0x1019", "E1000-0x1019"),
|
||
|
PCI_ROM(0x8086, 0x101A, "e1000-0x101A", "E1000-0x101A"),
|
||
|
PCI_ROM(0x8086, 0x101D, "e1000-0x101D", "E1000-0x101D"),
|
||
|
PCI_ROM(0x8086, 0x101E, "e1000-0x101E", "E1000-0x101E"),
|
||
|
PCI_ROM(0x8086, 0x1026, "e1000-0x1026", "E1000-0x1026"),
|
||
|
PCI_ROM(0x8086, 0x1027, "e1000-0x1027", "E1000-0x1027"),
|
||
|
PCI_ROM(0x8086, 0x1028, "e1000-0x1028", "E1000-0x1028"),
|
||
|
PCI_ROM(0x8086, 0x1049, "e1000-0x1049", "E1000-0x1049"),
|
||
|
PCI_ROM(0x8086, 0x104A, "e1000-0x104A", "E1000-0x104A"),
|
||
|
PCI_ROM(0x8086, 0x104B, "e1000-0x104B", "E1000-0x104B"),
|
||
|
PCI_ROM(0x8086, 0x104C, "e1000-0x104C", "E1000-0x104C"),
|
||
|
PCI_ROM(0x8086, 0x104D, "e1000-0x104D", "E1000-0x104D"),
|
||
|
PCI_ROM(0x8086, 0x105E, "e1000-0x105E", "E1000-0x105E"),
|
||
|
PCI_ROM(0x8086, 0x105F, "e1000-0x105F", "E1000-0x105F"),
|
||
|
PCI_ROM(0x8086, 0x1060, "e1000-0x1060", "E1000-0x1060"),
|
||
|
PCI_ROM(0x8086, 0x1075, "e1000-0x1075", "E1000-0x1075"),
|
||
|
PCI_ROM(0x8086, 0x1076, "e1000-0x1076", "E1000-0x1076"),
|
||
|
PCI_ROM(0x8086, 0x1077, "e1000-0x1077", "E1000-0x1077"),
|
||
|
PCI_ROM(0x8086, 0x1078, "e1000-0x1078", "E1000-0x1078"),
|
||
|
PCI_ROM(0x8086, 0x1079, "e1000-0x1079", "E1000-0x1079"),
|
||
|
PCI_ROM(0x8086, 0x107A, "e1000-0x107A", "E1000-0x107A"),
|
||
|
PCI_ROM(0x8086, 0x107B, "e1000-0x107B", "E1000-0x107B"),
|
||
|
PCI_ROM(0x8086, 0x107C, "e1000-0x107C", "E1000-0x107C"),
|
||
|
PCI_ROM(0x8086, 0x107D, "e1000-0x107D", "E1000-0x107D"),
|
||
|
PCI_ROM(0x8086, 0x107E, "e1000-0x107E", "E1000-0x107E"),
|
||
|
PCI_ROM(0x8086, 0x107F, "e1000-0x107F", "E1000-0x107F"),
|
||
|
PCI_ROM(0x8086, 0x108A, "e1000-0x108A", "E1000-0x108A"),
|
||
|
PCI_ROM(0x8086, 0x108B, "e1000-0x108B", "E1000-0x108B"),
|
||
|
PCI_ROM(0x8086, 0x108C, "e1000-0x108C", "E1000-0x108C"),
|
||
|
PCI_ROM(0x8086, 0x1096, "e1000-0x1096", "E1000-0x1096"),
|
||
|
PCI_ROM(0x8086, 0x1098, "e1000-0x1098", "E1000-0x1098"),
|
||
|
PCI_ROM(0x8086, 0x1099, "e1000-0x1099", "E1000-0x1099"),
|
||
|
PCI_ROM(0x8086, 0x109A, "e1000-0x109A", "E1000-0x109A"),
|
||
|
PCI_ROM(0x8086, 0x10A4, "e1000-0x10A4", "E1000-0x10A4"),
|
||
|
PCI_ROM(0x8086, 0x10A5, "e1000-0x10A5", "E1000-0x10A5"),
|
||
|
PCI_ROM(0x8086, 0x10B5, "e1000-0x10B5", "E1000-0x10B5"),
|
||
|
PCI_ROM(0x8086, 0x10B9, "e1000-0x10B9", "E1000-0x10B9"),
|
||
|
PCI_ROM(0x8086, 0x10BA, "e1000-0x10BA", "E1000-0x10BA"),
|
||
|
PCI_ROM(0x8086, 0x10BB, "e1000-0x10BB", "E1000-0x10BB"),
|
||
|
PCI_ROM(0x8086, 0x10BC, "e1000-0x10BC", "E1000-0x10BC"),
|
||
|
PCI_ROM(0x8086, 0x10C4, "e1000-0x10C4", "E1000-0x10C4"),
|
||
|
PCI_ROM(0x8086, 0x10C5, "e1000-0x10C5", "E1000-0x10C5"),
|
||
|
PCI_ROM(0x8086, 0x10D9, "e1000-0x10D9", "E1000-0x10D9"),
|
||
|
PCI_ROM(0x8086, 0x10DA, "e1000-0x10DA", "E1000-0x10DA"),
|
||
|
};
|
||
|
|
||
|
static void
|
||
|
e1000_init_manageability ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
DBG ( "e1000_init_manageability\n" );
|
||
|
|
||
|
if (adapter->en_mng_pt) {
|
||
|
uint32_t manc = E1000_READ_REG(&adapter->hw, MANC);
|
||
|
|
||
|
/* disable hardware interception of ARP */
|
||
|
manc &= ~(E1000_MANC_ARP_EN);
|
||
|
|
||
|
/* enable receiving management packets to the host */
|
||
|
/* this will probably generate destination unreachable messages
|
||
|
* from the host OS, but the packets will be handled on SMBUS */
|
||
|
if (adapter->hw.has_manc2h) {
|
||
|
uint32_t manc2h = E1000_READ_REG(&adapter->hw, MANC2H);
|
||
|
|
||
|
manc |= E1000_MANC_EN_MNG2HOST;
|
||
|
manc2h |= E1000_MNG2HOST_PORT_623;
|
||
|
manc2h |= E1000_MNG2HOST_PORT_664;
|
||
|
E1000_WRITE_REG(&adapter->hw, MANC2H, manc2h);
|
||
|
}
|
||
|
|
||
|
E1000_WRITE_REG(&adapter->hw, MANC, manc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_power_up_phy - restore link in case the phy was powered down
|
||
|
* @adapter: address of board private structure
|
||
|
*
|
||
|
* The phy may be powered down to save power and turn off link when the
|
||
|
* driver is unloaded and wake on lan is not enabled (among others)
|
||
|
* *** this routine MUST be followed by a call to e1000_reset ***
|
||
|
*
|
||
|
**/
|
||
|
static void
|
||
|
e1000_power_up_phy ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
DBG ( "e1000_power_up_phy\n" );
|
||
|
|
||
|
uint16_t mii_reg = 0;
|
||
|
|
||
|
/* Just clear the power down bit to wake the phy back up */
|
||
|
if (adapter->hw.media_type == e1000_media_type_copper) {
|
||
|
/* according to the manual, the phy will retain its
|
||
|
* settings across a power-down/up cycle */
|
||
|
e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
|
||
|
mii_reg &= ~MII_CR_POWER_DOWN;
|
||
|
e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
e1000_power_down_phy ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
DBG ( "e1000_power_down_phy\n" );
|
||
|
|
||
|
/* Power down the PHY so no link is implied when interface is down *
|
||
|
* The PHY cannot be powered down if any of the following is TRUE *
|
||
|
* (a) WoL is enabled
|
||
|
* (b) AMT is active
|
||
|
* (c) SoL/IDER session is active */
|
||
|
if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
|
||
|
adapter->hw.media_type == e1000_media_type_copper) {
|
||
|
uint16_t mii_reg = 0;
|
||
|
|
||
|
switch (adapter->hw.mac_type) {
|
||
|
case e1000_82540:
|
||
|
case e1000_82545:
|
||
|
case e1000_82545_rev_3:
|
||
|
case e1000_82546:
|
||
|
case e1000_82546_rev_3:
|
||
|
case e1000_82541:
|
||
|
case e1000_82541_rev_2:
|
||
|
case e1000_82547:
|
||
|
case e1000_82547_rev_2:
|
||
|
if (E1000_READ_REG(&adapter->hw, MANC) &
|
||
|
E1000_MANC_SMBUS_EN)
|
||
|
goto out;
|
||
|
break;
|
||
|
case e1000_82571:
|
||
|
case e1000_82572:
|
||
|
case e1000_82573:
|
||
|
case e1000_80003es2lan:
|
||
|
case e1000_ich8lan:
|
||
|
if (e1000_check_mng_mode(&adapter->hw) ||
|
||
|
e1000_check_phy_reset_block(&adapter->hw))
|
||
|
goto out;
|
||
|
break;
|
||
|
default:
|
||
|
goto out;
|
||
|
}
|
||
|
e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
|
||
|
mii_reg |= MII_CR_POWER_DOWN;
|
||
|
e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
|
||
|
mdelay(1);
|
||
|
}
|
||
|
out:
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_sw_init - Initialize general software structures (struct e1000_adapter)
|
||
|
* @adapter: board private structure to initialize
|
||
|
*
|
||
|
* e1000_sw_init initializes the Adapter private data structure.
|
||
|
* Fields are initialized based on PCI device information and
|
||
|
* OS network device settings (MTU size).
|
||
|
**/
|
||
|
static int
|
||
|
e1000_sw_init ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
struct e1000_hw *hw = &adapter->hw;
|
||
|
struct pci_device *pdev = adapter->pdev;
|
||
|
|
||
|
DBG ( "e1000_sw_init\n" );
|
||
|
|
||
|
/* PCI config space info */
|
||
|
hw->vendor_id = pdev->vendor;
|
||
|
hw->device_id = pdev->device;
|
||
|
|
||
|
pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
|
||
|
|
||
|
adapter->rx_buffer_len = 2048;
|
||
|
|
||
|
/* identify the MAC */
|
||
|
|
||
|
if ( e1000_set_mac_type ( hw ) ) {
|
||
|
DBG ( "Unknown MAC Type\n" );
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
switch (hw->mac_type) {
|
||
|
default:
|
||
|
break;
|
||
|
case e1000_82541:
|
||
|
case e1000_82547:
|
||
|
case e1000_82541_rev_2:
|
||
|
case e1000_82547_rev_2:
|
||
|
hw->phy_init_script = 1;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
e1000_set_media_type(hw);
|
||
|
|
||
|
hw->wait_autoneg_complete = TRUE;
|
||
|
hw->tbi_compatibility_en = TRUE;
|
||
|
hw->adaptive_ifs = TRUE;
|
||
|
|
||
|
/* Copper options */
|
||
|
|
||
|
if (hw->media_type == e1000_media_type_copper) {
|
||
|
hw->mdix = AUTO_ALL_MODES;
|
||
|
hw->disable_polarity_correction = FALSE;
|
||
|
hw->master_slave = E1000_MASTER_SLAVE;
|
||
|
}
|
||
|
|
||
|
adapter->num_tx_queues = 1;
|
||
|
adapter->num_rx_queues = 1;
|
||
|
|
||
|
return E1000_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_setup_tx_resources - allocate Tx resources (Descriptors)
|
||
|
* @adapter: board private structure
|
||
|
* @txdr: tx descriptor ring (for a specific queue) to setup
|
||
|
*
|
||
|
* Return 0 on success, negative on failure
|
||
|
**/
|
||
|
static int
|
||
|
e1000_setup_tx_resources ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
DBG ( "e1000_setup_tx_resources\n" );
|
||
|
|
||
|
/* Allocate transmit descriptor ring memory.
|
||
|
It must not cross a 64K boundary because of hardware errata #23
|
||
|
so we use malloc_dma() requesting a 128 byte block that is
|
||
|
128 byte aligned. This should guarantee that the memory
|
||
|
allocated will not cross a 64K boundary, because 128 is an
|
||
|
even multiple of 65536 ( 65536 / 128 == 512 ), so all possible
|
||
|
allocations of 128 bytes on a 128 byte boundary will not
|
||
|
cross 64K bytes.
|
||
|
*/
|
||
|
|
||
|
adapter->tx_desc_ring =
|
||
|
malloc_dma ( sizeof ( struct e1000_tx_desc ) * NUM_TX_DESC,
|
||
|
sizeof ( struct e1000_tx_desc ) * NUM_TX_DESC );
|
||
|
|
||
|
if ( ! adapter->tx_desc_ring ) {
|
||
|
return -ENOMEM;
|
||
|
}
|
||
|
|
||
|
memset ( adapter->tx_desc_ring, 0, sizeof ( struct e1000_tx_desc ) *
|
||
|
NUM_TX_DESC );
|
||
|
|
||
|
for ( i = 0; i < NUM_TX_DESC; i++ ) {
|
||
|
adapter->tx_desc[i] = (void *) adapter->tx_desc_ring +
|
||
|
( i * sizeof ( struct e1000_tx_desc ) );
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
e1000_free_tx_resources ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
DBG ( "e1000_free_tx_resources\n" );
|
||
|
|
||
|
free_dma ( adapter->tx_desc_ring,
|
||
|
sizeof ( struct e1000_tx_desc ) * NUM_TX_DESC );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_setup_rx_resources - allocate Rx resources (Descriptors)
|
||
|
* @adapter: board private structure
|
||
|
* @rxdr: rx descriptor ring (for a specific queue) to setup
|
||
|
*
|
||
|
* Returns 0 on success, negative on failure
|
||
|
**/
|
||
|
static int
|
||
|
e1000_setup_rx_resources ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
int i, j;
|
||
|
|
||
|
DBG ( "e1000_setup_rx_resources\n" );
|
||
|
|
||
|
/* Allocate receive descriptor ring memory.
|
||
|
It must not cross a 64K boundary because of hardware errata
|
||
|
*/
|
||
|
|
||
|
adapter->rx_desc_ring =
|
||
|
malloc_dma ( sizeof ( struct e1000_rx_desc ) * NUM_RX_DESC,
|
||
|
sizeof ( struct e1000_rx_desc ) * NUM_RX_DESC );
|
||
|
|
||
|
if ( ! adapter->rx_desc_ring ) {
|
||
|
return -ENOMEM;
|
||
|
}
|
||
|
|
||
|
memset ( adapter->rx_desc_ring, 0, sizeof (struct e1000_rx_desc) * NUM_RX_DESC );
|
||
|
|
||
|
for ( i = 0; i < NUM_RX_DESC; i++ ) {
|
||
|
|
||
|
adapter->rx_iobuf[i] = alloc_iob ( E1000_RXBUFFER_2048 );
|
||
|
|
||
|
/* If unable to allocate all iobufs, free any that
|
||
|
* were successfully allocated, and return an error
|
||
|
*/
|
||
|
if ( ! adapter->rx_iobuf[i] ) {
|
||
|
for ( j = 0; j < i; j++ ) {
|
||
|
free_iob ( adapter->rx_iobuf[j] );
|
||
|
}
|
||
|
return -ENOMEM;
|
||
|
}
|
||
|
|
||
|
adapter->rx_desc[i] = (void *) adapter->rx_desc_ring +
|
||
|
( i * sizeof ( struct e1000_rx_desc ) );
|
||
|
|
||
|
adapter->rx_desc[i]->buffer_addr = virt_to_bus ( adapter->rx_iobuf[i]->data );
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
e1000_free_rx_resources ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
DBG ( "e1000_free_rx_resources\n" );
|
||
|
|
||
|
free_dma ( adapter->rx_desc_ring,
|
||
|
sizeof ( struct e1000_rx_desc ) * NUM_RX_DESC );
|
||
|
|
||
|
for ( i = 0; i < NUM_RX_DESC; i++ ) {
|
||
|
free_iob ( adapter->rx_iobuf[i] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_configure_tx - Configure 8254x Transmit Unit after Reset
|
||
|
* @adapter: board private structure
|
||
|
*
|
||
|
* Configure the Tx unit of the MAC after a reset.
|
||
|
**/
|
||
|
static void
|
||
|
e1000_configure_tx ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
struct e1000_hw *hw = &adapter->hw;
|
||
|
uint32_t tctl, tipg, tarc;
|
||
|
uint32_t ipgr1, ipgr2;
|
||
|
|
||
|
DBG ( "e1000_configure_tx\n" );
|
||
|
|
||
|
E1000_WRITE_REG ( hw, TDBAH, 0 );
|
||
|
E1000_WRITE_REG ( hw, TDBAL, virt_to_bus ( adapter->tx_base ) );
|
||
|
E1000_WRITE_REG ( hw, TDLEN, sizeof ( struct e1000_tx_desc ) *
|
||
|
NUM_TX_DESC );
|
||
|
|
||
|
/* Setup the HW Tx Head and Tail descriptor pointers */
|
||
|
E1000_WRITE_REG ( hw, TDH, 0 );
|
||
|
E1000_WRITE_REG ( hw, TDT, 0 );
|
||
|
|
||
|
adapter->tx_head = 0;
|
||
|
adapter->tx_tail = 0;
|
||
|
adapter->tx_fill_ctr = 0;
|
||
|
|
||
|
/* Set the default values for the Tx Inter Packet Gap timer */
|
||
|
if (adapter->hw.mac_type <= e1000_82547_rev_2 &&
|
||
|
(hw->media_type == e1000_media_type_fiber ||
|
||
|
hw->media_type == e1000_media_type_internal_serdes))
|
||
|
tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
|
||
|
else
|
||
|
tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
|
||
|
|
||
|
switch (hw->mac_type) {
|
||
|
case e1000_82542_rev2_0:
|
||
|
case e1000_82542_rev2_1:
|
||
|
tipg = DEFAULT_82542_TIPG_IPGT;
|
||
|
ipgr1 = DEFAULT_82542_TIPG_IPGR1;
|
||
|
ipgr2 = DEFAULT_82542_TIPG_IPGR2;
|
||
|
break;
|
||
|
case e1000_80003es2lan:
|
||
|
ipgr1 = DEFAULT_82543_TIPG_IPGR1;
|
||
|
ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;
|
||
|
break;
|
||
|
default:
|
||
|
ipgr1 = DEFAULT_82543_TIPG_IPGR1;
|
||
|
ipgr2 = DEFAULT_82543_TIPG_IPGR2;
|
||
|
break;
|
||
|
}
|
||
|
tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
|
||
|
tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
|
||
|
E1000_WRITE_REG ( hw, TIPG, tipg );
|
||
|
|
||
|
/* Set the Tx Interrupt Delay register */
|
||
|
|
||
|
E1000_WRITE_REG (hw, TIDV, adapter->tx_int_delay);
|
||
|
if (hw->mac_type >= e1000_82540)
|
||
|
E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
|
||
|
|
||
|
/* Program the Transmit Control Register */
|
||
|
|
||
|
tctl = E1000_READ_REG(hw, TCTL);
|
||
|
tctl &= ~E1000_TCTL_CT;
|
||
|
tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
|
||
|
(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
|
||
|
|
||
|
if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
|
||
|
tarc = E1000_READ_REG(hw, TARC0);
|
||
|
/* set the speed mode bit, we'll clear it if we're not at
|
||
|
* gigabit link later */
|
||
|
tarc |= (1 << 21);
|
||
|
E1000_WRITE_REG(hw, TARC0, tarc);
|
||
|
} else if (hw->mac_type == e1000_80003es2lan) {
|
||
|
tarc = E1000_READ_REG(hw, TARC0);
|
||
|
tarc |= 1;
|
||
|
E1000_WRITE_REG(hw, TARC0, tarc);
|
||
|
tarc = E1000_READ_REG(hw, TARC1);
|
||
|
tarc |= 1;
|
||
|
E1000_WRITE_REG(hw, TARC1, tarc);
|
||
|
}
|
||
|
|
||
|
e1000_config_collision_dist(hw);
|
||
|
|
||
|
/* Setup Transmit Descriptor Settings for eop descriptor */
|
||
|
adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
|
||
|
|
||
|
/* only set IDE if we are delaying interrupts using the timers */
|
||
|
if (adapter->tx_int_delay)
|
||
|
adapter->txd_cmd |= E1000_TXD_CMD_IDE;
|
||
|
|
||
|
if (hw->mac_type < e1000_82543)
|
||
|
adapter->txd_cmd |= E1000_TXD_CMD_RPS;
|
||
|
else
|
||
|
adapter->txd_cmd |= E1000_TXD_CMD_RS;
|
||
|
|
||
|
/* Cache if we're 82544 running in PCI-X because we'll
|
||
|
* need this to apply a workaround later in the send path. */
|
||
|
if (hw->mac_type == e1000_82544 &&
|
||
|
hw->bus_type == e1000_bus_type_pcix)
|
||
|
adapter->pcix_82544 = 1;
|
||
|
|
||
|
E1000_WRITE_REG ( hw, TCTL, tctl );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_setup_rctl - configure the receive control registers
|
||
|
* @adapter: Board private structure
|
||
|
**/
|
||
|
static void
|
||
|
e1000_setup_rctl ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
uint32_t rctl;
|
||
|
|
||
|
DBG ( "e1000_setup_rctl\n" );
|
||
|
|
||
|
rctl = E1000_READ_REG ( &adapter->hw, RCTL );
|
||
|
|
||
|
rctl &= ~( 3 << E1000_RCTL_MO_SHIFT );
|
||
|
|
||
|
rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
|
||
|
E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
|
||
|
( adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT );
|
||
|
|
||
|
if ( adapter->hw.tbi_compatibility_on == 1 )
|
||
|
rctl |= E1000_RCTL_SBP;
|
||
|
else
|
||
|
rctl &= ~E1000_RCTL_SBP;
|
||
|
|
||
|
rctl &= ~E1000_RCTL_LPE;
|
||
|
|
||
|
/* Setup buffer sizes */
|
||
|
rctl |= E1000_RCTL_SZ_2048;
|
||
|
rctl &= ~E1000_RCTL_BSEX;
|
||
|
|
||
|
E1000_WRITE_REG ( &adapter->hw, RCTL, rctl );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_configure_rx - Configure 8254x Receive Unit after Reset
|
||
|
* @adapter: board private structure
|
||
|
*
|
||
|
* Configure the Rx unit of the MAC after a reset.
|
||
|
**/
|
||
|
static void
|
||
|
e1000_configure_rx ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
struct e1000_hw *hw = &adapter->hw;
|
||
|
uint32_t rctl, ctrl_ext;
|
||
|
|
||
|
DBG ( "e1000_configure_rx\n" );
|
||
|
|
||
|
/* disable receives while setting up the descriptors */
|
||
|
rctl = E1000_READ_REG(hw, RCTL);
|
||
|
E1000_WRITE_REG ( hw, RCTL, rctl & ~E1000_RCTL_EN );
|
||
|
|
||
|
/* set the Receive Delay Timer Register */
|
||
|
E1000_WRITE_REG( hw, RDTR, adapter->rx_int_delay );
|
||
|
|
||
|
if (hw->mac_type >= e1000_82540) {
|
||
|
E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
|
||
|
if (adapter->itr_setting != 0)
|
||
|
E1000_WRITE_REG(hw, ITR,
|
||
|
1000000000 / (adapter->itr * 256));
|
||
|
}
|
||
|
|
||
|
if (hw->mac_type >= e1000_82571) {
|
||
|
ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
|
||
|
/* Reset delay timers after every interrupt */
|
||
|
ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
|
||
|
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
|
||
|
E1000_WRITE_FLUSH(hw);
|
||
|
}
|
||
|
|
||
|
/* Setup the HW Rx Head and Tail Descriptor Pointers and
|
||
|
* the Base and Length of the Rx Descriptor Ring */
|
||
|
|
||
|
adapter->rx_tail = 0;
|
||
|
|
||
|
E1000_WRITE_REG ( hw, RDBAH, 0 );
|
||
|
E1000_WRITE_REG ( hw, RDBAL, virt_to_bus ( adapter->rx_base ) );
|
||
|
E1000_WRITE_REG ( hw, RDLEN, sizeof ( struct e1000_tx_desc ) *
|
||
|
NUM_TX_DESC );
|
||
|
|
||
|
E1000_WRITE_REG ( hw, RDH, 0);
|
||
|
E1000_WRITE_REG ( hw, RDT, 0);
|
||
|
|
||
|
/* Enable Receives */
|
||
|
|
||
|
E1000_WRITE_REG ( hw, RCTL, rctl );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_configure - configure the hardware for RX and TX
|
||
|
* @adapter = private board structure
|
||
|
**/
|
||
|
static void e1000_configure ( struct e1000_adapter *adapter )
|
||
|
{
|
||
|
DBG ( "e1000_configure\n" );
|
||
|
|
||
|
e1000_configure_tx ( adapter );
|
||
|
|
||
|
e1000_setup_rctl ( adapter );
|
||
|
|
||
|
e1000_configure_rx ( adapter );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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_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;
|
||
|
|
||
|
adapter->hw.fc_high_water = fc_high_water_mark;
|
||
|
adapter->hw.fc_low_water = fc_high_water_mark - 8;
|
||
|
if (adapter->hw.mac_type == e1000_80003es2lan)
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/** Functions that implement the gPXE driver API **/
|
||
|
|
||
|
/**
|
||
|
* 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 );
|
||
|
|
||
|
DBG ( "e1000_close\n" );
|
||
|
|
||
|
e1000_reset ( adapter );
|
||
|
e1000_power_down_phy ( adapter );
|
||
|
|
||
|
e1000_free_tx_resources ( adapter );
|
||
|
e1000_free_rx_resources ( adapter );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_transmit - Transmit a packet
|
||
|
*
|
||
|
* @v netdev Network device
|
||
|
* @v iobuf I/O buffer
|
||
|
*
|
||
|
* @ret rc Return status code
|
||
|
*/
|
||
|
static int
|
||
|
e1000_transmit ( struct net_device *netdev, struct io_buffer *iobuf )
|
||
|
{
|
||
|
struct e1000_adapter *adapter = netdev_priv( netdev );
|
||
|
struct e1000_hw *hw = &adapter->hw;
|
||
|
|
||
|
DBG ("e1000_transmit\n");
|
||
|
|
||
|
if ( adapter->tx_fill_ctr == NUM_TX_DESC ) {
|
||
|
DBG ("TX overflow\n");
|
||
|
return -ENOBUFS;
|
||
|
}
|
||
|
|
||
|
/* Save pointer to iobuf we have been given to transmit,
|
||
|
netdev_tx_complete() will need it later
|
||
|
*/
|
||
|
adapter->tx_iobuf[adapter->tx_tail] = iobuf;
|
||
|
|
||
|
/* Add the packet to TX ring
|
||
|
*/
|
||
|
adapter->tx_desc[adapter->tx_tail]->buffer_addr =
|
||
|
virt_to_bus ( iobuf->data );
|
||
|
adapter->tx_desc[adapter->tx_tail]->lower.data =
|
||
|
E1000_TXD_CMD_RPS | E1000_TXD_CMD_RS | E1000_TXD_CMD_EOP |
|
||
|
E1000_TXD_CMD_IFCS | iob_len ( iobuf );
|
||
|
adapter->tx_desc[adapter->tx_tail]->upper.data = 0;
|
||
|
|
||
|
DBG ( "TX fill: %ld tail: %ld addr: %#08lx len: %d\n", adapter->tx_fill_ctr,
|
||
|
adapter->tx_tail, virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );
|
||
|
|
||
|
/* Point to next free descriptor */
|
||
|
adapter->tx_tail = ( adapter->tx_tail + 1 ) % NUM_TX_DESC;
|
||
|
|
||
|
adapter->tx_fill_ctr++;
|
||
|
|
||
|
/* Write new tail to NIC, making packet available for transmit
|
||
|
*/
|
||
|
E1000_WRITE_REG ( hw, TDT, adapter->tx_tail ) ;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_poll - Poll for received packets
|
||
|
*
|
||
|
* @v netdev Network device
|
||
|
*/
|
||
|
static void
|
||
|
e1000_poll ( struct net_device *netdev )
|
||
|
{
|
||
|
struct e1000_adapter *adapter = netdev_priv( netdev );
|
||
|
struct e1000_hw *hw = &adapter->hw;
|
||
|
|
||
|
uint32_t icr;
|
||
|
uint32_t tx_status;
|
||
|
uint32_t rx_status;
|
||
|
uint32_t rx_len;
|
||
|
uint32_t rx_err;
|
||
|
struct io_buffer *rx_iob;
|
||
|
|
||
|
uint32_t i;
|
||
|
|
||
|
#if 0
|
||
|
DBG ( "e1000_poll\n" );
|
||
|
#endif
|
||
|
|
||
|
/* Acknowledge interrupt. */
|
||
|
icr = E1000_READ_REG ( hw, ICR );
|
||
|
|
||
|
#if 0
|
||
|
DBG ( "e1000_poll: intr_status = %#08lx\n", icr );
|
||
|
#endif
|
||
|
|
||
|
/* Check status of transmitted packets
|
||
|
*/
|
||
|
while ( ( i = adapter->tx_head ) != adapter->tx_tail ) {
|
||
|
|
||
|
//tx_status = adapter->tx_desc[i]->upper.fields.status;
|
||
|
tx_status = adapter->tx_desc[i]->upper.data;
|
||
|
|
||
|
DBG ( "e1000_poll: tx_status = %#08lx\n", tx_status );
|
||
|
|
||
|
/* if the packet at tx_head is not owned by hardware */
|
||
|
if ( ! ( tx_status & E1000_TXD_STAT_DD ) )
|
||
|
break;
|
||
|
|
||
|
DBG ( "got packet. tx_head: %ld tx_tail: %ld tx_status: %#08lx\n",
|
||
|
adapter->tx_head, adapter->tx_tail, tx_status );
|
||
|
|
||
|
if ( tx_status & ( E1000_TXD_STAT_EC | E1000_TXD_STAT_LC |
|
||
|
E1000_TXD_STAT_TU ) ) {
|
||
|
netdev_tx_complete_err ( netdev, adapter->tx_iobuf[i], -EINVAL );
|
||
|
DBG ( "Error transmitting packet, tx_status: %#08lx\n",
|
||
|
tx_status );
|
||
|
} else {
|
||
|
netdev_tx_complete ( netdev, adapter->tx_iobuf[i] );
|
||
|
DBG ( "Success transmitting packet, tx_status: %#08lx\n",
|
||
|
tx_status );
|
||
|
}
|
||
|
|
||
|
/* Decrement count of used descriptors, clear this descriptor
|
||
|
*/
|
||
|
adapter->tx_fill_ctr--;
|
||
|
memset ( &adapter->tx_desc[i], 0, sizeof ( struct e1000_tx_desc ) );
|
||
|
|
||
|
adapter->tx_head = ( adapter->tx_head + 1 ) % NUM_TX_DESC;
|
||
|
}
|
||
|
|
||
|
/* Process received packets
|
||
|
*/
|
||
|
while ( ( rx_status = adapter->rx_desc[adapter->rx_tail]->status ) & E1000_RXD_STAT_DD ) {
|
||
|
|
||
|
i = adapter->rx_tail;
|
||
|
|
||
|
rx_len = adapter->rx_desc[i]->length;
|
||
|
|
||
|
DBG ( "Received packet, rx_tail: %ld rx_status: %#08lx rx_len: %ld\n",
|
||
|
i, rx_status, rx_len );
|
||
|
|
||
|
rx_err = adapter->rx_desc[adapter->rx_tail]->errors;
|
||
|
|
||
|
if ( rx_err & E1000_RXD_ERR_FRAME_ERR_MASK ) {
|
||
|
|
||
|
netdev_rx_err ( netdev, NULL, -EINVAL );
|
||
|
DBG ( "e1000_poll: Corrupted packet received!"
|
||
|
" rx_err: %#08lx\n", rx_err );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
/* If unable allocate space for this packet,
|
||
|
* try again next poll
|
||
|
*/
|
||
|
rx_iob = alloc_iob ( rx_len );
|
||
|
if ( ! rx_iob )
|
||
|
break;
|
||
|
|
||
|
memcpy ( iob_put ( rx_iob, rx_len ),
|
||
|
adapter->rx_iobuf[i]->data, rx_len );
|
||
|
|
||
|
/* Add this packet to the receive queue.
|
||
|
*/
|
||
|
netdev_rx ( netdev, rx_iob );
|
||
|
}
|
||
|
|
||
|
adapter->rx_tail = ( adapter->rx_tail + 1 ) % NUM_RX_DESC;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_irq - Enable, Disable, or Force interrupts
|
||
|
*
|
||
|
* @v adapter e1000 adapter
|
||
|
* @v action requested interrupt action
|
||
|
**/
|
||
|
static void
|
||
|
e1000_irq ( struct net_device *netdev, int enable )
|
||
|
{
|
||
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||
|
|
||
|
DBG ( "e1000_irq\n" );
|
||
|
|
||
|
switch ( enable ) {
|
||
|
case 0 :
|
||
|
E1000_WRITE_REG ( &adapter->hw, IMC, ~0 );
|
||
|
E1000_WRITE_FLUSH ( &adapter->hw );
|
||
|
break;
|
||
|
case 1 :
|
||
|
E1000_WRITE_REG ( &adapter->hw, IMS,
|
||
|
E1000_IMS_RXT0 | E1000_IMS_RXSEQ );
|
||
|
E1000_WRITE_FLUSH ( &adapter->hw );
|
||
|
break;
|
||
|
/* FIXME: Etherboot has a "FORCE" action, does gPXE? */
|
||
|
case 2 :
|
||
|
E1000_WRITE_REG ( &adapter->hw, ICS, E1000_ICS_RXT0 );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static struct net_device_operations e1000_operations;
|
||
|
|
||
|
/**
|
||
|
* e1000_probe - Initial configuration of e1000 NIC
|
||
|
*
|
||
|
* @v pci PCI device
|
||
|
* @v id PCI IDs
|
||
|
*
|
||
|
* @ret rc Return status code
|
||
|
**/
|
||
|
static int
|
||
|
e1000_probe ( struct pci_device *pdev,
|
||
|
const struct pci_device_id *id __unused )
|
||
|
{
|
||
|
int i, err;
|
||
|
struct net_device *netdev;
|
||
|
struct e1000_adapter *adapter;
|
||
|
unsigned long mmio_start, mmio_len;
|
||
|
unsigned long flash_start, flash_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;
|
||
|
|
||
|
pci_set_drvdata ( pdev, netdev );
|
||
|
|
||
|
adapter = netdev_priv ( netdev );
|
||
|
memset ( adapter, 0, ( sizeof ( struct e1000_adapter ) ) );
|
||
|
|
||
|
/* Enable PCI device associated with this NIC device */
|
||
|
adjust_pci_device ( pdev );
|
||
|
|
||
|
adapter->ioaddr = pdev->ioaddr;
|
||
|
adapter->irqno = pdev->irq;
|
||
|
adapter->netdev = netdev;
|
||
|
adapter->pdev = pdev;
|
||
|
adapter->hw.back = adapter;
|
||
|
|
||
|
mmio_start = pci_bar_start ( pdev, PCI_BASE_ADDRESS_0 );
|
||
|
mmio_len = pci_bar_size ( pdev, PCI_BASE_ADDRESS_0 );
|
||
|
|
||
|
err = -EIO;
|
||
|
|
||
|
adapter->hw.hw_addr = ioremap ( mmio_start, mmio_len );
|
||
|
if ( ! adapter->hw.hw_addr )
|
||
|
goto err_ioremap;
|
||
|
|
||
|
for ( i = BAR_1; i <= BAR_5; i++ ) {
|
||
|
if ( pci_bar_size ( pdev, i ) == 0 )
|
||
|
continue;
|
||
|
if ( pci_find_capability ( pdev, i ) & IORESOURCE_IO ) {
|
||
|
adapter->hw.io_base = pci_bar_start ( pdev, i );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Associate e1000-specific network operations operations with
|
||
|
* generic network device layer
|
||
|
*/
|
||
|
netdev_init ( netdev, &e1000_operations );
|
||
|
|
||
|
/* setup the private structure */
|
||
|
if ( ( err = e1000_sw_init ( adapter ) ) )
|
||
|
goto err_sw_init;
|
||
|
|
||
|
DBG ( "adapter->hw.mac_type: %#08x\n", adapter->hw.mac_type );
|
||
|
|
||
|
/* Flash BAR mapping must happen after e1000_sw_init
|
||
|
* because it depends on mac_type
|
||
|
*/
|
||
|
if ( ( adapter->hw.mac_type == e1000_ich8lan ) && ( pdev->ioaddr ) ) {
|
||
|
flash_start = pci_bar_start ( pdev, 1 );
|
||
|
flash_len = pci_bar_size ( pdev, 1 );
|
||
|
adapter->hw.flash_address = ioremap ( flash_start, flash_len );
|
||
|
if ( ! adapter->hw.flash_address )
|
||
|
goto err_flashmap;
|
||
|
}
|
||
|
|
||
|
/* initialize eeprom parameters */
|
||
|
if ( e1000_init_eeprom_params ( &adapter->hw ) ) {
|
||
|
DBG ( "EEPROM initialization failed\n" );
|
||
|
goto err_eeprom;
|
||
|
}
|
||
|
|
||
|
/* before reading the EEPROM, reset the controller to
|
||
|
* put the device in a known good starting state
|
||
|
*/
|
||
|
e1000_reset_hw ( &adapter->hw );
|
||
|
|
||
|
/* make sure the EEPROM is good */
|
||
|
if ( e1000_validate_eeprom_checksum( &adapter->hw ) < 0 ) {
|
||
|
DBG ( "The EEPROM Checksum Is Not Valid\n" );
|
||
|
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->ll_addr, adapter->hw.mac_addr, ETH_ALEN );
|
||
|
|
||
|
/* reset the hardware with the new settings */
|
||
|
e1000_reset ( adapter );
|
||
|
|
||
|
if ( ( err = register_netdev ( netdev ) ) != 0)
|
||
|
goto err_register;
|
||
|
|
||
|
/* No errors, return success */
|
||
|
return 0;
|
||
|
|
||
|
/* Error return paths */
|
||
|
err_register:
|
||
|
err_eeprom:
|
||
|
if ( ! e1000_check_phy_reset_block ( &adapter->hw ) )
|
||
|
e1000_phy_hw_reset ( &adapter->hw );
|
||
|
if ( adapter->hw.flash_address )
|
||
|
iounmap ( adapter->hw.flash_address );
|
||
|
err_flashmap:
|
||
|
err_sw_init:
|
||
|
iounmap ( adapter->hw.hw_addr );
|
||
|
err_ioremap:
|
||
|
netdev_put ( netdev );
|
||
|
err_alloc_etherdev:
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_remove - Device Removal Routine
|
||
|
*
|
||
|
* @v pdev PCI device information struct
|
||
|
*
|
||
|
**/
|
||
|
static 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" );
|
||
|
|
||
|
e1000_reset_hw ( &adapter->hw );
|
||
|
unregister_netdev ( netdev );
|
||
|
netdev_put ( netdev );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* e1000_open - Called when a network interface is made active
|
||
|
*
|
||
|
* @v netdev network interface device structure
|
||
|
* @ret rc Return status code, 0 on success, negative value on failure
|
||
|
*
|
||
|
**/
|
||
|
static int
|
||
|
e1000_open ( struct net_device *netdev )
|
||
|
{
|
||
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||
|
int err;
|
||
|
|
||
|
DBG ( "e1000_open\n" );
|
||
|
|
||
|
/* allocate transmit descriptors */
|
||
|
err = e1000_setup_tx_resources ( adapter );
|
||
|
if (err)
|
||
|
goto err_setup_tx;
|
||
|
|
||
|
/* allocate receive descriptors */
|
||
|
err = e1000_setup_rx_resources ( adapter );
|
||
|
if (err)
|
||
|
goto err_setup_rx;
|
||
|
|
||
|
e1000_power_up_phy ( adapter );
|
||
|
|
||
|
/* disable firmware control */
|
||
|
e1000_init_manageability ( adapter );
|
||
|
|
||
|
e1000_configure ( adapter );
|
||
|
|
||
|
return E1000_SUCCESS;
|
||
|
|
||
|
err_setup_rx:
|
||
|
e1000_free_tx_resources ( adapter );
|
||
|
err_setup_tx:
|
||
|
e1000_reset ( adapter );
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
struct pci_driver e1000_driver __pci_driver = {
|
||
|
.ids = e1000_nics,
|
||
|
.id_count = (sizeof (e1000_nics) / sizeof (e1000_nics[0])),
|
||
|
.probe = e1000_probe,
|
||
|
.remove = e1000_remove,
|
||
|
};
|
||
|
|
||
|
/** e1000 net device operations */
|
||
|
static struct net_device_operations e1000_operations = {
|
||
|
.open = e1000_open,
|
||
|
.close = e1000_close,
|
||
|
.transmit = e1000_transmit,
|
||
|
.poll = e1000_poll,
|
||
|
.irq = e1000_irq,
|
||
|
};
|
||
|
|
||
|
int32_t
|
||
|
e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
|
||
|
{
|
||
|
struct e1000_adapter *adapter = hw->back;
|
||
|
uint16_t cap_offset;
|
||
|
|
||
|
#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
|
||
|
cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
|
||
|
if (!cap_offset)
|
||
|
return -E1000_ERR_CONFIG;
|
||
|
|
||
|
pci_read_config_word(adapter->pdev, cap_offset + reg, value);
|
||
|
|
||
|
return E1000_SUCCESS;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e1000_pci_clear_mwi ( struct e1000_hw *hw __unused )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e1000_pci_set_mwi ( struct e1000_hw *hw __unused )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
|
||
|
{
|
||
|
struct e1000_adapter *adapter = hw->back;
|
||
|
|
||
|
pci_read_config_word(adapter->pdev, reg, value);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
|
||
|
{
|
||
|
struct e1000_adapter *adapter = hw->back;
|
||
|
|
||
|
pci_write_config_word(adapter->pdev, reg, *value);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
e1000_io_write ( struct e1000_hw *hw __unused, unsigned long port, uint32_t value )
|
||
|
{
|
||
|
outl ( value, port );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Local variables:
|
||
|
* c-basic-offset: 8
|
||
|
* c-indent-level: 8
|
||
|
* tab-width: 8
|
||
|
* End:
|
||
|
*/
|