Commit 2d7edb92 authored by Malli Chilakala's avatar Malli Chilakala Committed by Jeff Garzik

[PATCH] e1000:82573 specific code & packet split code

82573 specific code & packet split code
Signed-off-by: default avatarMallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Signed-off-by: default avatarGanesh Venkatesan <ganesh.venkatesan@intel.com>
Signed-off-by: default avatarJohn Ronciak <john.ronciak@intel.com>
diff -up net-drivers-2.6/drivers/net/e1000/e1000.h net-drivers-2.6/drivers/net/e1000.new/e1000.h
parent f0d11ed0
...@@ -112,6 +112,8 @@ struct e1000_adapter; ...@@ -112,6 +112,8 @@ struct e1000_adapter;
#define E1000_MAX_82544_RXD 4096 #define E1000_MAX_82544_RXD 4096
/* Supported Rx Buffer Sizes */ /* Supported Rx Buffer Sizes */
#define E1000_RXBUFFER_128 128 /* Used for packet split */
#define E1000_RXBUFFER_256 256 /* Used for packet split */
#define E1000_RXBUFFER_2048 2048 #define E1000_RXBUFFER_2048 2048
#define E1000_RXBUFFER_4096 4096 #define E1000_RXBUFFER_4096 4096
#define E1000_RXBUFFER_8192 8192 #define E1000_RXBUFFER_8192 8192
...@@ -146,6 +148,10 @@ struct e1000_adapter; ...@@ -146,6 +148,10 @@ struct e1000_adapter;
#define E1000_MASTER_SLAVE e1000_ms_hw_default #define E1000_MASTER_SLAVE e1000_ms_hw_default
#endif #endif
#define E1000_MNG_VLAN_NONE -1
/* Number of packet split data buffers (not including the header buffer) */
#define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1
/* only works for sizes that are powers of 2 */ /* only works for sizes that are powers of 2 */
#define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
...@@ -159,6 +165,9 @@ struct e1000_buffer { ...@@ -159,6 +165,9 @@ struct e1000_buffer {
uint16_t next_to_watch; uint16_t next_to_watch;
}; };
struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; };
struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; };
struct e1000_desc_ring { struct e1000_desc_ring {
/* pointer to the descriptor ring memory */ /* pointer to the descriptor ring memory */
void *desc; void *desc;
...@@ -174,12 +183,19 @@ struct e1000_desc_ring { ...@@ -174,12 +183,19 @@ struct e1000_desc_ring {
unsigned int next_to_clean; unsigned int next_to_clean;
/* array of buffer information structs */ /* array of buffer information structs */
struct e1000_buffer *buffer_info; struct e1000_buffer *buffer_info;
/* arrays of page information for packet split */
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
}; };
#define E1000_DESC_UNUSED(R) \ #define E1000_DESC_UNUSED(R) \
((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \ ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
(R)->next_to_clean - (R)->next_to_use - 1) (R)->next_to_clean - (R)->next_to_use - 1)
#define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
#define E1000_RX_DESC_EXT(R, i) \
(&(((union e1000_rx_desc_extended *)((R).desc))[i]))
#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc) #define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
#define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc) #define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc)
...@@ -192,6 +208,7 @@ struct e1000_adapter { ...@@ -192,6 +208,7 @@ struct e1000_adapter {
struct timer_list watchdog_timer; struct timer_list watchdog_timer;
struct timer_list phy_info_timer; struct timer_list phy_info_timer;
struct vlan_group *vlgrp; struct vlan_group *vlgrp;
uint16_t mng_vlan_id;
uint32_t bd_number; uint32_t bd_number;
uint32_t rx_buffer_len; uint32_t rx_buffer_len;
uint32_t part_num; uint32_t part_num;
...@@ -228,14 +245,23 @@ struct e1000_adapter { ...@@ -228,14 +245,23 @@ struct e1000_adapter {
boolean_t detect_tx_hung; boolean_t detect_tx_hung;
/* RX */ /* RX */
#ifdef CONFIG_E1000_NAPI
boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done,
int work_to_do);
#else
boolean_t (*clean_rx) (struct e1000_adapter *adapter);
#endif
void (*alloc_rx_buf) (struct e1000_adapter *adapter);
struct e1000_desc_ring rx_ring; struct e1000_desc_ring rx_ring;
uint64_t hw_csum_err; uint64_t hw_csum_err;
uint64_t hw_csum_good; uint64_t hw_csum_good;
uint32_t rx_int_delay; uint32_t rx_int_delay;
uint32_t rx_abs_int_delay; uint32_t rx_abs_int_delay;
boolean_t rx_csum; boolean_t rx_csum;
boolean_t rx_ps;
uint32_t gorcl; uint32_t gorcl;
uint64_t gorcl_old; uint64_t gorcl_old;
uint16_t rx_ps_bsize0;
/* Interrupt Throttle Rate */ /* Interrupt Throttle Rate */
uint32_t itr; uint32_t itr;
......
...@@ -63,10 +63,11 @@ static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count); ...@@ -63,10 +63,11 @@ static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count);
static int32_t e1000_acquire_eeprom(struct e1000_hw *hw); static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
static void e1000_release_eeprom(struct e1000_hw *hw); static void e1000_release_eeprom(struct e1000_hw *hw);
static void e1000_standby_eeprom(struct e1000_hw *hw); static void e1000_standby_eeprom(struct e1000_hw *hw);
static int32_t e1000_id_led_init(struct e1000_hw * hw);
static int32_t e1000_set_vco_speed(struct e1000_hw *hw); static int32_t e1000_set_vco_speed(struct e1000_hw *hw);
static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw); static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);
static int32_t e1000_set_phy_mode(struct e1000_hw *hw); static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
/* IGP cable length table */ /* IGP cable length table */
static const static const
...@@ -80,6 +81,17 @@ uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = ...@@ -80,6 +81,17 @@ uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120}; 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
static const
uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
{ 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43,
22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58,
32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74,
43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90,
57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108,
73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124,
91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128,
108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
/****************************************************************************** /******************************************************************************
* Set the phy type member in the hw struct. * Set the phy type member in the hw struct.
...@@ -91,10 +103,14 @@ e1000_set_phy_type(struct e1000_hw *hw) ...@@ -91,10 +103,14 @@ e1000_set_phy_type(struct e1000_hw *hw)
{ {
DEBUGFUNC("e1000_set_phy_type"); DEBUGFUNC("e1000_set_phy_type");
if(hw->mac_type == e1000_undefined)
return -E1000_ERR_PHY_TYPE;
switch(hw->phy_id) { switch(hw->phy_id) {
case M88E1000_E_PHY_ID: case M88E1000_E_PHY_ID:
case M88E1000_I_PHY_ID: case M88E1000_I_PHY_ID:
case M88E1011_I_PHY_ID: case M88E1011_I_PHY_ID:
case M88E1111_I_PHY_ID:
hw->phy_type = e1000_phy_m88; hw->phy_type = e1000_phy_m88;
break; break;
case IGP01E1000_I_PHY_ID: case IGP01E1000_I_PHY_ID:
...@@ -271,6 +287,7 @@ e1000_set_mac_type(struct e1000_hw *hw) ...@@ -271,6 +287,7 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82546GB_FIBER: case E1000_DEV_ID_82546GB_FIBER:
case E1000_DEV_ID_82546GB_SERDES: case E1000_DEV_ID_82546GB_SERDES:
case E1000_DEV_ID_82546GB_PCIE: case E1000_DEV_ID_82546GB_PCIE:
case E1000_DEV_ID_82546GB_QUAD_COPPER:
hw->mac_type = e1000_82546_rev_3; hw->mac_type = e1000_82546_rev_3;
break; break;
case E1000_DEV_ID_82541EI: case E1000_DEV_ID_82541EI:
...@@ -289,12 +306,19 @@ e1000_set_mac_type(struct e1000_hw *hw) ...@@ -289,12 +306,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82547GI: case E1000_DEV_ID_82547GI:
hw->mac_type = e1000_82547_rev_2; hw->mac_type = e1000_82547_rev_2;
break; break;
case E1000_DEV_ID_82573E:
case E1000_DEV_ID_82573E_IAMT:
hw->mac_type = e1000_82573;
break;
default: default:
/* Should never have loaded on this device */ /* Should never have loaded on this device */
return -E1000_ERR_MAC_TYPE; return -E1000_ERR_MAC_TYPE;
} }
switch(hw->mac_type) { switch(hw->mac_type) {
case e1000_82573:
hw->eeprom_semaphore_present = TRUE;
/* fall through */
case e1000_82541: case e1000_82541:
case e1000_82547: case e1000_82547:
case e1000_82541_rev_2: case e1000_82541_rev_2:
...@@ -360,6 +384,9 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -360,6 +384,9 @@ e1000_reset_hw(struct e1000_hw *hw)
uint32_t icr; uint32_t icr;
uint32_t manc; uint32_t manc;
uint32_t led_ctrl; uint32_t led_ctrl;
uint32_t timeout;
uint32_t extcnf_ctrl;
int32_t ret_val;
DEBUGFUNC("e1000_reset_hw"); DEBUGFUNC("e1000_reset_hw");
...@@ -369,6 +396,15 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -369,6 +396,15 @@ e1000_reset_hw(struct e1000_hw *hw)
e1000_pci_clear_mwi(hw); e1000_pci_clear_mwi(hw);
} }
if(hw->bus_type == e1000_bus_type_pci_express) {
/* Prevent the PCI-E bus from sticking if there is no TLP connection
* on the last TLP read/write transaction when MAC is reset.
*/
if(e1000_disable_pciex_master(hw) != E1000_SUCCESS) {
DEBUGOUT("PCI-E Master disable polling has failed.\n");
}
}
/* Clear interrupt mask to stop board from generating interrupts */ /* Clear interrupt mask to stop board from generating interrupts */
DEBUGOUT("Masking off all interrupts\n"); DEBUGOUT("Masking off all interrupts\n");
E1000_WRITE_REG(hw, IMC, 0xffffffff); E1000_WRITE_REG(hw, IMC, 0xffffffff);
...@@ -393,10 +429,32 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -393,10 +429,32 @@ e1000_reset_hw(struct e1000_hw *hw)
/* Must reset the PHY before resetting the MAC */ /* Must reset the PHY before resetting the MAC */
if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST)); E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
msec_delay(5); msec_delay(5);
} }
/* Must acquire the MDIO ownership before MAC reset.
* Ownership defaults to firmware after a reset. */
if(hw->mac_type == e1000_82573) {
timeout = 10;
extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
do {
E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
if(extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
break;
else
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
msec_delay(2);
timeout--;
} while(timeout);
}
/* Issue a global reset to the MAC. This will reset the chip's /* Issue a global reset to the MAC. This will reset the chip's
* transmit, receive, DMA, and link units. It will not effect * transmit, receive, DMA, and link units. It will not effect
* the current PCI configuration. The global reset bit is self- * the current PCI configuration. The global reset bit is self-
...@@ -450,6 +508,18 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -450,6 +508,18 @@ e1000_reset_hw(struct e1000_hw *hw)
/* Wait for EEPROM reload */ /* Wait for EEPROM reload */
msec_delay(20); msec_delay(20);
break; break;
case e1000_82573:
udelay(10);
ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
ctrl_ext |= E1000_CTRL_EXT_EE_RST;
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
/* fall through */
ret_val = e1000_get_auto_rd_done(hw);
if(ret_val)
/* We don't want to continue accessing MAC registers. */
return ret_val;
break;
default: default:
/* Wait for EEPROM reload (it happens automatically) */ /* Wait for EEPROM reload (it happens automatically) */
msec_delay(5); msec_delay(5);
...@@ -457,7 +527,7 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -457,7 +527,7 @@ e1000_reset_hw(struct e1000_hw *hw)
} }
/* Disable HW ARPs on ASF enabled adapters */ /* Disable HW ARPs on ASF enabled adapters */
if(hw->mac_type >= e1000_82540) { if(hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) {
manc = E1000_READ_REG(hw, MANC); manc = E1000_READ_REG(hw, MANC);
manc &= ~(E1000_MANC_ARP_EN); manc &= ~(E1000_MANC_ARP_EN);
E1000_WRITE_REG(hw, MANC, manc); E1000_WRITE_REG(hw, MANC, manc);
...@@ -510,6 +580,8 @@ e1000_init_hw(struct e1000_hw *hw) ...@@ -510,6 +580,8 @@ e1000_init_hw(struct e1000_hw *hw)
uint16_t pcix_stat_hi_word; uint16_t pcix_stat_hi_word;
uint16_t cmd_mmrbc; uint16_t cmd_mmrbc;
uint16_t stat_mmrbc; uint16_t stat_mmrbc;
uint32_t mta_size;
DEBUGFUNC("e1000_init_hw"); DEBUGFUNC("e1000_init_hw");
/* Initialize Identification LED */ /* Initialize Identification LED */
...@@ -524,8 +596,8 @@ e1000_init_hw(struct e1000_hw *hw) ...@@ -524,8 +596,8 @@ e1000_init_hw(struct e1000_hw *hw)
/* Disabling VLAN filtering. */ /* Disabling VLAN filtering. */
DEBUGOUT("Initializing the IEEE VLAN\n"); DEBUGOUT("Initializing the IEEE VLAN\n");
E1000_WRITE_REG(hw, VET, 0); if (hw->mac_type < e1000_82545_rev_3)
E1000_WRITE_REG(hw, VET, 0);
e1000_clear_vfta(hw); e1000_clear_vfta(hw);
/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */ /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
...@@ -553,14 +625,16 @@ e1000_init_hw(struct e1000_hw *hw) ...@@ -553,14 +625,16 @@ e1000_init_hw(struct e1000_hw *hw)
/* Zero out the Multicast HASH table */ /* Zero out the Multicast HASH table */
DEBUGOUT("Zeroing the MTA\n"); DEBUGOUT("Zeroing the MTA\n");
for(i = 0; i < E1000_MC_TBL_SIZE; i++) mta_size = E1000_MC_TBL_SIZE;
for(i = 0; i < mta_size; i++)
E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
/* Set the PCI priority bit correctly in the CTRL register. This /* Set the PCI priority bit correctly in the CTRL register. This
* determines if the adapter gives priority to receives, or if it * determines if the adapter gives priority to receives, or if it
* gives equal priority to transmits and receives. * gives equal priority to transmits and receives. Valid only on
* 82542 and 82543 silicon.
*/ */
if(hw->dma_fairness) { if(hw->dma_fairness && hw->mac_type <= e1000_82543) {
ctrl = E1000_READ_REG(hw, CTRL); ctrl = E1000_READ_REG(hw, CTRL);
E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR); E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
} }
...@@ -598,9 +672,21 @@ e1000_init_hw(struct e1000_hw *hw) ...@@ -598,9 +672,21 @@ e1000_init_hw(struct e1000_hw *hw)
if(hw->mac_type > e1000_82544) { if(hw->mac_type > e1000_82544) {
ctrl = E1000_READ_REG(hw, TXDCTL); ctrl = E1000_READ_REG(hw, TXDCTL);
ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
switch (hw->mac_type) {
default:
break;
case e1000_82573:
ctrl |= E1000_TXDCTL_COUNT_DESC;
break;
}
E1000_WRITE_REG(hw, TXDCTL, ctrl); E1000_WRITE_REG(hw, TXDCTL, ctrl);
} }
if (hw->mac_type == e1000_82573) {
e1000_enable_tx_pkt_filtering(hw);
}
/* Clear all of the statistics registers (clear on read). It is /* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link * important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there * because the symbol error count will increment wildly if there
...@@ -679,7 +765,7 @@ e1000_setup_link(struct e1000_hw *hw) ...@@ -679,7 +765,7 @@ e1000_setup_link(struct e1000_hw *hw)
* control setting, then the variable hw->fc will * control setting, then the variable hw->fc will
* be initialized based on a value in the EEPROM. * be initialized based on a value in the EEPROM.
*/ */
if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 0) { if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) {
DEBUGOUT("EEPROM Read Error\n"); DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
...@@ -736,6 +822,7 @@ e1000_setup_link(struct e1000_hw *hw) ...@@ -736,6 +822,7 @@ e1000_setup_link(struct e1000_hw *hw)
E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW); E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH); E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE); E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time); E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
/* Set the flow control receive threshold registers. Normally, /* Set the flow control receive threshold registers. Normally,
...@@ -906,20 +993,18 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw) ...@@ -906,20 +993,18 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
} }
/****************************************************************************** /******************************************************************************
* Detects which PHY is present and the speed and duplex * Make sure we have a valid PHY and change PHY mode before link setup.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
******************************************************************************/ ******************************************************************************/
static int32_t static int32_t
e1000_setup_copper_link(struct e1000_hw *hw) e1000_copper_link_preconfig(struct e1000_hw *hw)
{ {
uint32_t ctrl; uint32_t ctrl;
uint32_t led_ctrl;
int32_t ret_val; int32_t ret_val;
uint16_t i;
uint16_t phy_data; uint16_t phy_data;
DEBUGFUNC("e1000_setup_copper_link"); DEBUGFUNC("e1000_copper_link_preconfig");
ctrl = E1000_READ_REG(hw, CTRL); ctrl = E1000_READ_REG(hw, CTRL);
/* With 82543, we need to force speed and duplex on the MAC equal to what /* With 82543, we need to force speed and duplex on the MAC equal to what
...@@ -933,7 +1018,9 @@ e1000_setup_copper_link(struct e1000_hw *hw) ...@@ -933,7 +1018,9 @@ e1000_setup_copper_link(struct e1000_hw *hw)
} else { } else {
ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU); ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
E1000_WRITE_REG(hw, CTRL, ctrl); E1000_WRITE_REG(hw, CTRL, ctrl);
e1000_phy_hw_reset(hw); ret_val = e1000_phy_hw_reset(hw);
if(ret_val)
return ret_val;
} }
/* Make sure we have a valid PHY */ /* Make sure we have a valid PHY */
...@@ -961,354 +1048,452 @@ e1000_setup_copper_link(struct e1000_hw *hw) ...@@ -961,354 +1048,452 @@ e1000_setup_copper_link(struct e1000_hw *hw)
hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
hw->phy_reset_disable = FALSE; hw->phy_reset_disable = FALSE;
if(!hw->phy_reset_disable) { return E1000_SUCCESS;
if (hw->phy_type == e1000_phy_igp) { }
ret_val = e1000_phy_reset(hw);
if(ret_val) {
DEBUGOUT("Error Resetting the PHY\n");
return ret_val;
}
/* Wait 10ms for MAC to configure PHY from eeprom settings */
msec_delay(15);
/* Configure activity LED after PHY reset */
led_ctrl = E1000_READ_REG(hw, LEDCTL);
led_ctrl &= IGP_ACTIVITY_LED_MASK;
led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
/* disable lplu d3 during driver init */ /********************************************************************
ret_val = e1000_set_d3_lplu_state(hw, FALSE); * Copper link setup for e1000_phy_igp series.
if(ret_val) { *
DEBUGOUT("Error Disabling LPLU D3\n"); * hw - Struct containing variables accessed by shared code
return ret_val; *********************************************************************/
} static int32_t
e1000_copper_link_igp_setup(struct e1000_hw *hw)
{
uint32_t led_ctrl;
int32_t ret_val;
uint16_t phy_data;
/* Configure mdi-mdix settings */ DEBUGFUNC("e1000_copper_link_igp_setup");
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
&phy_data);
if(ret_val)
return ret_val;
if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { if (hw->phy_reset_disable)
hw->dsp_config_state = e1000_dsp_config_disabled; return E1000_SUCCESS;
/* Force MDI for earlier revs of the IGP PHY */
phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | ret_val = e1000_phy_reset(hw);
IGP01E1000_PSCR_FORCE_MDI_MDIX); if (ret_val) {
hw->mdix = 1; DEBUGOUT("Error Resetting the PHY\n");
return ret_val;
}
} else { /* Wait 10ms for MAC to configure PHY from eeprom settings */
hw->dsp_config_state = e1000_dsp_config_enabled; msec_delay(15);
phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
switch (hw->mdix) {
case 1:
phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
break;
case 2:
phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
break;
case 0:
default:
phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
break;
}
}
ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
phy_data);
if(ret_val)
return ret_val;
/* set auto-master slave resolution settings */ /* Configure activity LED after PHY reset */
if(hw->autoneg) { led_ctrl = E1000_READ_REG(hw, LEDCTL);
e1000_ms_type phy_ms_setting = hw->master_slave; led_ctrl &= IGP_ACTIVITY_LED_MASK;
led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
if(hw->ffe_config_state == e1000_ffe_config_active) /* disable lplu d3 during driver init */
hw->ffe_config_state = e1000_ffe_config_enabled; ret_val = e1000_set_d3_lplu_state(hw, FALSE);
if (ret_val) {
DEBUGOUT("Error Disabling LPLU D3\n");
return ret_val;
}
if(hw->dsp_config_state == e1000_dsp_config_activated) /* disable lplu d0 during driver init */
hw->dsp_config_state = e1000_dsp_config_enabled; ret_val = e1000_set_d0_lplu_state(hw, FALSE);
if (ret_val) {
DEBUGOUT("Error Disabling LPLU D0\n");
return ret_val;
}
/* Configure mdi-mdix settings */
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
if (ret_val)
return ret_val;
/* when autonegotiation advertisment is only 1000Mbps then we if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
* should disable SmartSpeed and enable Auto MasterSlave hw->dsp_config_state = e1000_dsp_config_disabled;
* resolution as hardware default. */ /* Force MDI for earlier revs of the IGP PHY */
if(hw->autoneg_advertised == ADVERTISE_1000_FULL) { phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | IGP01E1000_PSCR_FORCE_MDI_MDIX);
/* Disable SmartSpeed */ hw->mdix = 1;
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&phy_data);
if(ret_val)
return ret_val;
phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1000_write_phy_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
phy_data);
if(ret_val)
return ret_val;
/* Set auto Master/Slave resolution process */
ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
if(ret_val)
return ret_val;
phy_data &= ~CR_1000T_MS_ENABLE;
ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
if(ret_val)
return ret_val;
}
ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); } else {
if(ret_val) hw->dsp_config_state = e1000_dsp_config_enabled;
return ret_val; phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
/* load defaults for future use */ switch (hw->mdix) {
hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ? case 1:
((phy_data & CR_1000T_MS_VALUE) ? phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
e1000_ms_force_master : break;
e1000_ms_force_slave) : case 2:
e1000_ms_auto; phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
break;
switch (phy_ms_setting) { case 0:
case e1000_ms_force_master: default:
phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
break; break;
case e1000_ms_force_slave: }
phy_data |= CR_1000T_MS_ENABLE; }
phy_data &= ~(CR_1000T_MS_VALUE); ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
break; if(ret_val)
case e1000_ms_auto: return ret_val;
phy_data &= ~CR_1000T_MS_ENABLE;
default:
break;
}
ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
if(ret_val)
return ret_val;
}
} else {
/* Enable CRS on TX. This must be set for half-duplex operation. */
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
&phy_data);
if(ret_val)
return ret_val;
phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; /* set auto-master slave resolution settings */
if(hw->autoneg) {
e1000_ms_type phy_ms_setting = hw->master_slave;
/* Options: if(hw->ffe_config_state == e1000_ffe_config_active)
* MDI/MDI-X = 0 (default) hw->ffe_config_state = e1000_ffe_config_enabled;
* 0 - Auto for all speeds
* 1 - MDI mode
* 2 - MDI-X mode
* 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
*/
phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
switch (hw->mdix) { if(hw->dsp_config_state == e1000_dsp_config_activated)
case 1: hw->dsp_config_state = e1000_dsp_config_enabled;
phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
break;
case 2:
phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
break;
case 3:
phy_data |= M88E1000_PSCR_AUTO_X_1000T;
break;
case 0:
default:
phy_data |= M88E1000_PSCR_AUTO_X_MODE;
break;
}
/* Options: /* when autonegotiation advertisment is only 1000Mbps then we
* disable_polarity_correction = 0 (default) * should disable SmartSpeed and enable Auto MasterSlave
* Automatic Correction for Reversed Cable Polarity * resolution as hardware default. */
* 0 - Disabled if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
* 1 - Enabled /* Disable SmartSpeed */
*/ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
if(hw->disable_polarity_correction == 1)
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
/* Force TX_CLK in the Extended PHY Specific Control Register ret_val = e1000_write_phy_reg(hw,
* to 25MHz clock. IGP01E1000_PHY_PORT_CONFIG,
*/ phy_data);
ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
&phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
/* Set auto Master/Slave resolution process */
ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
if(ret_val)
return ret_val;
phy_data &= ~CR_1000T_MS_ENABLE;
ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
if(ret_val)
return ret_val;
}
phy_data |= M88E1000_EPSCR_TX_CLK_25; ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
if(ret_val)
return ret_val;
if (hw->phy_revision < M88E1011_I_REV_4) { /* load defaults for future use */
/* Configure Master and Slave downshift values */ hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | ((phy_data & CR_1000T_MS_VALUE) ?
M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); e1000_ms_force_master :
phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | e1000_ms_force_slave) :
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); e1000_ms_auto;
ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
phy_data);
if(ret_val)
return ret_val;
}
/* SW Reset the PHY so all changes take effect */ switch (phy_ms_setting) {
ret_val = e1000_phy_reset(hw); case e1000_ms_force_master:
if(ret_val) { phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
DEBUGOUT("Error Resetting the PHY\n"); break;
return ret_val; case e1000_ms_force_slave:
} phy_data |= CR_1000T_MS_ENABLE;
phy_data &= ~(CR_1000T_MS_VALUE);
break;
case e1000_ms_auto:
phy_data &= ~CR_1000T_MS_ENABLE;
default:
break;
}
ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
if(ret_val)
return ret_val;
} }
/* Options: return E1000_SUCCESS;
* autoneg = 1 (default) }
* PHY will advertise value(s) parsed from
* autoneg_advertised and fc
* autoneg = 0
* PHY will be set to 10H, 10F, 100H, or 100F
* depending on value parsed from forced_speed_duplex.
*/
/* Is autoneg enabled? This is enabled by default or by software
* override. If so, call e1000_phy_setup_autoneg routine to parse the
* autoneg_advertised and fc options. If autoneg is NOT enabled, then
* the user should have provided a speed/duplex override. If so, then
* call e1000_phy_force_speed_duplex to parse and set this up.
*/
if(hw->autoneg) {
/* Perform some bounds checking on the hw->autoneg_advertised
* parameter. If this variable is zero, then set it to the default.
*/
hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
/* If autoneg_advertised is zero, we assume it was not defaulted /********************************************************************
* by the calling code so we set to advertise full capability. * Copper link setup for e1000_phy_m88 series.
*/ *
if(hw->autoneg_advertised == 0) * hw - Struct containing variables accessed by shared code
hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; *********************************************************************/
static int32_t
e1000_copper_link_mgp_setup(struct e1000_hw *hw)
{
int32_t ret_val;
uint16_t phy_data;
DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); DEBUGFUNC("e1000_copper_link_mgp_setup");
ret_val = e1000_phy_setup_autoneg(hw);
if(ret_val) {
DEBUGOUT("Error Setting up Auto-Negotiation\n");
return ret_val;
}
DEBUGOUT("Restarting Auto-Neg\n");
/* Restart auto-negotiation by setting the Auto Neg Enable bit and if(hw->phy_reset_disable)
* the Auto Neg Restart bit in the PHY control register. return E1000_SUCCESS;
*/
ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); /* Enable CRS on TX. This must be set for half-duplex operation. */
if(ret_val) ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
return ret_val; if(ret_val)
return ret_val;
phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
if(ret_val)
return ret_val;
/* Does the user want to wait for Auto-Neg to complete here, or /* Options:
* check at a later time (for example, callback routine). * MDI/MDI-X = 0 (default)
*/ * 0 - Auto for all speeds
if(hw->wait_autoneg_complete) { * 1 - MDI mode
ret_val = e1000_wait_autoneg(hw); * 2 - MDI-X mode
if(ret_val) { * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
DEBUGOUT("Error while waiting for autoneg to complete\n"); */
return ret_val; phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
}
}
hw->get_link_status = TRUE;
} else {
DEBUGOUT("Forcing speed and duplex\n");
ret_val = e1000_phy_force_speed_duplex(hw);
if(ret_val) {
DEBUGOUT("Error Forcing Speed and Duplex\n");
return ret_val;
}
}
} /* !hw->phy_reset_disable */
/* Check link status. Wait up to 100 microseconds for link to become switch (hw->mdix) {
* valid. case 1:
phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
break;
case 2:
phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
break;
case 3:
phy_data |= M88E1000_PSCR_AUTO_X_1000T;
break;
case 0:
default:
phy_data |= M88E1000_PSCR_AUTO_X_MODE;
break;
}
/* Options:
* disable_polarity_correction = 0 (default)
* Automatic Correction for Reversed Cable Polarity
* 0 - Disabled
* 1 - Enabled
*/ */
for(i = 0; i < 10; i++) { phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); if(hw->disable_polarity_correction == 1)
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
/* Force TX_CLK in the Extended PHY Specific Control Register
* to 25MHz clock.
*/
ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
if(ret_val)
return ret_val;
phy_data |= M88E1000_EPSCR_TX_CLK_25;
if (hw->phy_revision < M88E1011_I_REV_4) {
/* Configure Master and Slave downshift values */
phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
}
if(phy_data & MII_SR_LINK_STATUS) { /* SW Reset the PHY so all changes take effect */
/* We have link, so we need to finish the config process: ret_val = e1000_phy_reset(hw);
* 1) Set up the MAC to the current PHY speed/duplex if(ret_val) {
* if we are on 82543. If we DEBUGOUT("Error Resetting the PHY\n");
* are on newer silicon, we only need to configure return ret_val;
* collision distance in the Transmit Control Register.
* 2) Set up flow control on the MAC to that established with
* the link partner.
*/
if(hw->mac_type >= e1000_82544) {
e1000_config_collision_dist(hw);
} else {
ret_val = e1000_config_mac_to_phy(hw);
if(ret_val) {
DEBUGOUT("Error configuring MAC to PHY settings\n");
return ret_val;
}
}
ret_val = e1000_config_fc_after_link_up(hw);
if(ret_val) {
DEBUGOUT("Error Configuring Flow Control\n");
return ret_val;
}
DEBUGOUT("Valid link established!!!\n");
if(hw->phy_type == e1000_phy_igp) {
ret_val = e1000_config_dsp_after_link_change(hw, TRUE);
if(ret_val) {
DEBUGOUT("Error Configuring DSP after link up\n");
return ret_val;
}
}
DEBUGOUT("Valid link established!!!\n");
return E1000_SUCCESS;
}
udelay(10);
} }
DEBUGOUT("Unable to establish link!!!\n"); return E1000_SUCCESS;
return E1000_SUCCESS;
} }
/****************************************************************************** /********************************************************************
* Configures PHY autoneg and flow control advertisement settings * Setup auto-negotiation and flow control advertisements,
* and then perform auto-negotiation.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
******************************************************************************/ *********************************************************************/
int32_t static int32_t
e1000_phy_setup_autoneg(struct e1000_hw *hw) e1000_copper_link_autoneg(struct e1000_hw *hw)
{ {
int32_t ret_val; int32_t ret_val;
uint16_t mii_autoneg_adv_reg; uint16_t phy_data;
uint16_t mii_1000t_ctrl_reg;
DEBUGFUNC("e1000_phy_setup_autoneg"); DEBUGFUNC("e1000_copper_link_autoneg");
/* Read the MII Auto-Neg Advertisement Register (Address 4). */ /* Perform some bounds checking on the hw->autoneg_advertised
ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); * parameter. If this variable is zero, then set it to the default.
*/
hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
/* If autoneg_advertised is zero, we assume it was not defaulted
* by the calling code so we set to advertise full capability.
*/
if(hw->autoneg_advertised == 0)
hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
ret_val = e1000_phy_setup_autoneg(hw);
if(ret_val) {
DEBUGOUT("Error Setting up Auto-Negotiation\n");
return ret_val;
}
DEBUGOUT("Restarting Auto-Neg\n");
/* Restart auto-negotiation by setting the Auto Neg Enable bit and
* the Auto Neg Restart bit in the PHY control register.
*/
ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
/* Read the MII 1000Base-T Control Register (Address 9). */ phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg); ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
/* Need to parse both autoneg_advertised and fc and set up /* Does the user want to wait for Auto-Neg to complete here, or
* the appropriate PHY registers. First we will parse for * check at a later time (for example, callback routine).
*/
if(hw->wait_autoneg_complete) {
ret_val = e1000_wait_autoneg(hw);
if(ret_val) {
DEBUGOUT("Error while waiting for autoneg to complete\n");
return ret_val;
}
}
hw->get_link_status = TRUE;
return E1000_SUCCESS;
}
/******************************************************************************
* Config the MAC and the PHY after link is up.
* 1) Set up the MAC to the current PHY speed/duplex
* if we are on 82543. If we
* are on newer silicon, we only need to configure
* collision distance in the Transmit Control Register.
* 2) Set up flow control on the MAC to that established with
* the link partner.
* 3) Config DSP to improve Gigabit link quality for some PHY revisions.
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static int32_t
e1000_copper_link_postconfig(struct e1000_hw *hw)
{
int32_t ret_val;
DEBUGFUNC("e1000_copper_link_postconfig");
if(hw->mac_type >= e1000_82544) {
e1000_config_collision_dist(hw);
} else {
ret_val = e1000_config_mac_to_phy(hw);
if(ret_val) {
DEBUGOUT("Error configuring MAC to PHY settings\n");
return ret_val;
}
}
ret_val = e1000_config_fc_after_link_up(hw);
if(ret_val) {
DEBUGOUT("Error Configuring Flow Control\n");
return ret_val;
}
/* Config DSP to improve Giga link quality */
if(hw->phy_type == e1000_phy_igp) {
ret_val = e1000_config_dsp_after_link_change(hw, TRUE);
if(ret_val) {
DEBUGOUT("Error Configuring DSP after link up\n");
return ret_val;
}
}
return E1000_SUCCESS;
}
/******************************************************************************
* Detects which PHY is present and setup the speed and duplex
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static int32_t
e1000_setup_copper_link(struct e1000_hw *hw)
{
int32_t ret_val;
uint16_t i;
uint16_t phy_data;
DEBUGFUNC("e1000_setup_copper_link");
/* Check if it is a valid PHY and set PHY mode if necessary. */
ret_val = e1000_copper_link_preconfig(hw);
if(ret_val)
return ret_val;
if (hw->phy_type == e1000_phy_igp ||
hw->phy_type == e1000_phy_igp_2) {
ret_val = e1000_copper_link_igp_setup(hw);
if(ret_val)
return ret_val;
} else if (hw->phy_type == e1000_phy_m88) {
ret_val = e1000_copper_link_mgp_setup(hw);
if(ret_val)
return ret_val;
}
if(hw->autoneg) {
/* Setup autoneg and flow control advertisement
* and perform autonegotiation */
ret_val = e1000_copper_link_autoneg(hw);
if(ret_val)
return ret_val;
} else {
/* PHY will be set to 10H, 10F, 100H,or 100F
* depending on value from forced_speed_duplex. */
DEBUGOUT("Forcing speed and duplex\n");
ret_val = e1000_phy_force_speed_duplex(hw);
if(ret_val) {
DEBUGOUT("Error Forcing Speed and Duplex\n");
return ret_val;
}
}
/* Check link status. Wait up to 100 microseconds for link to become
* valid.
*/
for(i = 0; i < 10; i++) {
ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
if(ret_val)
return ret_val;
ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
if(ret_val)
return ret_val;
if(phy_data & MII_SR_LINK_STATUS) {
/* Config the MAC and PHY after link is up */
ret_val = e1000_copper_link_postconfig(hw);
if(ret_val)
return ret_val;
DEBUGOUT("Valid link established!!!\n");
return E1000_SUCCESS;
}
udelay(10);
}
DEBUGOUT("Unable to establish link!!!\n");
return E1000_SUCCESS;
}
/******************************************************************************
* Configures PHY autoneg and flow control advertisement settings
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
int32_t
e1000_phy_setup_autoneg(struct e1000_hw *hw)
{
int32_t ret_val;
uint16_t mii_autoneg_adv_reg;
uint16_t mii_1000t_ctrl_reg;
DEBUGFUNC("e1000_phy_setup_autoneg");
/* Read the MII Auto-Neg Advertisement Register (Address 4). */
ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
if(ret_val)
return ret_val;
/* Read the MII 1000Base-T Control Register (Address 9). */
ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
if(ret_val)
return ret_val;
/* Need to parse both autoneg_advertised and fc and set up
* the appropriate PHY registers. First we will parse for
* autoneg_advertised software override. Since we can advertise * autoneg_advertised software override. Since we can advertise
* a plethora of combinations, we need to check each bit * a plethora of combinations, we need to check each bit
* individually. * individually.
...@@ -1417,7 +1602,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw) ...@@ -1417,7 +1602,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
...@@ -1678,6 +1863,11 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) ...@@ -1678,6 +1863,11 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
DEBUGFUNC("e1000_config_mac_to_phy"); DEBUGFUNC("e1000_config_mac_to_phy");
/* 82544 or newer MAC, Auto Speed Detection takes care of
* MAC speed/duplex configuration.*/
if (hw->mac_type >= e1000_82544)
return E1000_SUCCESS;
/* Read the Device Control Register and set the bits to Force Speed /* Read the Device Control Register and set the bits to Force Speed
* and Duplex. * and Duplex.
*/ */
...@@ -1688,45 +1878,25 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) ...@@ -1688,45 +1878,25 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
/* Set up duplex in the Device Control and Transmit Control /* Set up duplex in the Device Control and Transmit Control
* registers depending on negotiated values. * registers depending on negotiated values.
*/ */
if (hw->phy_type == e1000_phy_igp) { ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, if(ret_val)
&phy_data); return ret_val;
if(ret_val)
return ret_val;
if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD;
else ctrl &= ~E1000_CTRL_FD;
e1000_config_collision_dist(hw);
/* Set up speed in the Device Control register depending on if(phy_data & M88E1000_PSSR_DPLX)
* negotiated values. ctrl |= E1000_CTRL_FD;
*/ else
if((phy_data & IGP01E1000_PSSR_SPEED_MASK) == ctrl &= ~E1000_CTRL_FD;
IGP01E1000_PSSR_SPEED_1000MBPS)
ctrl |= E1000_CTRL_SPD_1000;
else if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
IGP01E1000_PSSR_SPEED_100MBPS)
ctrl |= E1000_CTRL_SPD_100;
} else {
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
&phy_data);
if(ret_val)
return ret_val;
if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD; e1000_config_collision_dist(hw);
else ctrl &= ~E1000_CTRL_FD;
e1000_config_collision_dist(hw); /* Set up speed in the Device Control register depending on
* negotiated values.
*/
if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
ctrl |= E1000_CTRL_SPD_1000;
else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
ctrl |= E1000_CTRL_SPD_100;
/* Set up speed in the Device Control register depending on
* negotiated values.
*/
if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
ctrl |= E1000_CTRL_SPD_1000;
else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
ctrl |= E1000_CTRL_SPD_100;
}
/* Write the configured values back to the Device Control Reg. */ /* Write the configured values back to the Device Control Reg. */
E1000_WRITE_REG(hw, CTRL, ctrl); E1000_WRITE_REG(hw, CTRL, ctrl);
return E1000_SUCCESS; return E1000_SUCCESS;
...@@ -2494,8 +2664,8 @@ e1000_read_phy_reg(struct e1000_hw *hw, ...@@ -2494,8 +2664,8 @@ e1000_read_phy_reg(struct e1000_hw *hw,
DEBUGFUNC("e1000_read_phy_reg"); DEBUGFUNC("e1000_read_phy_reg");
if((hw->phy_type == e1000_phy_igp ||
if(hw->phy_type == e1000_phy_igp && hw->phy_type == e1000_phy_igp_2) &&
(reg_addr > MAX_PHY_MULTI_PAGE_REG)) { (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
(uint16_t)reg_addr); (uint16_t)reg_addr);
...@@ -2600,8 +2770,8 @@ e1000_write_phy_reg(struct e1000_hw *hw, ...@@ -2600,8 +2770,8 @@ e1000_write_phy_reg(struct e1000_hw *hw,
DEBUGFUNC("e1000_write_phy_reg"); DEBUGFUNC("e1000_write_phy_reg");
if((hw->phy_type == e1000_phy_igp ||
if(hw->phy_type == e1000_phy_igp && hw->phy_type == e1000_phy_igp_2) &&
(reg_addr > MAX_PHY_MULTI_PAGE_REG)) { (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
(uint16_t)reg_addr); (uint16_t)reg_addr);
...@@ -2679,19 +2849,27 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw, ...@@ -2679,19 +2849,27 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw,
return E1000_SUCCESS; return E1000_SUCCESS;
} }
/****************************************************************************** /******************************************************************************
* Returns the PHY to the power-on reset state * Returns the PHY to the power-on reset state
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
******************************************************************************/ ******************************************************************************/
void int32_t
e1000_phy_hw_reset(struct e1000_hw *hw) e1000_phy_hw_reset(struct e1000_hw *hw)
{ {
uint32_t ctrl, ctrl_ext; uint32_t ctrl, ctrl_ext;
uint32_t led_ctrl; uint32_t led_ctrl;
int32_t ret_val;
DEBUGFUNC("e1000_phy_hw_reset"); DEBUGFUNC("e1000_phy_hw_reset");
/* In the case of the phy reset being blocked, it's not an error, we
* simply return success without performing the reset. */
ret_val = e1000_check_phy_reset_block(hw);
if (ret_val)
return E1000_SUCCESS;
DEBUGOUT("Resetting Phy...\n"); DEBUGOUT("Resetting Phy...\n");
if(hw->mac_type > e1000_82543) { if(hw->mac_type > e1000_82543) {
...@@ -2727,6 +2905,11 @@ e1000_phy_hw_reset(struct e1000_hw *hw) ...@@ -2727,6 +2905,11 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
E1000_WRITE_REG(hw, LEDCTL, led_ctrl); E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
} }
/* Wait for FW to finish PHY configuration. */
ret_val = e1000_get_phy_cfg_done(hw);
return ret_val;
} }
/****************************************************************************** /******************************************************************************
...@@ -2744,7 +2927,19 @@ e1000_phy_reset(struct e1000_hw *hw) ...@@ -2744,7 +2927,19 @@ e1000_phy_reset(struct e1000_hw *hw)
DEBUGFUNC("e1000_phy_reset"); DEBUGFUNC("e1000_phy_reset");
if(hw->mac_type != e1000_82541_rev_2) { /* In the case of the phy reset being blocked, it's not an error, we
* simply return success without performing the reset. */
ret_val = e1000_check_phy_reset_block(hw);
if (ret_val)
return E1000_SUCCESS;
switch (hw->mac_type) {
case e1000_82541_rev_2:
ret_val = e1000_phy_hw_reset(hw);
if(ret_val)
return ret_val;
break;
default:
ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
...@@ -2755,9 +2950,10 @@ e1000_phy_reset(struct e1000_hw *hw) ...@@ -2755,9 +2950,10 @@ e1000_phy_reset(struct e1000_hw *hw)
return ret_val; return ret_val;
udelay(1); udelay(1);
} else e1000_phy_hw_reset(hw); break;
}
if(hw->phy_type == e1000_phy_igp) if(hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2)
e1000_phy_init_script(hw); e1000_phy_init_script(hw);
return E1000_SUCCESS; return E1000_SUCCESS;
...@@ -2811,6 +3007,9 @@ e1000_detect_gig_phy(struct e1000_hw *hw) ...@@ -2811,6 +3007,9 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
case e1000_82547_rev_2: case e1000_82547_rev_2:
if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE; if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
break; break;
case e1000_82573:
if(hw->phy_id == M88E1111_I_PHY_ID) match = TRUE;
break;
default: default:
DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type); DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
return -E1000_ERR_CONFIG; return -E1000_ERR_CONFIG;
...@@ -2866,7 +3065,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw, ...@@ -2866,7 +3065,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
/* The downshift status is checked only once, after link is established, /* The downshift status is checked only once, after link is established,
* and it stored in the hw->speed_downgraded parameter. */ * and it stored in the hw->speed_downgraded parameter. */
phy_info->downshift = hw->speed_downgraded; phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
/* IGP01E1000 does not need to support it. */ /* IGP01E1000 does not need to support it. */
phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal; phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
...@@ -2905,7 +3104,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw, ...@@ -2905,7 +3104,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
if(ret_val) if(ret_val)
return ret_val; return ret_val;
/* transalte to old method */ /* Translate to old method */
average = (max_length + min_length) / 2; average = (max_length + min_length) / 2;
if(average <= e1000_igp_cable_length_50) if(average <= e1000_igp_cable_length_50)
...@@ -2940,7 +3139,7 @@ e1000_phy_m88_get_info(struct e1000_hw *hw, ...@@ -2940,7 +3139,7 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
/* The downshift status is checked only once, after link is established, /* The downshift status is checked only once, after link is established,
* and it stored in the hw->speed_downgraded parameter. */ * and it stored in the hw->speed_downgraded parameter. */
phy_info->downshift = hw->speed_downgraded; phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if(ret_val) if(ret_val)
...@@ -3029,7 +3228,8 @@ e1000_phy_get_info(struct e1000_hw *hw, ...@@ -3029,7 +3228,8 @@ e1000_phy_get_info(struct e1000_hw *hw,
return -E1000_ERR_CONFIG; return -E1000_ERR_CONFIG;
} }
if(hw->phy_type == e1000_phy_igp) if(hw->phy_type == e1000_phy_igp ||
hw->phy_type == e1000_phy_igp_2)
return e1000_phy_igp_get_info(hw, phy_info); return e1000_phy_igp_get_info(hw, phy_info);
else else
return e1000_phy_m88_get_info(hw, phy_info); return e1000_phy_m88_get_info(hw, phy_info);
...@@ -3055,11 +3255,12 @@ e1000_validate_mdi_setting(struct e1000_hw *hw) ...@@ -3055,11 +3255,12 @@ e1000_validate_mdi_setting(struct e1000_hw *hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
void int32_t
e1000_init_eeprom_params(struct e1000_hw *hw) e1000_init_eeprom_params(struct e1000_hw *hw)
{ {
struct e1000_eeprom_info *eeprom = &hw->eeprom; struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd = E1000_READ_REG(hw, EECD); uint32_t eecd = E1000_READ_REG(hw, EECD);
int32_t ret_val = E1000_SUCCESS;
uint16_t eeprom_size; uint16_t eeprom_size;
DEBUGFUNC("e1000_init_eeprom_params"); DEBUGFUNC("e1000_init_eeprom_params");
...@@ -3074,6 +3275,8 @@ e1000_init_eeprom_params(struct e1000_hw *hw) ...@@ -3074,6 +3275,8 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->opcode_bits = 3; eeprom->opcode_bits = 3;
eeprom->address_bits = 6; eeprom->address_bits = 6;
eeprom->delay_usec = 50; eeprom->delay_usec = 50;
eeprom->use_eerd = FALSE;
eeprom->use_eewr = FALSE;
break; break;
case e1000_82540: case e1000_82540:
case e1000_82545: case e1000_82545:
...@@ -3090,6 +3293,8 @@ e1000_init_eeprom_params(struct e1000_hw *hw) ...@@ -3090,6 +3293,8 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->word_size = 64; eeprom->word_size = 64;
eeprom->address_bits = 6; eeprom->address_bits = 6;
} }
eeprom->use_eerd = FALSE;
eeprom->use_eewr = FALSE;
break; break;
case e1000_82541: case e1000_82541:
case e1000_82541_rev_2: case e1000_82541_rev_2:
...@@ -3118,42 +3323,60 @@ e1000_init_eeprom_params(struct e1000_hw *hw) ...@@ -3118,42 +3323,60 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->address_bits = 6; eeprom->address_bits = 6;
} }
} }
eeprom->use_eerd = FALSE;
eeprom->use_eewr = FALSE;
break;
case e1000_82573:
eeprom->type = e1000_eeprom_spi;
eeprom->opcode_bits = 8;
eeprom->delay_usec = 1;
if (eecd & E1000_EECD_ADDR_BITS) {
eeprom->page_size = 32;
eeprom->address_bits = 16;
} else {
eeprom->page_size = 8;
eeprom->address_bits = 8;
}
eeprom->use_eerd = TRUE;
eeprom->use_eewr = TRUE;
if(e1000_is_onboard_nvm_eeprom(hw) == FALSE) {
eeprom->type = e1000_eeprom_flash;
eeprom->word_size = 2048;
/* Ensure that the Autonomous FLASH update bit is cleared due to
* Flash update issue on parts which use a FLASH for NVM. */
eecd &= ~E1000_EECD_AUPDEN;
E1000_WRITE_REG(hw, EECD, eecd);
}
break; break;
default: default:
break; break;
} }
if (eeprom->type == e1000_eeprom_spi) { if (eeprom->type == e1000_eeprom_spi) {
eeprom->word_size = 64; /* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
if (e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) { * 32KB (incremented by powers of 2).
eeprom_size &= EEPROM_SIZE_MASK; */
if(hw->mac_type <= e1000_82547_rev_2) {
switch (eeprom_size) { /* Set to default value for initial eeprom read. */
case EEPROM_SIZE_16KB: eeprom->word_size = 64;
eeprom->word_size = 8192; ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
break; if(ret_val)
case EEPROM_SIZE_8KB: return ret_val;
eeprom->word_size = 4096; eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
break; /* 256B eeprom size was not supported in earlier hardware, so we
case EEPROM_SIZE_4KB: * bump eeprom_size up one to ensure that "1" (which maps to 256B)
eeprom->word_size = 2048; * is never the result used in the shifting logic below. */
break; if(eeprom_size)
case EEPROM_SIZE_2KB: eeprom_size++;
eeprom->word_size = 1024; } else {
break; eeprom_size = (uint16_t)((eecd & E1000_EECD_SIZE_EX_MASK) >>
case EEPROM_SIZE_1KB: E1000_EECD_SIZE_EX_SHIFT);
eeprom->word_size = 512;
break;
case EEPROM_SIZE_512B:
eeprom->word_size = 256;
break;
case EEPROM_SIZE_128B:
default:
eeprom->word_size = 64;
break;
}
} }
eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
} }
return ret_val;
} }
/****************************************************************************** /******************************************************************************
...@@ -3306,8 +3529,12 @@ e1000_acquire_eeprom(struct e1000_hw *hw) ...@@ -3306,8 +3529,12 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
DEBUGFUNC("e1000_acquire_eeprom"); DEBUGFUNC("e1000_acquire_eeprom");
if(e1000_get_hw_eeprom_semaphore(hw))
return -E1000_ERR_EEPROM;
eecd = E1000_READ_REG(hw, EECD); eecd = E1000_READ_REG(hw, EECD);
if (hw->mac_type != e1000_82573) {
/* Request EEPROM Access */ /* Request EEPROM Access */
if(hw->mac_type > e1000_82544) { if(hw->mac_type > e1000_82544) {
eecd |= E1000_EECD_REQ; eecd |= E1000_EECD_REQ;
...@@ -3326,6 +3553,7 @@ e1000_acquire_eeprom(struct e1000_hw *hw) ...@@ -3326,6 +3553,7 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
} }
}
/* Setup EEPROM for Read/Write */ /* Setup EEPROM for Read/Write */
...@@ -3443,6 +3671,8 @@ e1000_release_eeprom(struct e1000_hw *hw) ...@@ -3443,6 +3671,8 @@ e1000_release_eeprom(struct e1000_hw *hw)
eecd &= ~E1000_EECD_REQ; eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd); E1000_WRITE_REG(hw, EECD, eecd);
} }
e1000_put_hw_eeprom_semaphore(hw);
} }
/****************************************************************************** /******************************************************************************
...@@ -3504,8 +3734,10 @@ e1000_read_eeprom(struct e1000_hw *hw, ...@@ -3504,8 +3734,10 @@ e1000_read_eeprom(struct e1000_hw *hw,
{ {
struct e1000_eeprom_info *eeprom = &hw->eeprom; struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t i = 0; uint32_t i = 0;
int32_t ret_val;
DEBUGFUNC("e1000_read_eeprom"); DEBUGFUNC("e1000_read_eeprom");
/* A check for invalid values: offset too large, too many words, and not /* A check for invalid values: offset too large, too many words, and not
* enough words. * enough words.
*/ */
...@@ -3515,9 +3747,23 @@ e1000_read_eeprom(struct e1000_hw *hw, ...@@ -3515,9 +3747,23 @@ e1000_read_eeprom(struct e1000_hw *hw,
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
/* Prepare the EEPROM for reading */ /* FLASH reads without acquiring the semaphore are safe in 82573-based
if(e1000_acquire_eeprom(hw) != E1000_SUCCESS) * controllers.
return -E1000_ERR_EEPROM; */
if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
(hw->mac_type != e1000_82573)) {
/* Prepare the EEPROM for reading */
if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
return -E1000_ERR_EEPROM;
}
if(eeprom->use_eerd == TRUE) {
ret_val = e1000_read_eeprom_eerd(hw, offset, words, data);
if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
(hw->mac_type != e1000_82573))
e1000_release_eeprom(hw);
return ret_val;
}
if(eeprom->type == e1000_eeprom_spi) { if(eeprom->type == e1000_eeprom_spi) {
uint16_t word_in; uint16_t word_in;
...@@ -3569,65 +3815,212 @@ e1000_read_eeprom(struct e1000_hw *hw, ...@@ -3569,65 +3815,212 @@ e1000_read_eeprom(struct e1000_hw *hw,
} }
/****************************************************************************** /******************************************************************************
* Verifies that the EEPROM has a valid checksum * Reads a 16 bit word from the EEPROM using the EERD register.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* * offset - offset of word in the EEPROM to read
* Reads the first 64 16 bit words of the EEPROM and sums the values read. * data - word read from the EEPROM
* If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is * words - number of words to read
* valid.
*****************************************************************************/ *****************************************************************************/
int32_t int32_t
e1000_validate_eeprom_checksum(struct e1000_hw *hw) e1000_read_eeprom_eerd(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
uint16_t *data)
{ {
uint16_t checksum = 0; uint32_t i, eerd = 0;
uint16_t i, eeprom_data; int32_t error = 0;
DEBUGFUNC("e1000_validate_eeprom_checksum"); for (i = 0; i < words; i++) {
eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) +
E1000_EEPROM_RW_REG_START;
for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { E1000_WRITE_REG(hw, EERD, eerd);
if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) { error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM; if(error) {
break;
} }
checksum += eeprom_data; data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA);
}
if(checksum == (uint16_t) EEPROM_SUM)
return E1000_SUCCESS;
else {
DEBUGOUT("EEPROM Checksum Invalid\n");
return -E1000_ERR_EEPROM;
} }
return error;
} }
/****************************************************************************** /******************************************************************************
* Calculates the EEPROM checksum and writes it to the EEPROM * Writes a 16 bit word from the EEPROM using the EEWR register.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* * offset - offset of word in the EEPROM to read
* Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA. * data - word read from the EEPROM
* Writes the difference to word offset 63 of the EEPROM. * words - number of words to read
*****************************************************************************/ *****************************************************************************/
int32_t int32_t
e1000_update_eeprom_checksum(struct e1000_hw *hw) e1000_write_eeprom_eewr(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
uint16_t *data)
{ {
uint16_t checksum = 0; uint32_t register_value = 0;
uint16_t i, eeprom_data; uint32_t i = 0;
int32_t error = 0;
DEBUGFUNC("e1000_update_eeprom_checksum"); for (i = 0; i < words; i++) {
register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) |
((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) |
E1000_EEPROM_RW_REG_START;
for(i = 0; i < EEPROM_CHECKSUM_REG; i++) { error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) { if(error) {
DEBUGOUT("EEPROM Read Error\n"); break;
return -E1000_ERR_EEPROM; }
}
checksum += eeprom_data; E1000_WRITE_REG(hw, EEWR, register_value);
}
checksum = (uint16_t) EEPROM_SUM - checksum; error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
if(error) {
break;
}
}
return error;
}
/******************************************************************************
* Polls the status bit (bit 1) of the EERD to determine when the read is done.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
int32_t
e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
{
uint32_t attempts = 100000;
uint32_t i, reg = 0;
int32_t done = E1000_ERR_EEPROM;
for(i = 0; i < attempts; i++) {
if(eerd == E1000_EEPROM_POLL_READ)
reg = E1000_READ_REG(hw, EERD);
else
reg = E1000_READ_REG(hw, EEWR);
if(reg & E1000_EEPROM_RW_REG_DONE) {
done = E1000_SUCCESS;
break;
}
udelay(5);
}
return done;
}
/***************************************************************************
* Description: Determines if the onboard NVM is FLASH or EEPROM.
*
* hw - Struct containing variables accessed by shared code
****************************************************************************/
boolean_t
e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
{
uint32_t eecd = 0;
if(hw->mac_type == e1000_82573) {
eecd = E1000_READ_REG(hw, EECD);
/* Isolate bits 15 & 16 */
eecd = ((eecd >> 15) & 0x03);
/* If both bits are set, device is Flash type */
if(eecd == 0x03) {
return FALSE;
}
}
return TRUE;
}
/******************************************************************************
* Verifies that the EEPROM has a valid checksum
*
* hw - Struct containing variables accessed by shared code
*
* Reads the first 64 16 bit words of the EEPROM and sums the values read.
* If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
* valid.
*****************************************************************************/
int32_t
e1000_validate_eeprom_checksum(struct e1000_hw *hw)
{
uint16_t checksum = 0;
uint16_t i, eeprom_data;
DEBUGFUNC("e1000_validate_eeprom_checksum");
if ((hw->mac_type == e1000_82573) &&
(e1000_is_onboard_nvm_eeprom(hw) == FALSE)) {
/* Check bit 4 of word 10h. If it is 0, firmware is done updating
* 10h-12h. Checksum may need to be fixed. */
e1000_read_eeprom(hw, 0x10, 1, &eeprom_data);
if ((eeprom_data & 0x10) == 0) {
/* Read 0x23 and check bit 15. This bit is a 1 when the checksum
* has already been fixed. If the checksum is still wrong and this
* bit is a 1, we need to return bad checksum. Otherwise, we need
* to set this bit to a 1 and update the checksum. */
e1000_read_eeprom(hw, 0x23, 1, &eeprom_data);
if ((eeprom_data & 0x8000) == 0) {
eeprom_data |= 0x8000;
e1000_write_eeprom(hw, 0x23, 1, &eeprom_data);
e1000_update_eeprom_checksum(hw);
}
}
}
for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
}
checksum += eeprom_data;
}
if(checksum == (uint16_t) EEPROM_SUM)
return E1000_SUCCESS;
else {
DEBUGOUT("EEPROM Checksum Invalid\n");
return -E1000_ERR_EEPROM;
}
}
/******************************************************************************
* Calculates the EEPROM checksum and writes it to the EEPROM
*
* hw - Struct containing variables accessed by shared code
*
* Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
* Writes the difference to word offset 63 of the EEPROM.
*****************************************************************************/
int32_t
e1000_update_eeprom_checksum(struct e1000_hw *hw)
{
uint16_t checksum = 0;
uint16_t i, eeprom_data;
DEBUGFUNC("e1000_update_eeprom_checksum");
for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
}
checksum += eeprom_data;
}
checksum = (uint16_t) EEPROM_SUM - checksum;
if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) { if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
DEBUGOUT("EEPROM Write Error\n"); DEBUGOUT("EEPROM Write Error\n");
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} else if (hw->eeprom.type == e1000_eeprom_flash) {
e1000_commit_shadow_ram(hw);
} }
return E1000_SUCCESS; return E1000_SUCCESS;
} }
...@@ -3663,6 +4056,10 @@ e1000_write_eeprom(struct e1000_hw *hw, ...@@ -3663,6 +4056,10 @@ e1000_write_eeprom(struct e1000_hw *hw,
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
/* 82573 reads only through eerd */
if(eeprom->use_eewr == TRUE)
return e1000_write_eeprom_eewr(hw, offset, words, data);
/* Prepare the EEPROM for writing */ /* Prepare the EEPROM for writing */
if (e1000_acquire_eeprom(hw) != E1000_SUCCESS) if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
...@@ -3832,6 +4229,65 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw, ...@@ -3832,6 +4229,65 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw,
return E1000_SUCCESS; return E1000_SUCCESS;
} }
/******************************************************************************
* Flushes the cached eeprom to NVM. This is done by saving the modified values
* in the eeprom cache and the non modified values in the currently active bank
* to the new bank.
*
* hw - Struct containing variables accessed by shared code
* offset - offset of word in the EEPROM to read
* data - word read from the EEPROM
* words - number of words to read
*****************************************************************************/
int32_t
e1000_commit_shadow_ram(struct e1000_hw *hw)
{
uint32_t attempts = 100000;
uint32_t eecd = 0;
uint32_t flop = 0;
uint32_t i = 0;
int32_t error = E1000_SUCCESS;
/* The flop register will be used to determine if flash type is STM */
flop = E1000_READ_REG(hw, FLOP);
if (hw->mac_type == e1000_82573) {
for (i=0; i < attempts; i++) {
eecd = E1000_READ_REG(hw, EECD);
if ((eecd & E1000_EECD_FLUPD) == 0) {
break;
}
udelay(5);
}
if (i == attempts) {
return -E1000_ERR_EEPROM;
}
/* If STM opcode located in bits 15:8 of flop, reset firmware */
if ((flop & 0xFF00) == E1000_STM_OPCODE) {
E1000_WRITE_REG(hw, HICR, E1000_HICR_FW_RESET);
}
/* Perform the flash update */
E1000_WRITE_REG(hw, EECD, eecd | E1000_EECD_FLUPD);
for (i=0; i < attempts; i++) {
eecd = E1000_READ_REG(hw, EECD);
if ((eecd & E1000_EECD_FLUPD) == 0) {
break;
}
udelay(5);
}
if (i == attempts) {
return -E1000_ERR_EEPROM;
}
}
return error;
}
/****************************************************************************** /******************************************************************************
* Reads the adapter's part number from the EEPROM * Reads the adapter's part number from the EEPROM
* *
...@@ -3911,6 +4367,7 @@ void ...@@ -3911,6 +4367,7 @@ void
e1000_init_rx_addrs(struct e1000_hw *hw) e1000_init_rx_addrs(struct e1000_hw *hw)
{ {
uint32_t i; uint32_t i;
uint32_t rar_num;
DEBUGFUNC("e1000_init_rx_addrs"); DEBUGFUNC("e1000_init_rx_addrs");
...@@ -3919,9 +4376,10 @@ e1000_init_rx_addrs(struct e1000_hw *hw) ...@@ -3919,9 +4376,10 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
e1000_rar_set(hw, hw->mac_addr, 0); e1000_rar_set(hw, hw->mac_addr, 0);
rar_num = E1000_RAR_ENTRIES;
/* Zero out the other 15 receive addresses. */ /* Zero out the other 15 receive addresses. */
DEBUGOUT("Clearing RAR[1-15]\n"); DEBUGOUT("Clearing RAR[1-15]\n");
for(i = 1; i < E1000_RAR_ENTRIES; i++) { for(i = 1; i < rar_num; i++) {
E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
} }
...@@ -3950,7 +4408,9 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, ...@@ -3950,7 +4408,9 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
{ {
uint32_t hash_value; uint32_t hash_value;
uint32_t i; uint32_t i;
uint32_t num_rar_entry;
uint32_t num_mta_entry;
DEBUGFUNC("e1000_mc_addr_list_update"); DEBUGFUNC("e1000_mc_addr_list_update");
/* Set the new number of MC addresses that we are being requested to use. */ /* Set the new number of MC addresses that we are being requested to use. */
...@@ -3958,14 +4418,16 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, ...@@ -3958,14 +4418,16 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
/* Clear RAR[1-15] */ /* Clear RAR[1-15] */
DEBUGOUT(" Clearing RAR[1-15]\n"); DEBUGOUT(" Clearing RAR[1-15]\n");
for(i = rar_used_count; i < E1000_RAR_ENTRIES; i++) { num_rar_entry = E1000_RAR_ENTRIES;
for(i = rar_used_count; i < num_rar_entry; i++) {
E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
} }
/* Clear the MTA */ /* Clear the MTA */
DEBUGOUT(" Clearing MTA\n"); DEBUGOUT(" Clearing MTA\n");
for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++) { num_mta_entry = E1000_NUM_MTA_REGISTERS;
for(i = 0; i < num_mta_entry; i++) {
E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
} }
...@@ -3989,7 +4451,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, ...@@ -3989,7 +4451,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
/* Place this multicast address in the RAR if there is room, * /* Place this multicast address in the RAR if there is room, *
* else put it in the MTA * else put it in the MTA
*/ */
if(rar_used_count < E1000_RAR_ENTRIES) { if (rar_used_count < num_rar_entry) {
e1000_rar_set(hw, e1000_rar_set(hw,
mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)), mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)),
rar_used_count); rar_used_count);
...@@ -4040,6 +4502,7 @@ e1000_hash_mc_addr(struct e1000_hw *hw, ...@@ -4040,6 +4502,7 @@ e1000_hash_mc_addr(struct e1000_hw *hw,
} }
hash_value &= 0xFFF; hash_value &= 0xFFF;
return hash_value; return hash_value;
} }
...@@ -4144,12 +4607,33 @@ void ...@@ -4144,12 +4607,33 @@ void
e1000_clear_vfta(struct e1000_hw *hw) e1000_clear_vfta(struct e1000_hw *hw)
{ {
uint32_t offset; uint32_t offset;
uint32_t vfta_value = 0;
for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) uint32_t vfta_offset = 0;
E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0); uint32_t vfta_bit_in_reg = 0;
if (hw->mac_type == e1000_82573) {
if (hw->mng_cookie.vlan_id != 0) {
/* The VFTA is a 4096b bit-field, each identifying a single VLAN
* ID. The following operations determine which 32b entry
* (i.e. offset) into the array we want to set the VLAN ID
* (i.e. bit) of the manageability unit. */
vfta_offset = (hw->mng_cookie.vlan_id >>
E1000_VFTA_ENTRY_SHIFT) &
E1000_VFTA_ENTRY_MASK;
vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
}
}
for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
/* If the offset we want to clear is the same offset of the
* manageability VLAN ID, then clear all bits except that of the
* manageability unit */
vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
}
} }
static int32_t int32_t
e1000_id_led_init(struct e1000_hw * hw) e1000_id_led_init(struct e1000_hw * hw)
{ {
uint32_t ledctl; uint32_t ledctl;
...@@ -4480,6 +4964,19 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw) ...@@ -4480,6 +4964,19 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw)
temp = E1000_READ_REG(hw, MGTPRC); temp = E1000_READ_REG(hw, MGTPRC);
temp = E1000_READ_REG(hw, MGTPDC); temp = E1000_READ_REG(hw, MGTPDC);
temp = E1000_READ_REG(hw, MGTPTC); temp = E1000_READ_REG(hw, MGTPTC);
if(hw->mac_type <= e1000_82547_rev_2) return;
temp = E1000_READ_REG(hw, IAC);
temp = E1000_READ_REG(hw, ICRXOC);
temp = E1000_READ_REG(hw, ICRXPTC);
temp = E1000_READ_REG(hw, ICRXATC);
temp = E1000_READ_REG(hw, ICTXPTC);
temp = E1000_READ_REG(hw, ICTXATC);
temp = E1000_READ_REG(hw, ICTXQEC);
temp = E1000_READ_REG(hw, ICTXQMTC);
temp = E1000_READ_REG(hw, ICRXDMTC);
} }
/****************************************************************************** /******************************************************************************
...@@ -4646,6 +5143,11 @@ e1000_get_bus_info(struct e1000_hw *hw) ...@@ -4646,6 +5143,11 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw->bus_speed = e1000_bus_speed_unknown; hw->bus_speed = e1000_bus_speed_unknown;
hw->bus_width = e1000_bus_width_unknown; hw->bus_width = e1000_bus_width_unknown;
break; break;
case e1000_82573:
hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500;
hw->bus_width = e1000_bus_width_pciex_4;
break;
default: default:
status = E1000_READ_REG(hw, STATUS); status = E1000_READ_REG(hw, STATUS);
hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
...@@ -4749,6 +5251,7 @@ e1000_get_cable_length(struct e1000_hw *hw, ...@@ -4749,6 +5251,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
/* Use old method for Phy older than IGP */ /* Use old method for Phy older than IGP */
if(hw->phy_type == e1000_phy_m88) { if(hw->phy_type == e1000_phy_m88) {
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
&phy_data); &phy_data);
if(ret_val) if(ret_val)
...@@ -4865,7 +5368,8 @@ e1000_check_polarity(struct e1000_hw *hw, ...@@ -4865,7 +5368,8 @@ e1000_check_polarity(struct e1000_hw *hw,
return ret_val; return ret_val;
*polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >> *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
M88E1000_PSSR_REV_POLARITY_SHIFT; M88E1000_PSSR_REV_POLARITY_SHIFT;
} else if(hw->phy_type == e1000_phy_igp) { } else if(hw->phy_type == e1000_phy_igp ||
hw->phy_type == e1000_phy_igp_2) {
/* Read the Status register to check the speed */ /* Read the Status register to check the speed */
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
&phy_data); &phy_data);
...@@ -4917,7 +5421,8 @@ e1000_check_downshift(struct e1000_hw *hw) ...@@ -4917,7 +5421,8 @@ e1000_check_downshift(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_downshift"); DEBUGFUNC("e1000_check_downshift");
if(hw->phy_type == e1000_phy_igp) { if(hw->phy_type == e1000_phy_igp ||
hw->phy_type == e1000_phy_igp_2) {
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
&phy_data); &phy_data);
if(ret_val) if(ret_val)
...@@ -4933,6 +5438,7 @@ e1000_check_downshift(struct e1000_hw *hw) ...@@ -4933,6 +5438,7 @@ e1000_check_downshift(struct e1000_hw *hw)
hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >> hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
M88E1000_PSSR_DOWNSHIFT_SHIFT; M88E1000_PSSR_DOWNSHIFT_SHIFT;
} }
return E1000_SUCCESS; return E1000_SUCCESS;
} }
...@@ -5047,7 +5553,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, ...@@ -5047,7 +5553,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw,
if(ret_val) if(ret_val)
return ret_val; return ret_val;
msec_delay(20); msec_delay_irq(20);
ret_val = e1000_write_phy_reg(hw, 0x0000, ret_val = e1000_write_phy_reg(hw, 0x0000,
IGP01E1000_IEEE_FORCE_GIGA); IGP01E1000_IEEE_FORCE_GIGA);
...@@ -5071,7 +5577,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, ...@@ -5071,7 +5577,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw,
if(ret_val) if(ret_val)
return ret_val; return ret_val;
msec_delay(20); msec_delay_irq(20);
/* Now enable the transmitter */ /* Now enable the transmitter */
ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
...@@ -5096,7 +5602,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, ...@@ -5096,7 +5602,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw,
if(ret_val) if(ret_val)
return ret_val; return ret_val;
msec_delay(20); msec_delay_irq(20);
ret_val = e1000_write_phy_reg(hw, 0x0000, ret_val = e1000_write_phy_reg(hw, 0x0000,
IGP01E1000_IEEE_FORCE_GIGA); IGP01E1000_IEEE_FORCE_GIGA);
...@@ -5112,7 +5618,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, ...@@ -5112,7 +5618,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw,
if(ret_val) if(ret_val)
return ret_val; return ret_val;
msec_delay(20); msec_delay_irq(20);
/* Now enable the transmitter */ /* Now enable the transmitter */
ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
...@@ -5187,22 +5693,36 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, ...@@ -5187,22 +5693,36 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
uint16_t phy_data; uint16_t phy_data;
DEBUGFUNC("e1000_set_d3_lplu_state"); DEBUGFUNC("e1000_set_d3_lplu_state");
if(!((hw->mac_type == e1000_82541_rev_2) || if(hw->phy_type != e1000_phy_igp && hw->phy_type != e1000_phy_igp_2)
(hw->mac_type == e1000_82547_rev_2)))
return E1000_SUCCESS; return E1000_SUCCESS;
/* During driver activity LPLU should not be used or it will attain link /* During driver activity LPLU should not be used or it will attain link
* from the lowest speeds starting from 10Mbps. The capability is used for * from the lowest speeds starting from 10Mbps. The capability is used for
* Dx transitions and states */ * Dx transitions and states */
ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data); if(hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) {
if(ret_val) ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
return ret_val; if(ret_val)
return ret_val;
if(!active) { } else {
phy_data &= ~IGP01E1000_GMII_FLEX_SPD; ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
}
if(!active) {
if(hw->mac_type == e1000_82541_rev_2 ||
hw->mac_type == e1000_82547_rev_2) {
phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
if(ret_val)
return ret_val;
} else {
phy_data &= ~IGP02E1000_PM_D3_LPLU;
ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
phy_data);
if (ret_val)
return ret_val;
}
/* LPLU and SmartSpeed are mutually exclusive. LPLU is used during /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during
* Dx states where the power conservation is most important. During * Dx states where the power conservation is most important. During
...@@ -5236,11 +5756,105 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, ...@@ -5236,11 +5756,105 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
(hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
(hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) { (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
phy_data |= IGP01E1000_GMII_FLEX_SPD; if(hw->mac_type == e1000_82541_rev_2 ||
ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); hw->mac_type == e1000_82547_rev_2) {
phy_data |= IGP01E1000_GMII_FLEX_SPD;
ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
if(ret_val)
return ret_val;
} else {
phy_data |= IGP02E1000_PM_D3_LPLU;
ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
phy_data);
if (ret_val)
return ret_val;
}
/* When LPLU is enabled we should disable SmartSpeed */
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
if(ret_val)
return ret_val;
phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
if(ret_val)
return ret_val;
}
return E1000_SUCCESS;
}
/*****************************************************************************
*
* This function sets the lplu d0 state according to the active flag. When
* activating lplu this function also disables smart speed and vise versa.
* lplu will not be activated unless the device autonegotiation advertisment
* meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
* hw: Struct containing variables accessed by shared code
* active - true to enable lplu false to disable lplu.
*
* returns: - E1000_ERR_PHY if fail to read/write the PHY
* E1000_SUCCESS at any other case.
*
****************************************************************************/
int32_t
e1000_set_d0_lplu_state(struct e1000_hw *hw,
boolean_t active)
{
int32_t ret_val;
uint16_t phy_data;
DEBUGFUNC("e1000_set_d0_lplu_state");
if(hw->mac_type <= e1000_82547_rev_2)
return E1000_SUCCESS;
ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
if (!active) {
phy_data &= ~IGP02E1000_PM_D0_LPLU;
ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
if (ret_val)
return ret_val;
/* LPLU and SmartSpeed are mutually exclusive. LPLU is used during
* Dx states where the power conservation is most important. During
* driver activity we should enable SmartSpeed, so performance is
* maintained. */
if (hw->smart_speed == e1000_smart_speed_on) {
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&phy_data);
if(ret_val)
return ret_val;
phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
phy_data);
if(ret_val)
return ret_val;
} else if (hw->smart_speed == e1000_smart_speed_off) {
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&phy_data);
if (ret_val)
return ret_val;
phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
phy_data);
if(ret_val)
return ret_val;
}
} else {
phy_data |= IGP02E1000_PM_D0_LPLU;
ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
if (ret_val)
return ret_val;
/* When LPLU is enabled we should disable SmartSpeed */ /* When LPLU is enabled we should disable SmartSpeed */
ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
if(ret_val) if(ret_val)
...@@ -5318,18 +5932,350 @@ e1000_set_vco_speed(struct e1000_hw *hw) ...@@ -5318,18 +5932,350 @@ e1000_set_vco_speed(struct e1000_hw *hw)
return E1000_SUCCESS; return E1000_SUCCESS;
} }
static int32_t
e1000_polarity_reversal_workaround(struct e1000_hw *hw)
{
int32_t ret_val;
uint16_t mii_status_reg;
uint16_t i;
/* Polarity reversal workaround for forced 10F/10H links. */ /*****************************************************************************
* This function reads the cookie from ARC ram.
*
* returns: - E1000_SUCCESS .
****************************************************************************/
int32_t
e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer)
{
uint8_t i;
uint32_t offset = E1000_MNG_DHCP_COOKIE_OFFSET;
uint8_t length = E1000_MNG_DHCP_COOKIE_LENGTH;
/* Disable the transmitter on the PHY */ length = (length >> 2);
offset = (offset >> 2);
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); for (i = 0; i < length; i++) {
*((uint32_t *) buffer + i) =
E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i);
}
return E1000_SUCCESS;
}
/*****************************************************************************
* This function checks whether the HOST IF is enabled for command operaton
* and also checks whether the previous command is completed.
* It busy waits in case of previous command is not completed.
*
* returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or
* timeout
* - E1000_SUCCESS for success.
****************************************************************************/
int32_t
e1000_mng_enable_host_if(struct e1000_hw * hw)
{
uint32_t hicr;
uint8_t i;
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, HICR);
if ((hicr & E1000_HICR_EN) == 0) {
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* check the previous command is completed */
for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
hicr = E1000_READ_REG(hw, HICR);
if (!(hicr & E1000_HICR_C))
break;
msec_delay_irq(1);
}
if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
DEBUGOUT("Previous command timeout failed .\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
return E1000_SUCCESS;
}
/*****************************************************************************
* This function writes the buffer content at the offset given on the host if.
* It also does alignment considerations to do the writes in most efficient way.
* Also fills up the sum of the buffer in *buffer parameter.
*
* returns - E1000_SUCCESS for success.
****************************************************************************/
int32_t
e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer,
uint16_t length, uint16_t offset, uint8_t *sum)
{
uint8_t *tmp;
uint8_t *bufptr = buffer;
uint32_t data;
uint16_t remaining, i, j, prev_bytes;
/* sum = only sum of the data and it is not checksum */
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
return -E1000_ERR_PARAM;
}
tmp = (uint8_t *)&data;
prev_bytes = offset & 0x3;
offset &= 0xFFFC;
offset >>= 2;
if (prev_bytes) {
data = E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset);
for (j = prev_bytes; j < sizeof(uint32_t); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset, data);
length -= j - prev_bytes;
offset++;
}
remaining = length & 0x3;
length -= remaining;
/* Calculate length in DWORDs */
length >>= 2;
/* The device driver writes the relevant command block into the
* ram area. */
for (i = 0; i < length; i++) {
for (j = 0; j < sizeof(uint32_t); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
}
if (remaining) {
for (j = 0; j < sizeof(uint32_t); j++) {
if (j < remaining)
*(tmp + j) = *bufptr++;
else
*(tmp + j) = 0;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
}
return E1000_SUCCESS;
}
/*****************************************************************************
* This function writes the command header after does the checksum calculation.
*
* returns - E1000_SUCCESS for success.
****************************************************************************/
int32_t
e1000_mng_write_cmd_header(struct e1000_hw * hw,
struct e1000_host_mng_command_header * hdr)
{
uint16_t i;
uint8_t sum;
uint8_t *buffer;
/* Write the whole command header structure which includes sum of
* the buffer */
uint16_t length = sizeof(struct e1000_host_mng_command_header);
sum = hdr->checksum;
hdr->checksum = 0;
buffer = (uint8_t *) hdr;
i = length;
while(i--)
sum += buffer[i];
hdr->checksum = 0 - sum;
length >>= 2;
/* The device driver writes the relevant command block into the ram area. */
for (i = 0; i < length; i++)
E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((uint32_t *) hdr + i));
return E1000_SUCCESS;
}
/*****************************************************************************
* This function indicates to ARC that a new command is pending which completes
* one write operation by the driver.
*
* returns - E1000_SUCCESS for success.
****************************************************************************/
int32_t
e1000_mng_write_commit(
struct e1000_hw * hw)
{
uint32_t hicr;
hicr = E1000_READ_REG(hw, HICR);
/* Setting this bit tells the ARC that a new command is pending. */
E1000_WRITE_REG(hw, HICR, hicr | E1000_HICR_C);
return E1000_SUCCESS;
}
/*****************************************************************************
* This function checks the mode of the firmware.
*
* returns - TRUE when the mode is IAMT or FALSE.
****************************************************************************/
boolean_t
e1000_check_mng_mode(
struct e1000_hw *hw)
{
uint32_t fwsm;
fwsm = E1000_READ_REG(hw, FWSM);
if((fwsm & E1000_FWSM_MODE_MASK) ==
(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
return TRUE;
return FALSE;
}
/*****************************************************************************
* This function writes the dhcp info .
****************************************************************************/
int32_t
e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
uint16_t length)
{
int32_t ret_val;
struct e1000_host_mng_command_header hdr;
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
hdr.command_length = length;
hdr.reserved1 = 0;
hdr.reserved2 = 0;
hdr.checksum = 0;
ret_val = e1000_mng_enable_host_if(hw);
if (ret_val == E1000_SUCCESS) {
ret_val = e1000_mng_host_if_write(hw, buffer, length, sizeof(hdr),
&(hdr.checksum));
if (ret_val == E1000_SUCCESS) {
ret_val = e1000_mng_write_cmd_header(hw, &hdr);
if (ret_val == E1000_SUCCESS)
ret_val = e1000_mng_write_commit(hw);
}
}
return ret_val;
}
/*****************************************************************************
* This function calculates the checksum.
*
* returns - checksum of buffer contents.
****************************************************************************/
uint8_t
e1000_calculate_mng_checksum(char *buffer, uint32_t length)
{
uint8_t sum = 0;
uint32_t i;
if (!buffer)
return 0;
for (i=0; i < length; i++)
sum += buffer[i];
return (uint8_t) (0 - sum);
}
/*****************************************************************************
* This function checks whether tx pkt filtering needs to be enabled or not.
*
* returns - TRUE for packet filtering or FALSE.
****************************************************************************/
boolean_t
e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
{
/* called in init as well as watchdog timer functions */
int32_t ret_val, checksum;
boolean_t tx_filter = FALSE;
struct e1000_host_mng_dhcp_cookie *hdr = &(hw->mng_cookie);
uint8_t *buffer = (uint8_t *) &(hw->mng_cookie);
if (e1000_check_mng_mode(hw)) {
ret_val = e1000_mng_enable_host_if(hw);
if (ret_val == E1000_SUCCESS) {
ret_val = e1000_host_if_read_cookie(hw, buffer);
if (ret_val == E1000_SUCCESS) {
checksum = hdr->checksum;
hdr->checksum = 0;
if ((hdr->signature == E1000_IAMT_SIGNATURE) &&
checksum == e1000_calculate_mng_checksum((char *)buffer,
E1000_MNG_DHCP_COOKIE_LENGTH)) {
if (hdr->status &
E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT)
tx_filter = TRUE;
} else
tx_filter = TRUE;
} else
tx_filter = TRUE;
}
}
hw->tx_pkt_filtering = tx_filter;
return tx_filter;
}
/******************************************************************************
* Verifies the hardware needs to allow ARPs to be processed by the host
*
* hw - Struct containing variables accessed by shared code
*
* returns: - TRUE/FALSE
*
*****************************************************************************/
uint32_t
e1000_enable_mng_pass_thru(struct e1000_hw *hw)
{
uint32_t manc;
uint32_t fwsm, factps;
if (hw->asf_firmware_present) {
manc = E1000_READ_REG(hw, MANC);
if (!(manc & E1000_MANC_RCV_TCO_EN) ||
!(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
return FALSE;
if (e1000_arc_subsystem_valid(hw) == TRUE) {
fwsm = E1000_READ_REG(hw, FWSM);
factps = E1000_READ_REG(hw, FACTPS);
if (((fwsm & E1000_FWSM_MODE_MASK) ==
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) &&
(factps & E1000_FACTPS_MNGCG))
return TRUE;
} else
if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
return TRUE;
}
return FALSE;
}
static int32_t
e1000_polarity_reversal_workaround(struct e1000_hw *hw)
{
int32_t ret_val;
uint16_t mii_status_reg;
uint16_t i;
/* Polarity reversal workaround for forced 10F/10H links. */
/* Disable the transmitter on the PHY */
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF); ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
...@@ -5403,3 +6349,265 @@ e1000_polarity_reversal_workaround(struct e1000_hw *hw) ...@@ -5403,3 +6349,265 @@ e1000_polarity_reversal_workaround(struct e1000_hw *hw)
return E1000_SUCCESS; return E1000_SUCCESS;
} }
/***************************************************************************
*
* Disables PCI-Express master access.
*
* hw: Struct containing variables accessed by shared code
*
* returns: - none.
*
***************************************************************************/
void
e1000_set_pci_express_master_disable(struct e1000_hw *hw)
{
uint32_t ctrl;
DEBUGFUNC("e1000_set_pci_express_master_disable");
if (hw->bus_type != e1000_bus_type_pci_express)
return;
ctrl = E1000_READ_REG(hw, CTRL);
ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
E1000_WRITE_REG(hw, CTRL, ctrl);
}
/***************************************************************************
*
* Enables PCI-Express master access.
*
* hw: Struct containing variables accessed by shared code
*
* returns: - none.
*
***************************************************************************/
void
e1000_enable_pciex_master(struct e1000_hw *hw)
{
uint32_t ctrl;
DEBUGFUNC("e1000_enable_pciex_master");
if (hw->bus_type != e1000_bus_type_pci_express)
return;
ctrl = E1000_READ_REG(hw, CTRL);
ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
E1000_WRITE_REG(hw, CTRL, ctrl);
}
/*******************************************************************************
*
* Disables PCI-Express master access and verifies there are no pending requests
*
* hw: Struct containing variables accessed by shared code
*
* returns: - E1000_ERR_MASTER_REQUESTS_PENDING if master disable bit hasn't
* caused the master requests to be disabled.
* E1000_SUCCESS master requests disabled.
*
******************************************************************************/
int32_t
e1000_disable_pciex_master(struct e1000_hw *hw)
{
int32_t timeout = MASTER_DISABLE_TIMEOUT; /* 80ms */
DEBUGFUNC("e1000_disable_pciex_master");
if (hw->bus_type != e1000_bus_type_pci_express)
return E1000_SUCCESS;
e1000_set_pci_express_master_disable(hw);
while(timeout) {
if(!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
break;
else
udelay(100);
timeout--;
}
if(!timeout) {
DEBUGOUT("Master requests are pending.\n");
return -E1000_ERR_MASTER_REQUESTS_PENDING;
}
return E1000_SUCCESS;
}
/*******************************************************************************
*
* Check for EEPROM Auto Read bit done.
*
* hw: Struct containing variables accessed by shared code
*
* returns: - E1000_ERR_RESET if fail to reset MAC
* E1000_SUCCESS at any other case.
*
******************************************************************************/
int32_t
e1000_get_auto_rd_done(struct e1000_hw *hw)
{
int32_t timeout = AUTO_READ_DONE_TIMEOUT;
DEBUGFUNC("e1000_get_auto_rd_done");
switch (hw->mac_type) {
default:
msec_delay(5);
break;
case e1000_82573:
while(timeout) {
if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break;
else msec_delay(1);
timeout--;
}
if(!timeout) {
DEBUGOUT("Auto read by HW from EEPROM has not completed.\n");
return -E1000_ERR_RESET;
}
break;
}
return E1000_SUCCESS;
}
/***************************************************************************
* Checks if the PHY configuration is done
*
* hw: Struct containing variables accessed by shared code
*
* returns: - E1000_ERR_RESET if fail to reset MAC
* E1000_SUCCESS at any other case.
*
***************************************************************************/
int32_t
e1000_get_phy_cfg_done(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_get_phy_cfg_done");
/* Simply wait for 10ms */
msec_delay(10);
return E1000_SUCCESS;
}
/***************************************************************************
*
* Using the combination of SMBI and SWESMBI semaphore bits when resetting
* adapter or Eeprom access.
*
* hw: Struct containing variables accessed by shared code
*
* returns: - E1000_ERR_EEPROM if fail to access EEPROM.
* E1000_SUCCESS at any other case.
*
***************************************************************************/
int32_t
e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
{
int32_t timeout;
uint32_t swsm;
DEBUGFUNC("e1000_get_hw_eeprom_semaphore");
if(!hw->eeprom_semaphore_present)
return E1000_SUCCESS;
/* Get the FW semaphore. */
timeout = hw->eeprom.word_size + 1;
while(timeout) {
swsm = E1000_READ_REG(hw, SWSM);
swsm |= E1000_SWSM_SWESMBI;
E1000_WRITE_REG(hw, SWSM, swsm);
/* if we managed to set the bit we got the semaphore. */
swsm = E1000_READ_REG(hw, SWSM);
if(swsm & E1000_SWSM_SWESMBI)
break;
udelay(50);
timeout--;
}
if(!timeout) {
/* Release semaphores */
e1000_put_hw_eeprom_semaphore(hw);
DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n");
return -E1000_ERR_EEPROM;
}
return E1000_SUCCESS;
}
/***************************************************************************
* This function clears HW semaphore bits.
*
* hw: Struct containing variables accessed by shared code
*
* returns: - None.
*
***************************************************************************/
void
e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
{
uint32_t swsm;
DEBUGFUNC("e1000_put_hw_eeprom_semaphore");
if(!hw->eeprom_semaphore_present)
return;
swsm = E1000_READ_REG(hw, SWSM);
/* Release both semaphores. */
swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
E1000_WRITE_REG(hw, SWSM, swsm);
}
/******************************************************************************
* Checks if PHY reset is blocked due to SOL/IDER session, for example.
* Returning E1000_BLK_PHY_RESET isn't necessarily an error. But it's up to
* the caller to figure out how to deal with it.
*
* hw - Struct containing variables accessed by shared code
*
* returns: - E1000_BLK_PHY_RESET
* E1000_SUCCESS
*
*****************************************************************************/
int32_t
e1000_check_phy_reset_block(struct e1000_hw *hw)
{
uint32_t manc = 0;
if(hw->mac_type > e1000_82547_rev_2)
manc = E1000_READ_REG(hw, MANC);
return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
E1000_BLK_PHY_RESET : E1000_SUCCESS;
}
uint8_t
e1000_arc_subsystem_valid(struct e1000_hw *hw)
{
uint32_t fwsm;
/* On 8257x silicon, registers in the range of 0x8800 - 0x8FFC
* may not be provided a DMA clock when no manageability features are
* enabled. We do not want to perform any reads/writes to these registers
* if this is the case. We read FWSM to determine the manageability mode.
*/
switch (hw->mac_type) {
case e1000_82573:
fwsm = E1000_READ_REG(hw, FWSM);
if((fwsm & E1000_FWSM_MODE_MASK) != 0)
return TRUE;
break;
default:
break;
}
return FALSE;
}
...@@ -57,6 +57,7 @@ typedef enum { ...@@ -57,6 +57,7 @@ typedef enum {
e1000_82541_rev_2, e1000_82541_rev_2,
e1000_82547, e1000_82547,
e1000_82547_rev_2, e1000_82547_rev_2,
e1000_82573,
e1000_num_macs e1000_num_macs
} e1000_mac_type; } e1000_mac_type;
...@@ -64,6 +65,7 @@ typedef enum { ...@@ -64,6 +65,7 @@ typedef enum {
e1000_eeprom_uninitialized = 0, e1000_eeprom_uninitialized = 0,
e1000_eeprom_spi, e1000_eeprom_spi,
e1000_eeprom_microwire, e1000_eeprom_microwire,
e1000_eeprom_flash,
e1000_num_eeprom_types e1000_num_eeprom_types
} e1000_eeprom_type; } e1000_eeprom_type;
...@@ -96,6 +98,7 @@ typedef enum { ...@@ -96,6 +98,7 @@ typedef enum {
e1000_bus_type_unknown = 0, e1000_bus_type_unknown = 0,
e1000_bus_type_pci, e1000_bus_type_pci,
e1000_bus_type_pcix, e1000_bus_type_pcix,
e1000_bus_type_pci_express,
e1000_bus_type_reserved e1000_bus_type_reserved
} e1000_bus_type; } e1000_bus_type;
...@@ -107,6 +110,7 @@ typedef enum { ...@@ -107,6 +110,7 @@ typedef enum {
e1000_bus_speed_100, e1000_bus_speed_100,
e1000_bus_speed_120, e1000_bus_speed_120,
e1000_bus_speed_133, e1000_bus_speed_133,
e1000_bus_speed_2500,
e1000_bus_speed_reserved e1000_bus_speed_reserved
} e1000_bus_speed; } e1000_bus_speed;
...@@ -115,6 +119,8 @@ typedef enum { ...@@ -115,6 +119,8 @@ typedef enum {
e1000_bus_width_unknown = 0, e1000_bus_width_unknown = 0,
e1000_bus_width_32, e1000_bus_width_32,
e1000_bus_width_64, e1000_bus_width_64,
e1000_bus_width_pciex_1,
e1000_bus_width_pciex_4,
e1000_bus_width_reserved e1000_bus_width_reserved
} e1000_bus_width; } e1000_bus_width;
...@@ -196,6 +202,7 @@ typedef enum { ...@@ -196,6 +202,7 @@ typedef enum {
typedef enum { typedef enum {
e1000_phy_m88 = 0, e1000_phy_m88 = 0,
e1000_phy_igp, e1000_phy_igp,
e1000_phy_igp_2,
e1000_phy_undefined = 0xFF e1000_phy_undefined = 0xFF
} e1000_phy_type; } e1000_phy_type;
...@@ -242,8 +249,19 @@ struct e1000_eeprom_info { ...@@ -242,8 +249,19 @@ struct e1000_eeprom_info {
uint16_t address_bits; uint16_t address_bits;
uint16_t delay_usec; uint16_t delay_usec;
uint16_t page_size; uint16_t page_size;
boolean_t use_eerd;
boolean_t use_eewr;
}; };
/* Flex ASF Information */
#define E1000_HOST_IF_MAX_SIZE 2048
typedef enum {
e1000_byte_align = 0,
e1000_word_align = 1,
e1000_dword_align = 2
} e1000_align_type;
/* Error Codes */ /* Error Codes */
...@@ -254,11 +272,16 @@ struct e1000_eeprom_info { ...@@ -254,11 +272,16 @@ struct e1000_eeprom_info {
#define E1000_ERR_PARAM 4 #define E1000_ERR_PARAM 4
#define E1000_ERR_MAC_TYPE 5 #define E1000_ERR_MAC_TYPE 5
#define E1000_ERR_PHY_TYPE 6 #define E1000_ERR_PHY_TYPE 6
#define E1000_ERR_RESET 9
#define E1000_ERR_MASTER_REQUESTS_PENDING 10
#define E1000_ERR_HOST_INTERFACE_COMMAND 11
#define E1000_BLK_PHY_RESET 12
/* Function prototypes */ /* Function prototypes */
/* Initialization */ /* Initialization */
int32_t e1000_reset_hw(struct e1000_hw *hw); int32_t e1000_reset_hw(struct e1000_hw *hw);
int32_t e1000_init_hw(struct e1000_hw *hw); int32_t e1000_init_hw(struct e1000_hw *hw);
int32_t e1000_id_led_init(struct e1000_hw * hw);
int32_t e1000_set_mac_type(struct e1000_hw *hw); int32_t e1000_set_mac_type(struct e1000_hw *hw);
void e1000_set_media_type(struct e1000_hw *hw); void e1000_set_media_type(struct e1000_hw *hw);
...@@ -275,7 +298,7 @@ int32_t e1000_force_mac_fc(struct e1000_hw *hw); ...@@ -275,7 +298,7 @@ int32_t e1000_force_mac_fc(struct e1000_hw *hw);
/* PHY */ /* PHY */
int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data); int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data);
int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data); int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
void e1000_phy_hw_reset(struct e1000_hw *hw); int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
int32_t e1000_phy_reset(struct e1000_hw *hw); int32_t e1000_phy_reset(struct e1000_hw *hw);
int32_t e1000_detect_gig_phy(struct e1000_hw *hw); int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info); int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
...@@ -287,13 +310,86 @@ int32_t e1000_check_downshift(struct e1000_hw *hw); ...@@ -287,13 +310,86 @@ int32_t e1000_check_downshift(struct e1000_hw *hw);
int32_t e1000_validate_mdi_setting(struct e1000_hw *hw); int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
/* EEPROM Functions */ /* EEPROM Functions */
void e1000_init_eeprom_params(struct e1000_hw *hw); int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
/* MNG HOST IF functions */
uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 /* Host Interface data length */
#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 /* Time in ms to process MNG command */
#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 /* Cookie offset */
#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 /* Cookie length */
#define E1000_MNG_IAMT_MODE 0x3
#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management Technology signature */
#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT 0x1 /* DHCP parsing enabled */
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT 0x2 /* DHCP parsing enabled */
#define E1000_VFTA_ENTRY_SHIFT 0x5
#define E1000_VFTA_ENTRY_MASK 0x7F
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
struct e1000_host_mng_command_header {
uint8_t command_id;
uint8_t checksum;
uint16_t reserved1;
uint16_t reserved2;
uint16_t command_length;
};
struct e1000_host_mng_command_info {
struct e1000_host_mng_command_header command_header; /* Command Head/Command Result Head has 4 bytes */
uint8_t command_data[E1000_HI_MAX_MNG_DATA_LENGTH]; /* Command data can length 0..0x658*/
};
#ifdef __BIG_ENDIAN
struct e1000_host_mng_dhcp_cookie{
uint32_t signature;
uint16_t vlan_id;
uint8_t reserved0;
uint8_t status;
uint32_t reserved1;
uint8_t checksum;
uint8_t reserved3;
uint16_t reserved2;
};
#else
struct e1000_host_mng_dhcp_cookie{
uint32_t signature;
uint8_t status;
uint8_t reserved0;
uint16_t vlan_id;
uint32_t reserved1;
uint16_t reserved2;
uint8_t reserved3;
uint8_t checksum;
};
#endif
int32_t e1000_mng_write_dhcp_info(struct e1000_hw *hw, uint8_t *buffer,
uint16_t length);
boolean_t e1000_check_mng_mode(struct e1000_hw *hw);
boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer,
uint16_t length, uint16_t offset, uint8_t *sum);
int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw,
struct e1000_host_mng_command_header* hdr);
int32_t e1000_mng_write_commit(struct e1000_hw *hw);
int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data); int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw); int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw); int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data); int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num); int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
int32_t e1000_read_mac_addr(struct e1000_hw * hw); int32_t e1000_read_mac_addr(struct e1000_hw * hw);
int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
/* Filters (multicast, vlan, receive) */ /* Filters (multicast, vlan, receive) */
void e1000_init_rx_addrs(struct e1000_hw *hw); void e1000_init_rx_addrs(struct e1000_hw *hw);
...@@ -313,7 +409,6 @@ int32_t e1000_led_off(struct e1000_hw *hw); ...@@ -313,7 +409,6 @@ int32_t e1000_led_off(struct e1000_hw *hw);
/* Adaptive IFS Functions */ /* Adaptive IFS Functions */
/* Everything else */ /* Everything else */
uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
void e1000_clear_hw_cntrs(struct e1000_hw *hw); void e1000_clear_hw_cntrs(struct e1000_hw *hw);
void e1000_reset_adaptive(struct e1000_hw *hw); void e1000_reset_adaptive(struct e1000_hw *hw);
void e1000_update_adaptive(struct e1000_hw *hw); void e1000_update_adaptive(struct e1000_hw *hw);
...@@ -330,6 +425,19 @@ void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value); ...@@ -330,6 +425,19 @@ void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value); void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up); int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
void e1000_enable_pciex_master(struct e1000_hw *hw);
int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
void e1000_release_software_semaphore(struct e1000_hw *hw);
int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
#define E1000_READ_REG_IO(a, reg) \ #define E1000_READ_REG_IO(a, reg) \
e1000_read_reg_io((a), E1000_##reg) e1000_read_reg_io((a), E1000_##reg)
...@@ -369,6 +477,10 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); ...@@ -369,6 +477,10 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
#define E1000_DEV_ID_82546GB_SERDES 0x107B #define E1000_DEV_ID_82546GB_SERDES 0x107B
#define E1000_DEV_ID_82546GB_PCIE 0x108A #define E1000_DEV_ID_82546GB_PCIE 0x108A
#define E1000_DEV_ID_82547EI 0x1019 #define E1000_DEV_ID_82547EI 0x1019
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
#define NODE_ADDRESS_SIZE 6 #define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6 #define ETH_LENGTH_OF_ADDRESS 6
...@@ -381,6 +493,7 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); ...@@ -381,6 +493,7 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
#define E1000_REVISION_0 0 #define E1000_REVISION_0 0
#define E1000_REVISION_1 1 #define E1000_REVISION_1 1
#define E1000_REVISION_2 2 #define E1000_REVISION_2 2
#define E1000_REVISION_3 3
#define SPEED_10 10 #define SPEED_10 10
#define SPEED_100 100 #define SPEED_100 100
...@@ -437,6 +550,7 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); ...@@ -437,6 +550,7 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
E1000_IMS_RXSEQ | \ E1000_IMS_RXSEQ | \
E1000_IMS_LSC) E1000_IMS_LSC)
/* Number of high/low register pairs in the RAR. The RAR (Receive Address /* Number of high/low register pairs in the RAR. The RAR (Receive Address
* Registers) holds the directed and multicast addresses that we monitor. We * Registers) holds the directed and multicast addresses that we monitor. We
* reserve one of these spots for our directed address, allowing us room for * reserve one of these spots for our directed address, allowing us room for
...@@ -457,14 +571,74 @@ struct e1000_rx_desc { ...@@ -457,14 +571,74 @@ struct e1000_rx_desc {
uint16_t special; uint16_t special;
}; };
/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
struct {
uint64_t buffer_addr;
uint64_t reserved;
} read;
struct {
struct {
uint32_t mrq; /* Multiple Rx Queues */
union {
uint32_t rss; /* RSS Hash */
struct {
uint16_t ip_id; /* IP id */
uint16_t csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
uint32_t status_error; /* ext status/error */
uint16_t length;
uint16_t vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define MAX_PS_BUFFERS 4
/* Receive Descriptor - Packet Split */
union e1000_rx_desc_packet_split {
struct {
/* one buffer for protocol header(s), three data buffers */
uint64_t buffer_addr[MAX_PS_BUFFERS];
} read;
struct {
struct {
uint32_t mrq; /* Multiple Rx Queues */
union {
uint32_t rss; /* RSS Hash */
struct {
uint16_t ip_id; /* IP id */
uint16_t csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
uint32_t status_error; /* ext status/error */
uint16_t length0; /* length of buffer 0 */
uint16_t vlan; /* VLAN tag */
} middle;
struct {
uint16_t header_status;
uint16_t length[3]; /* length of buffers 1-3 */
} upper;
uint64_t reserved;
} wb; /* writeback */
};
/* Receive Decriptor bit definitions */ /* Receive Decriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ #define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ #define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ #define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ #define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ #define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */ #define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */
#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
#define E1000_RXD_ERR_CE 0x01 /* CRC Error */ #define E1000_RXD_ERR_CE 0x01 /* CRC Error */
#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ #define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ #define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
...@@ -474,9 +648,20 @@ struct e1000_rx_desc { ...@@ -474,9 +648,20 @@ struct e1000_rx_desc {
#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ #define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
#define E1000_RXD_SPC_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */ #define E1000_RXD_SPC_PRI_SHIFT 13
#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ #define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */
#define E1000_RXD_SPC_CFI_SHIFT 0x000C /* CFI is bit 12 */ #define E1000_RXD_SPC_CFI_SHIFT 12
#define E1000_RXDEXT_STATERR_CE 0x01000000
#define E1000_RXDEXT_STATERR_SE 0x02000000
#define E1000_RXDEXT_STATERR_SEQ 0x04000000
#define E1000_RXDEXT_STATERR_CXE 0x10000000
#define E1000_RXDEXT_STATERR_TCPE 0x20000000
#define E1000_RXDEXT_STATERR_IPE 0x40000000
#define E1000_RXDEXT_STATERR_RXE 0x80000000
#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
/* mask to determine if packets should be dropped due to frame errors */ /* mask to determine if packets should be dropped due to frame errors */
#define E1000_RXD_ERR_FRAME_ERR_MASK ( \ #define E1000_RXD_ERR_FRAME_ERR_MASK ( \
...@@ -486,6 +671,15 @@ struct e1000_rx_desc { ...@@ -486,6 +671,15 @@ struct e1000_rx_desc {
E1000_RXD_ERR_CXE | \ E1000_RXD_ERR_CXE | \
E1000_RXD_ERR_RXE) E1000_RXD_ERR_RXE)
/* Same mask, but for extended and packet split descriptors */
#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
E1000_RXDEXT_STATERR_CE | \
E1000_RXDEXT_STATERR_SE | \
E1000_RXDEXT_STATERR_SEQ | \
E1000_RXDEXT_STATERR_CXE | \
E1000_RXDEXT_STATERR_RXE)
/* Transmit Descriptor */ /* Transmit Descriptor */
struct e1000_tx_desc { struct e1000_tx_desc {
uint64_t buffer_addr; /* Address of the descriptor's data buffer */ uint64_t buffer_addr; /* Address of the descriptor's data buffer */
...@@ -667,6 +861,7 @@ struct e1000_ffvt_entry { ...@@ -667,6 +861,7 @@ struct e1000_ffvt_entry {
#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ #define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ #define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ #define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_RCTL 0x00100 /* RX Control - RW */ #define E1000_RCTL 0x00100 /* RX Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ #define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */ #define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
...@@ -676,9 +871,23 @@ struct e1000_ffvt_entry { ...@@ -676,9 +871,23 @@ struct e1000_ffvt_entry {
#define E1000_TBT 0x00448 /* TX Burst Timer - RW */ #define E1000_TBT 0x00448 /* TX Burst Timer - RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ #define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */ #define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ #define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_FLASH_UPDATES 1000
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_FLSWCTL 0x01030 /* FLASH control register */
#define E1000_FLSWDATA 0x01034 /* FLASH data register */
#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ #define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ #define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ #define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
...@@ -688,6 +897,7 @@ struct e1000_ffvt_entry { ...@@ -688,6 +897,7 @@ struct e1000_ffvt_entry {
#define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */ #define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */
#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */ #define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */ #define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */ #define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */ #define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */ #define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
...@@ -703,6 +913,14 @@ struct e1000_ffvt_entry { ...@@ -703,6 +913,14 @@ struct e1000_ffvt_entry {
#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */ #define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */
#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */ #define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */
#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */ #define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */
#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */
#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */
#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */
#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */
#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */
#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */
#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ #define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ #define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ #define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
...@@ -761,7 +979,17 @@ struct e1000_ffvt_entry { ...@@ -761,7 +979,17 @@ struct e1000_ffvt_entry {
#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */ #define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */ #define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */ #define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
#define E1000_IAC 0x4100 /* Interrupt Assertion Count */
#define E1000_ICRXPTC 0x4104 /* Interrupt Cause Rx Packet Timer Expire Count */
#define E1000_ICRXATC 0x4108 /* Interrupt Cause Rx Absolute Timer Expire Count */
#define E1000_ICTXPTC 0x410C /* Interrupt Cause Tx Packet Timer Expire Count */
#define E1000_ICTXATC 0x4110 /* Interrupt Cause Tx Absolute Timer Expire Count */
#define E1000_ICTXQEC 0x4118 /* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQMTC 0x411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
#define E1000_ICRXDMTC 0x4120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXOC 0x4124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */ #define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */ #define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */ #define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */ #define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
...@@ -779,6 +1007,16 @@ struct e1000_ffvt_entry { ...@@ -779,6 +1007,16 @@ struct e1000_ffvt_entry {
#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ #define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */ #define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
#define E1000_GCR 0x05B00 /* PCI-Ex Control */
#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Inteface Control */
/* Register Set (82542) /* Register Set (82542)
* *
* Some of the 82542 registers are located at different offsets than they are * Some of the 82542 registers are located at different offsets than they are
...@@ -829,6 +1067,18 @@ struct e1000_ffvt_entry { ...@@ -829,6 +1067,18 @@ struct e1000_ffvt_entry {
#define E1000_82542_VFTA 0x00600 #define E1000_82542_VFTA 0x00600
#define E1000_82542_LEDCTL E1000_LEDCTL #define E1000_82542_LEDCTL E1000_LEDCTL
#define E1000_82542_PBA E1000_PBA #define E1000_82542_PBA E1000_PBA
#define E1000_82542_PBS E1000_PBS
#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
#define E1000_82542_EEARBC E1000_EEARBC
#define E1000_82542_FLASHT E1000_FLASHT
#define E1000_82542_EEWR E1000_EEWR
#define E1000_82542_FLSWCTL E1000_FLSWCTL
#define E1000_82542_FLSWDATA E1000_FLSWDATA
#define E1000_82542_FLSWCNT E1000_FLSWCNT
#define E1000_82542_FLOP E1000_FLOP
#define E1000_82542_EXTCNF_CTRL E1000_EXTCNF_CTRL
#define E1000_82542_EXTCNF_SIZE E1000_EXTCNF_SIZE
#define E1000_82542_ERT E1000_ERT
#define E1000_82542_RXDCTL E1000_RXDCTL #define E1000_82542_RXDCTL E1000_RXDCTL
#define E1000_82542_RADV E1000_RADV #define E1000_82542_RADV E1000_RADV
#define E1000_82542_RSRPD E1000_RSRPD #define E1000_82542_RSRPD E1000_RSRPD
...@@ -913,6 +1163,38 @@ struct e1000_ffvt_entry { ...@@ -913,6 +1163,38 @@ struct e1000_ffvt_entry {
#define E1000_82542_FFMT E1000_FFMT #define E1000_82542_FFMT E1000_FFMT
#define E1000_82542_FFVT E1000_FFVT #define E1000_82542_FFVT E1000_FFVT
#define E1000_82542_HOST_IF E1000_HOST_IF #define E1000_82542_HOST_IF E1000_HOST_IF
#define E1000_82542_IAM E1000_IAM
#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
#define E1000_82542_PSRCTL E1000_PSRCTL
#define E1000_82542_RAID E1000_RAID
#define E1000_82542_TARC0 E1000_TARC0
#define E1000_82542_TDBAL1 E1000_TDBAL1
#define E1000_82542_TDBAH1 E1000_TDBAH1
#define E1000_82542_TDLEN1 E1000_TDLEN1
#define E1000_82542_TDH1 E1000_TDH1
#define E1000_82542_TDT1 E1000_TDT1
#define E1000_82542_TXDCTL1 E1000_TXDCTL1
#define E1000_82542_TARC1 E1000_TARC1
#define E1000_82542_RFCTL E1000_RFCTL
#define E1000_82542_GCR E1000_GCR
#define E1000_82542_GSCL_1 E1000_GSCL_1
#define E1000_82542_GSCL_2 E1000_GSCL_2
#define E1000_82542_GSCL_3 E1000_GSCL_3
#define E1000_82542_GSCL_4 E1000_GSCL_4
#define E1000_82542_FACTPS E1000_FACTPS
#define E1000_82542_SWSM E1000_SWSM
#define E1000_82542_FWSM E1000_FWSM
#define E1000_82542_FFLT_DBG E1000_FFLT_DBG
#define E1000_82542_IAC E1000_IAC
#define E1000_82542_ICRXPTC E1000_ICRXPTC
#define E1000_82542_ICRXATC E1000_ICRXATC
#define E1000_82542_ICTXPTC E1000_ICTXPTC
#define E1000_82542_ICTXATC E1000_ICTXATC
#define E1000_82542_ICTXQEC E1000_ICTXQEC
#define E1000_82542_ICTXQMTC E1000_ICTXQMTC
#define E1000_82542_ICRXDMTC E1000_ICRXDMTC
#define E1000_82542_ICRXOC E1000_ICRXOC
#define E1000_82542_HICR E1000_HICR
/* Statistics counters collected by the MAC */ /* Statistics counters collected by the MAC */
struct e1000_hw_stats { struct e1000_hw_stats {
...@@ -974,11 +1256,21 @@ struct e1000_hw_stats { ...@@ -974,11 +1256,21 @@ struct e1000_hw_stats {
uint64_t bptc; uint64_t bptc;
uint64_t tsctc; uint64_t tsctc;
uint64_t tsctfc; uint64_t tsctfc;
uint64_t iac;
uint64_t icrxptc;
uint64_t icrxatc;
uint64_t ictxptc;
uint64_t ictxatc;
uint64_t ictxqec;
uint64_t ictxqmtc;
uint64_t icrxdmtc;
uint64_t icrxoc;
}; };
/* Structure containing variables used by the shared code (e1000_hw.c) */ /* Structure containing variables used by the shared code (e1000_hw.c) */
struct e1000_hw { struct e1000_hw {
uint8_t __iomem *hw_addr; uint8_t *hw_addr;
uint8_t *flash_address;
e1000_mac_type mac_type; e1000_mac_type mac_type;
e1000_phy_type phy_type; e1000_phy_type phy_type;
uint32_t phy_init_script; uint32_t phy_init_script;
...@@ -993,6 +1285,7 @@ struct e1000_hw { ...@@ -993,6 +1285,7 @@ struct e1000_hw {
e1000_ms_type original_master_slave; e1000_ms_type original_master_slave;
e1000_ffe_config ffe_config_state; e1000_ffe_config ffe_config_state;
uint32_t asf_firmware_present; uint32_t asf_firmware_present;
uint32_t eeprom_semaphore_present;
unsigned long io_base; unsigned long io_base;
uint32_t phy_id; uint32_t phy_id;
uint32_t phy_revision; uint32_t phy_revision;
...@@ -1009,6 +1302,8 @@ struct e1000_hw { ...@@ -1009,6 +1302,8 @@ struct e1000_hw {
uint32_t ledctl_default; uint32_t ledctl_default;
uint32_t ledctl_mode1; uint32_t ledctl_mode1;
uint32_t ledctl_mode2; uint32_t ledctl_mode2;
boolean_t tx_pkt_filtering;
struct e1000_host_mng_dhcp_cookie mng_cookie;
uint16_t phy_spd_default; uint16_t phy_spd_default;
uint16_t autoneg_advertised; uint16_t autoneg_advertised;
uint16_t pci_cmd_word; uint16_t pci_cmd_word;
...@@ -1047,16 +1342,24 @@ struct e1000_hw { ...@@ -1047,16 +1342,24 @@ struct e1000_hw {
boolean_t adaptive_ifs; boolean_t adaptive_ifs;
boolean_t ifs_params_forced; boolean_t ifs_params_forced;
boolean_t in_ifs_mode; boolean_t in_ifs_mode;
boolean_t mng_reg_access_disabled;
}; };
#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */ #define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */ #define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */
#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */
#define E1000_EEPROM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */
#define E1000_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */
#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */
/* Register Bit Masks */ /* Register Bit Masks */
/* Device Control */ /* Device Control */
#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ #define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */ #define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */ #define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */ #define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */ #define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */ #define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
...@@ -1070,6 +1373,7 @@ struct e1000_hw { ...@@ -1070,6 +1373,7 @@ struct e1000_hw {
#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ #define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ #define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ #define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
...@@ -1089,6 +1393,7 @@ struct e1000_hw { ...@@ -1089,6 +1393,7 @@ struct e1000_hw {
#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */ #define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ #define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */ #define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
#define E1000_STATUS_FUNC_SHIFT 2
#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ #define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */
#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */ #define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ #define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
...@@ -1098,6 +1403,8 @@ struct e1000_hw { ...@@ -1098,6 +1403,8 @@ struct e1000_hw {
#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ #define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ #define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ #define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */ #define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */ #define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ #define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
...@@ -1128,6 +1435,18 @@ struct e1000_hw { ...@@ -1128,6 +1435,18 @@ struct e1000_hw {
#ifndef E1000_EEPROM_GRANT_ATTEMPTS #ifndef E1000_EEPROM_GRANT_ATTEMPTS
#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */ #define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
#endif #endif
#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */
#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */
#define E1000_EECD_SIZE_EX_SHIFT 11
#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */
#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
#define E1000_STM_OPCODE 0xDB00
#define E1000_HICR_FW_RESET 0xC0
/* EEPROM Read */ /* EEPROM Read */
#define E1000_EERD_START 0x00000001 /* Start Read */ #define E1000_EERD_START 0x00000001 /* Start Read */
...@@ -1171,6 +1490,8 @@ struct e1000_hw { ...@@ -1171,6 +1490,8 @@ struct e1000_hw {
#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000 #define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000 #define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000 #define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
/* MDI Control */ /* MDI Control */
#define E1000_MDIC_DATA_MASK 0x0000FFFF #define E1000_MDIC_DATA_MASK 0x0000FFFF
...@@ -1187,14 +1508,17 @@ struct e1000_hw { ...@@ -1187,14 +1508,17 @@ struct e1000_hw {
/* LED Control */ /* LED Control */
#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F #define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
#define E1000_LEDCTL_LED0_MODE_SHIFT 0 #define E1000_LEDCTL_LED0_MODE_SHIFT 0
#define E1000_LEDCTL_LED0_BLINK_RATE 0x0000020
#define E1000_LEDCTL_LED0_IVRT 0x00000040 #define E1000_LEDCTL_LED0_IVRT 0x00000040
#define E1000_LEDCTL_LED0_BLINK 0x00000080 #define E1000_LEDCTL_LED0_BLINK 0x00000080
#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00 #define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00
#define E1000_LEDCTL_LED1_MODE_SHIFT 8 #define E1000_LEDCTL_LED1_MODE_SHIFT 8
#define E1000_LEDCTL_LED1_BLINK_RATE 0x0002000
#define E1000_LEDCTL_LED1_IVRT 0x00004000 #define E1000_LEDCTL_LED1_IVRT 0x00004000
#define E1000_LEDCTL_LED1_BLINK 0x00008000 #define E1000_LEDCTL_LED1_BLINK 0x00008000
#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000 #define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000
#define E1000_LEDCTL_LED2_MODE_SHIFT 16 #define E1000_LEDCTL_LED2_MODE_SHIFT 16
#define E1000_LEDCTL_LED2_BLINK_RATE 0x00200000
#define E1000_LEDCTL_LED2_IVRT 0x00400000 #define E1000_LEDCTL_LED2_IVRT 0x00400000
#define E1000_LEDCTL_LED2_BLINK 0x00800000 #define E1000_LEDCTL_LED2_BLINK 0x00800000
#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000 #define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
...@@ -1238,6 +1562,10 @@ struct e1000_hw { ...@@ -1238,6 +1562,10 @@ struct e1000_hw {
#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ #define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
#define E1000_ICR_TXD_LOW 0x00008000 #define E1000_ICR_TXD_LOW 0x00008000
#define E1000_ICR_SRPD 0x00010000 #define E1000_ICR_SRPD 0x00010000
#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
#define E1000_ICR_MNG 0x00040000 /* Manageability event */
#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */
/* Interrupt Cause Set */ /* Interrupt Cause Set */
#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ #define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
...@@ -1255,6 +1583,9 @@ struct e1000_hw { ...@@ -1255,6 +1583,9 @@ struct e1000_hw {
#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ #define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW #define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
#define E1000_ICS_SRPD E1000_ICR_SRPD #define E1000_ICS_SRPD E1000_ICR_SRPD
#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */
#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */
#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */
/* Interrupt Mask Set */ /* Interrupt Mask Set */
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ #define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
...@@ -1272,6 +1603,9 @@ struct e1000_hw { ...@@ -1272,6 +1603,9 @@ struct e1000_hw {
#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ #define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW #define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
#define E1000_IMS_SRPD E1000_ICR_SRPD #define E1000_IMS_SRPD E1000_ICR_SRPD
#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */
#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */
#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */
/* Interrupt Mask Clear */ /* Interrupt Mask Clear */
#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */ #define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
...@@ -1289,6 +1623,9 @@ struct e1000_hw { ...@@ -1289,6 +1623,9 @@ struct e1000_hw {
#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ #define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW #define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
#define E1000_IMC_SRPD E1000_ICR_SRPD #define E1000_IMC_SRPD E1000_ICR_SRPD
#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */
#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */
#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */
/* Receive Control */ /* Receive Control */
#define E1000_RCTL_RST 0x00000001 /* Software reset */ #define E1000_RCTL_RST 0x00000001 /* Software reset */
...@@ -1301,6 +1638,8 @@ struct e1000_hw { ...@@ -1301,6 +1638,8 @@ struct e1000_hw {
#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ #define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ #define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ #define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */
#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ #define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */ #define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */ #define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
...@@ -1327,6 +1666,34 @@ struct e1000_hw { ...@@ -1327,6 +1666,34 @@ struct e1000_hw {
#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ #define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ #define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ #define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */
#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */
/* Use byte values for the following shift parameters
* Usage:
* psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
* E1000_PSRCTL_BSIZE0_MASK) |
* ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
* E1000_PSRCTL_BSIZE1_MASK) |
* ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
* E1000_PSRCTL_BSIZE2_MASK) |
* ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
* E1000_PSRCTL_BSIZE3_MASK))
* where value0 = [128..16256], default=256
* value1 = [1024..64512], default=4096
* value2 = [0..64512], default=4096
* value3 = [0..64512], default=0
*/
#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F
#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00
#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000
#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000
#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */
#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */
#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */
#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */
/* Receive Descriptor */ /* Receive Descriptor */
#define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */ #define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */
...@@ -1341,6 +1708,23 @@ struct e1000_hw { ...@@ -1341,6 +1708,23 @@ struct e1000_hw {
#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */ #define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ #define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
/* Header split receive */
#define E1000_RFCTL_ISCSI_DIS 0x00000001
#define E1000_RFCTL_ISCSI_DWC_MASK 0x0000003E
#define E1000_RFCTL_ISCSI_DWC_SHIFT 1
#define E1000_RFCTL_NFSW_DIS 0x00000040
#define E1000_RFCTL_NFSR_DIS 0x00000080
#define E1000_RFCTL_NFS_VER_MASK 0x00000300
#define E1000_RFCTL_NFS_VER_SHIFT 8
#define E1000_RFCTL_IPV6_DIS 0x00000400
#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800
#define E1000_RFCTL_ACK_DIS 0x00001000
#define E1000_RFCTL_ACKD_DIS 0x00002000
#define E1000_RFCTL_IPFRSP_DIS 0x00004000
#define E1000_RFCTL_EXTEN 0x00008000
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
/* Receive Descriptor Control */ /* Receive Descriptor Control */
#define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */ #define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */
#define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */ #define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */
...@@ -1354,6 +1738,8 @@ struct e1000_hw { ...@@ -1354,6 +1738,8 @@ struct e1000_hw {
#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ #define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc.
still to be processed. */
/* Transmit Configuration Word */ /* Transmit Configuration Word */
#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */ #define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
...@@ -1387,12 +1773,16 @@ struct e1000_hw { ...@@ -1387,12 +1773,16 @@ struct e1000_hw {
#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ #define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */
#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ #define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ #define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
/* Receive Checksum Control */ /* Receive Checksum Control */
#define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */ #define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */
#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ #define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */
#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
#define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */ #define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* Definitions for power management and wakeup registers */ /* Definitions for power management and wakeup registers */
/* Wake Up Control */ /* Wake Up Control */
...@@ -1411,6 +1801,7 @@ struct e1000_hw { ...@@ -1411,6 +1801,7 @@ struct e1000_hw {
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ #define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */ #define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */ #define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */ #define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */ #define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */ #define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
...@@ -1446,13 +1837,19 @@ struct e1000_hw { ...@@ -1446,13 +1837,19 @@ struct e1000_hw {
#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ #define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery #define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery
* Filtering */ * Filtering */
#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */
#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ #define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */
#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ #define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address #define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address
* filtering */ * filtering */
#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host #define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host
* memory */ * memory */
#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address
* filtering */
#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */
#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */
#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */ #define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */ #define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */ #define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
...@@ -1463,11 +1860,97 @@ struct e1000_hw { ...@@ -1463,11 +1860,97 @@ struct e1000_hw {
#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ #define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ #define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
/* SW Semaphore Register */
#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */
#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
/* FW Semaphore Register */
#define E1000_FWSM_MODE_MASK 0x0000000E /* FW mode */
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_FWSM_FW_VALID 0x00008000 /* FW established a valid mode */
/* FFLT Debug Register */
#define E1000_FFLT_DBG_INVC 0x00100000 /* Invalid /C/ code handling */
typedef enum {
e1000_mng_mode_none = 0,
e1000_mng_mode_asf,
e1000_mng_mode_pt,
e1000_mng_mode_ipmi,
e1000_mng_mode_host_interface_only
} e1000_mng_mode;
/* Host Inteface Control Register */
#define E1000_HICR_EN 0x00000001 /* Enable Bit - RO */
#define E1000_HICR_C 0x00000002 /* Driver sets this bit when done
* to put command in RAM */
#define E1000_HICR_SV 0x00000004 /* Status Validity */
#define E1000_HICR_FWR 0x00000080 /* FW reset. Set by the Host */
/* Host Interface Command Interface - Address range 0x8800-0x8EFF */
#define E1000_HI_MAX_DATA_LENGTH 252 /* Host Interface data length */
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Number of bytes in range */
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Number of dwords in range */
#define E1000_HI_COMMAND_TIMEOUT 500 /* Time in ms to process HI command */
struct e1000_host_command_header {
uint8_t command_id;
uint8_t command_length;
uint8_t command_options; /* I/F bits for command, status for return */
uint8_t checksum;
};
struct e1000_host_command_info {
struct e1000_host_command_header command_header; /* Command Head/Command Result Head has 4 bytes */
uint8_t command_data[E1000_HI_MAX_DATA_LENGTH]; /* Command data can length 0..252 */
};
/* Host SMB register #0 */
#define E1000_HSMC0R_CLKIN 0x00000001 /* SMB Clock in */
#define E1000_HSMC0R_DATAIN 0x00000002 /* SMB Data in */
#define E1000_HSMC0R_DATAOUT 0x00000004 /* SMB Data out */
#define E1000_HSMC0R_CLKOUT 0x00000008 /* SMB Clock out */
/* Host SMB register #1 */
#define E1000_HSMC1R_CLKIN E1000_HSMC0R_CLKIN
#define E1000_HSMC1R_DATAIN E1000_HSMC0R_DATAIN
#define E1000_HSMC1R_DATAOUT E1000_HSMC0R_DATAOUT
#define E1000_HSMC1R_CLKOUT E1000_HSMC0R_CLKOUT
/* FW Status Register */
#define E1000_FWSTS_FWS_MASK 0x000000FF /* FW Status */
/* Wake Up Packet Length */ /* Wake Up Packet Length */
#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */ #define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */
#define E1000_MDALIGN 4096 #define E1000_MDALIGN 4096
#define E1000_GCR_BEM32 0x00400000
/* Function Active and Power State to MNG */
#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003
#define E1000_FACTPS_LAN0_VALID 0x00000004
#define E1000_FACTPS_FUNC0_AUX_EN 0x00000008
#define E1000_FACTPS_FUNC1_POWER_STATE_MASK 0x000000C0
#define E1000_FACTPS_FUNC1_POWER_STATE_SHIFT 6
#define E1000_FACTPS_LAN1_VALID 0x00000100
#define E1000_FACTPS_FUNC1_AUX_EN 0x00000200
#define E1000_FACTPS_FUNC2_POWER_STATE_MASK 0x00003000
#define E1000_FACTPS_FUNC2_POWER_STATE_SHIFT 12
#define E1000_FACTPS_IDE_ENABLE 0x00004000
#define E1000_FACTPS_FUNC2_AUX_EN 0x00008000
#define E1000_FACTPS_FUNC3_POWER_STATE_MASK 0x000C0000
#define E1000_FACTPS_FUNC3_POWER_STATE_SHIFT 18
#define E1000_FACTPS_SP_ENABLE 0x00100000
#define E1000_FACTPS_FUNC3_AUX_EN 0x00200000
#define E1000_FACTPS_FUNC4_POWER_STATE_MASK 0x03000000
#define E1000_FACTPS_FUNC4_POWER_STATE_SHIFT 24
#define E1000_FACTPS_IPMI_ENABLE 0x04000000
#define E1000_FACTPS_FUNC4_AUX_EN 0x08000000
#define E1000_FACTPS_MNGCG 0x20000000
#define E1000_FACTPS_LAN_FUNC_SEL 0x40000000
#define E1000_FACTPS_PM_STATE_CHANGED 0x80000000
/* EEPROM Commands - Microwire */ /* EEPROM Commands - Microwire */
#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */ #define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */ #define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
...@@ -1477,22 +1960,20 @@ struct e1000_hw { ...@@ -1477,22 +1960,20 @@ struct e1000_hw {
/* EEPROM Commands - SPI */ /* EEPROM Commands - SPI */
#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ #define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
#define EEPROM_READ_OPCODE_SPI 0x3 /* EEPROM read opcode */ #define EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_SPI 0x2 /* EEPROM write opcode */ #define EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */
#define EEPROM_A8_OPCODE_SPI 0x8 /* opcode bit-3 = address bit-8 */ #define EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */
#define EEPROM_WREN_OPCODE_SPI 0x6 /* EEPROM set Write Enable latch */ #define EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Enable latch */
#define EEPROM_WRDI_OPCODE_SPI 0x4 /* EEPROM reset Write Enable latch */ #define EEPROM_WRDI_OPCODE_SPI 0x04 /* EEPROM reset Write Enable latch */
#define EEPROM_RDSR_OPCODE_SPI 0x5 /* EEPROM read Status register */ #define EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status register */
#define EEPROM_WRSR_OPCODE_SPI 0x1 /* EEPROM write Status register */ #define EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status register */
#define EEPROM_ERASE4K_OPCODE_SPI 0x20 /* EEPROM ERASE 4KB */
#define EEPROM_ERASE64K_OPCODE_SPI 0xD8 /* EEPROM ERASE 64KB */
#define EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */
/* EEPROM Size definitions */ /* EEPROM Size definitions */
#define EEPROM_SIZE_16KB 0x1800 #define EEPROM_WORD_SIZE_SHIFT 6
#define EEPROM_SIZE_8KB 0x1400 #define EEPROM_SIZE_SHIFT 10
#define EEPROM_SIZE_4KB 0x1000
#define EEPROM_SIZE_2KB 0x0C00
#define EEPROM_SIZE_1KB 0x0800
#define EEPROM_SIZE_512B 0x0400
#define EEPROM_SIZE_128B 0x0000
#define EEPROM_SIZE_MASK 0x1C00 #define EEPROM_SIZE_MASK 0x1C00
/* EEPROM Word Offsets */ /* EEPROM Word Offsets */
...@@ -1606,7 +2087,22 @@ struct e1000_hw { ...@@ -1606,7 +2087,22 @@ struct e1000_hw {
#define IFS_MIN 40 #define IFS_MIN 40
#define IFS_RATIO 4 #define IFS_RATIO 4
/* Extended Configuration Control and Size */
#define E1000_EXTCNF_CTRL_PCIE_WRITE_ENABLE 0x00000001
#define E1000_EXTCNF_CTRL_PHY_WRITE_ENABLE 0x00000002
#define E1000_EXTCNF_CTRL_D_UD_ENABLE 0x00000004
#define E1000_EXTCNF_CTRL_D_UD_LATENCY 0x00000008
#define E1000_EXTCNF_CTRL_D_UD_OWNER 0x00000010
#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
#define E1000_EXTCNF_CTRL_MDIO_HW_OWNERSHIP 0x00000040
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER 0x1FFF0000
#define E1000_EXTCNF_SIZE_EXT_PHY_LENGTH 0x000000FF
#define E1000_EXTCNF_SIZE_EXT_DOCK_LENGTH 0x0000FF00
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH 0x00FF0000
/* PBA constants */ /* PBA constants */
#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */
#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
#define E1000_PBA_22K 0x0016 #define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018 #define E1000_PBA_24K 0x0018
...@@ -1663,6 +2159,13 @@ struct e1000_hw { ...@@ -1663,6 +2159,13 @@ struct e1000_hw {
/* Number of milliseconds we wait for auto-negotiation to complete */ /* Number of milliseconds we wait for auto-negotiation to complete */
#define LINK_UP_TIMEOUT 500 #define LINK_UP_TIMEOUT 500
/* Number of 100 microseconds we wait for PCI Express master disable */
#define MASTER_DISABLE_TIMEOUT 800
/* Number of milliseconds we wait for Eeprom auto read bit done after MAC reset */
#define AUTO_READ_DONE_TIMEOUT 10
/* Number of milliseconds we wait for PHY configuration done after MAC reset */
#define PHY_CFG_TIMEOUT 40
#define E1000_TX_BUFFER_SIZE ((uint32_t)1514) #define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
/* The carrier extension symbol, as received by the NIC. */ /* The carrier extension symbol, as received by the NIC. */
...@@ -1763,6 +2266,7 @@ struct e1000_hw { ...@@ -1763,6 +2266,7 @@ struct e1000_hw {
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */ #define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */
#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */ #define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */
#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */ #define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */
#define IGP02E1000_PHY_POWER_MGMT 0x19
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */ #define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */
/* IGP01E1000 AGC Registers - stores the cable length values*/ /* IGP01E1000 AGC Registers - stores the cable length values*/
...@@ -1771,12 +2275,20 @@ struct e1000_hw { ...@@ -1771,12 +2275,20 @@ struct e1000_hw {
#define IGP01E1000_PHY_AGC_C 0x1472 #define IGP01E1000_PHY_AGC_C 0x1472
#define IGP01E1000_PHY_AGC_D 0x1872 #define IGP01E1000_PHY_AGC_D 0x1872
/* IGP02E1000 AGC Registers for cable length values */
#define IGP02E1000_PHY_AGC_A 0x11B1
#define IGP02E1000_PHY_AGC_B 0x12B1
#define IGP02E1000_PHY_AGC_C 0x14B1
#define IGP02E1000_PHY_AGC_D 0x18B1
/* IGP01E1000 DSP Reset Register */ /* IGP01E1000 DSP Reset Register */
#define IGP01E1000_PHY_DSP_RESET 0x1F33 #define IGP01E1000_PHY_DSP_RESET 0x1F33
#define IGP01E1000_PHY_DSP_SET 0x1F71 #define IGP01E1000_PHY_DSP_SET 0x1F71
#define IGP01E1000_PHY_DSP_FFE 0x1F35 #define IGP01E1000_PHY_DSP_FFE 0x1F35
#define IGP01E1000_PHY_CHANNEL_NUM 4 #define IGP01E1000_PHY_CHANNEL_NUM 4
#define IGP02E1000_PHY_CHANNEL_NUM 4
#define IGP01E1000_PHY_AGC_PARAM_A 0x1171 #define IGP01E1000_PHY_AGC_PARAM_A 0x1171
#define IGP01E1000_PHY_AGC_PARAM_B 0x1271 #define IGP01E1000_PHY_AGC_PARAM_B 0x1271
#define IGP01E1000_PHY_AGC_PARAM_C 0x1471 #define IGP01E1000_PHY_AGC_PARAM_C 0x1471
...@@ -2060,20 +2572,30 @@ struct e1000_hw { ...@@ -2060,20 +2572,30 @@ struct e1000_hw {
#define IGP01E1000_MSE_CHANNEL_B 0x0F00 #define IGP01E1000_MSE_CHANNEL_B 0x0F00
#define IGP01E1000_MSE_CHANNEL_A 0xF000 #define IGP01E1000_MSE_CHANNEL_A 0xF000
#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
#define IGP02E1000_PM_D3_LPLU 0x0004 /* Enable LPLU in non-D0a modes */
#define IGP02E1000_PM_D0_LPLU 0x0002 /* Enable LPLU in D0a mode */
/* IGP01E1000 DSP reset macros */ /* IGP01E1000 DSP reset macros */
#define DSP_RESET_ENABLE 0x0 #define DSP_RESET_ENABLE 0x0
#define DSP_RESET_DISABLE 0x2 #define DSP_RESET_DISABLE 0x2
#define E1000_MAX_DSP_RESETS 10 #define E1000_MAX_DSP_RESETS 10
/* IGP01E1000 AGC Registers */ /* IGP01E1000 & IGP02E1000 AGC Registers */
#define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */ #define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Coarse - 15:13, Fine - 12:9 */
/* IGP02E1000 AGC Register Length 9-bit mask */
#define IGP02E1000_AGC_LENGTH_MASK 0x7F
/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */ /* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128 #define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128
/* The precision of the length is +/- 10 meters */ /* The precision error of the cable length is +/- 10 meters */
#define IGP01E1000_AGC_RANGE 10 #define IGP01E1000_AGC_RANGE 10
#define IGP02E1000_AGC_RANGE 10
/* IGP01E1000 PCS Initialization register */ /* IGP01E1000 PCS Initialization register */
/* bits 3:6 in the PCS registers stores the channels polarity */ /* bits 3:6 in the PCS registers stores the channels polarity */
...@@ -2113,6 +2635,8 @@ struct e1000_hw { ...@@ -2113,6 +2635,8 @@ struct e1000_hw {
#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID #define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
#define M88E1011_I_REV_4 0x04 #define M88E1011_I_REV_4 0x04
#define M88E1111_I_PHY_ID 0x01410CC0
#define L1LXT971A_PHY_ID 0x001378E0
/* Miscellaneous PHY bit definitions. */ /* Miscellaneous PHY bit definitions. */
#define PHY_PREAMBLE 0xFFFFFFFF #define PHY_PREAMBLE 0xFFFFFFFF
......
...@@ -155,10 +155,14 @@ static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter); ...@@ -155,10 +155,14 @@ static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
static int e1000_clean(struct net_device *netdev, int *budget); static int e1000_clean(struct net_device *netdev, int *budget);
static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter, static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
int *work_done, int work_to_do); int *work_done, int work_to_do);
static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
int *work_done, int work_to_do);
#else #else
static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter); static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter);
static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter);
#endif #endif
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter); static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter);
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
int cmd); int cmd);
...@@ -286,7 +290,29 @@ e1000_irq_enable(struct e1000_adapter *adapter) ...@@ -286,7 +290,29 @@ e1000_irq_enable(struct e1000_adapter *adapter)
E1000_WRITE_FLUSH(&adapter->hw); E1000_WRITE_FLUSH(&adapter->hw);
} }
} }
void
e1000_update_mng_vlan(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
uint16_t vid = adapter->hw.mng_cookie.vlan_id;
uint16_t old_vid = adapter->mng_vlan_id;
if(adapter->vlgrp) {
if(!adapter->vlgrp->vlan_devices[vid]) {
if(adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
e1000_vlan_rx_add_vid(netdev, vid);
adapter->mng_vlan_id = vid;
} else
adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
if((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) &&
(vid != old_vid) &&
!adapter->vlgrp->vlan_devices[old_vid])
e1000_vlan_rx_kill_vid(netdev, old_vid);
}
}
}
int int
e1000_up(struct e1000_adapter *adapter) e1000_up(struct e1000_adapter *adapter)
{ {
...@@ -310,7 +336,7 @@ e1000_up(struct e1000_adapter *adapter) ...@@ -310,7 +336,7 @@ e1000_up(struct e1000_adapter *adapter)
e1000_configure_tx(adapter); e1000_configure_tx(adapter);
e1000_setup_rctl(adapter); e1000_setup_rctl(adapter);
e1000_configure_rx(adapter); e1000_configure_rx(adapter);
e1000_alloc_rx_buffers(adapter); adapter->alloc_rx_buf(adapter);
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
if(adapter->hw.mac_type > e1000_82547_rev_2) { if(adapter->hw.mac_type > e1000_82547_rev_2) {
...@@ -366,8 +392,12 @@ e1000_down(struct e1000_adapter *adapter) ...@@ -366,8 +392,12 @@ e1000_down(struct e1000_adapter *adapter)
e1000_clean_rx_ring(adapter); e1000_clean_rx_ring(adapter);
/* If WoL is not enabled /* If WoL is not enabled
* and management mode is not IAMT
* Power down the PHY so no link is implied when interface is down */ * Power down the PHY so no link is implied when interface is down */
if(!adapter->wol && adapter->hw.media_type == e1000_media_type_copper) { if(!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
adapter->hw.media_type == e1000_media_type_copper &&
!e1000_check_mng_mode(&adapter->hw) &&
!(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN)) {
uint16_t mii_reg; uint16_t mii_reg;
e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg); e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
mii_reg |= MII_CR_POWER_DOWN; mii_reg |= MII_CR_POWER_DOWN;
...@@ -379,28 +409,34 @@ e1000_down(struct e1000_adapter *adapter) ...@@ -379,28 +409,34 @@ e1000_down(struct e1000_adapter *adapter)
void void
e1000_reset(struct e1000_adapter *adapter) e1000_reset(struct e1000_adapter *adapter)
{ {
uint32_t pba; uint32_t pba, manc;
/* Repartition Pba for greater than 9k mtu /* Repartition Pba for greater than 9k mtu
* To take effect CTRL.RST is required. * To take effect CTRL.RST is required.
*/ */
if(adapter->hw.mac_type < e1000_82547) { switch (adapter->hw.mac_type) {
if(adapter->rx_buffer_len > E1000_RXBUFFER_8192) case e1000_82547:
pba = E1000_PBA_40K; pba = E1000_PBA_30K;
else break;
pba = E1000_PBA_48K; case e1000_82573:
} else { pba = E1000_PBA_12K;
if(adapter->rx_buffer_len > E1000_RXBUFFER_8192) break;
pba = E1000_PBA_22K; default:
else pba = E1000_PBA_48K;
pba = E1000_PBA_30K; break;
}
if(adapter->hw.mac_type == e1000_82547) {
adapter->tx_fifo_head = 0; adapter->tx_fifo_head = 0;
adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
adapter->tx_fifo_size = adapter->tx_fifo_size =
(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
atomic_set(&adapter->tx_fifo_stall, 0); atomic_set(&adapter->tx_fifo_stall, 0);
} }
E1000_WRITE_REG(&adapter->hw, PBA, pba); E1000_WRITE_REG(&adapter->hw, PBA, pba);
/* flow control settings */ /* flow control settings */
...@@ -412,17 +448,23 @@ e1000_reset(struct e1000_adapter *adapter) ...@@ -412,17 +448,23 @@ e1000_reset(struct e1000_adapter *adapter)
adapter->hw.fc_send_xon = 1; adapter->hw.fc_send_xon = 1;
adapter->hw.fc = adapter->hw.original_fc; adapter->hw.fc = adapter->hw.original_fc;
/* Allow time for pending master requests to run */
e1000_reset_hw(&adapter->hw); e1000_reset_hw(&adapter->hw);
if(adapter->hw.mac_type >= e1000_82544) if(adapter->hw.mac_type >= e1000_82544)
E1000_WRITE_REG(&adapter->hw, WUC, 0); E1000_WRITE_REG(&adapter->hw, WUC, 0);
if(e1000_init_hw(&adapter->hw)) if(e1000_init_hw(&adapter->hw))
DPRINTK(PROBE, ERR, "Hardware Error\n"); DPRINTK(PROBE, ERR, "Hardware Error\n");
e1000_update_mng_vlan(adapter);
/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE); E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE);
e1000_reset_adaptive(&adapter->hw); e1000_reset_adaptive(&adapter->hw);
e1000_phy_get_info(&adapter->hw, &adapter->phy_info); e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
if (adapter->en_mng_pt) {
manc = E1000_READ_REG(&adapter->hw, MANC);
manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
E1000_WRITE_REG(&adapter->hw, MANC, manc);
}
} }
/** /**
...@@ -443,15 +485,13 @@ e1000_probe(struct pci_dev *pdev, ...@@ -443,15 +485,13 @@ e1000_probe(struct pci_dev *pdev,
{ {
struct net_device *netdev; struct net_device *netdev;
struct e1000_adapter *adapter; struct e1000_adapter *adapter;
unsigned long mmio_start, mmio_len;
uint32_t swsm;
static int cards_found = 0; static int cards_found = 0;
unsigned long mmio_start; int i, err, pci_using_dac;
int mmio_len;
int pci_using_dac;
int i;
int err;
uint16_t eeprom_data; uint16_t eeprom_data;
uint16_t eeprom_apme_mask = E1000_EEPROM_APME; uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
if((err = pci_enable_device(pdev))) if((err = pci_enable_device(pdev)))
return err; return err;
...@@ -538,6 +578,9 @@ e1000_probe(struct pci_dev *pdev, ...@@ -538,6 +578,9 @@ e1000_probe(struct pci_dev *pdev,
if((err = e1000_sw_init(adapter))) if((err = e1000_sw_init(adapter)))
goto err_sw_init; goto err_sw_init;
if((err = e1000_check_phy_reset_block(&adapter->hw)))
DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
if(adapter->hw.mac_type >= e1000_82543) { if(adapter->hw.mac_type >= e1000_82543) {
netdev->features = NETIF_F_SG | netdev->features = NETIF_F_SG |
NETIF_F_HW_CSUM | NETIF_F_HW_CSUM |
...@@ -550,6 +593,11 @@ e1000_probe(struct pci_dev *pdev, ...@@ -550,6 +593,11 @@ e1000_probe(struct pci_dev *pdev,
if((adapter->hw.mac_type >= e1000_82544) && if((adapter->hw.mac_type >= e1000_82544) &&
(adapter->hw.mac_type != e1000_82547)) (adapter->hw.mac_type != e1000_82547))
netdev->features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO;
#ifdef NETIF_F_TSO_IPV6
if(adapter->hw.mac_type > e1000_82547_rev_2)
netdev->features |= NETIF_F_TSO_IPV6;
#endif
#endif #endif
if(pci_using_dac) if(pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA; netdev->features |= NETIF_F_HIGHDMA;
...@@ -557,6 +605,8 @@ e1000_probe(struct pci_dev *pdev, ...@@ -557,6 +605,8 @@ e1000_probe(struct pci_dev *pdev,
/* hard_start_xmit is safe against parallel locking */ /* hard_start_xmit is safe against parallel locking */
netdev->features |= NETIF_F_LLTX; netdev->features |= NETIF_F_LLTX;
adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
/* before reading the EEPROM, reset the controller to /* before reading the EEPROM, reset the controller to
* put the device in a known good starting state */ * put the device in a known good starting state */
...@@ -646,6 +696,17 @@ e1000_probe(struct pci_dev *pdev, ...@@ -646,6 +696,17 @@ e1000_probe(struct pci_dev *pdev,
/* reset the hardware with the new settings */ /* reset the hardware with the new settings */
e1000_reset(adapter); e1000_reset(adapter);
/* Let firmware know the driver has taken over */
switch(adapter->hw.mac_type) {
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm | E1000_SWSM_DRV_LOAD);
break;
default:
break;
}
strcpy(netdev->name, "eth%d"); strcpy(netdev->name, "eth%d");
if((err = register_netdev(netdev))) if((err = register_netdev(netdev)))
goto err_register; goto err_register;
...@@ -681,7 +742,7 @@ e1000_remove(struct pci_dev *pdev) ...@@ -681,7 +742,7 @@ e1000_remove(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
uint32_t manc; uint32_t manc, swsm;
flush_scheduled_work(); flush_scheduled_work();
...@@ -694,9 +755,21 @@ e1000_remove(struct pci_dev *pdev) ...@@ -694,9 +755,21 @@ e1000_remove(struct pci_dev *pdev)
} }
} }
switch(adapter->hw.mac_type) {
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm & ~E1000_SWSM_DRV_LOAD);
break;
default:
break;
}
unregister_netdev(netdev); unregister_netdev(netdev);
e1000_phy_hw_reset(&adapter->hw); if(!e1000_check_phy_reset_block(&adapter->hw))
e1000_phy_hw_reset(&adapter->hw);
iounmap(adapter->hw.hw_addr); iounmap(adapter->hw.hw_addr);
pci_release_regions(pdev); pci_release_regions(pdev);
...@@ -734,6 +807,7 @@ e1000_sw_init(struct e1000_adapter *adapter) ...@@ -734,6 +807,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
adapter->rx_buffer_len = E1000_RXBUFFER_2048; adapter->rx_buffer_len = E1000_RXBUFFER_2048;
adapter->rx_ps_bsize0 = E1000_RXBUFFER_256;
hw->max_frame_size = netdev->mtu + hw->max_frame_size = netdev->mtu +
ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
...@@ -747,7 +821,10 @@ e1000_sw_init(struct e1000_adapter *adapter) ...@@ -747,7 +821,10 @@ e1000_sw_init(struct e1000_adapter *adapter)
/* initialize eeprom parameters */ /* initialize eeprom parameters */
e1000_init_eeprom_params(hw); if(e1000_init_eeprom_params(hw)) {
E1000_ERR("EEPROM initialization failed\n");
return -EIO;
}
switch(hw->mac_type) { switch(hw->mac_type) {
default: default:
...@@ -812,6 +889,11 @@ e1000_open(struct net_device *netdev) ...@@ -812,6 +889,11 @@ e1000_open(struct net_device *netdev)
if((err = e1000_up(adapter))) if((err = e1000_up(adapter)))
goto err_up; goto err_up;
adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
if((adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
e1000_update_mng_vlan(adapter);
}
return E1000_SUCCESS; return E1000_SUCCESS;
...@@ -847,14 +929,18 @@ e1000_close(struct net_device *netdev) ...@@ -847,14 +929,18 @@ e1000_close(struct net_device *netdev)
e1000_free_tx_resources(adapter); e1000_free_tx_resources(adapter);
e1000_free_rx_resources(adapter); e1000_free_rx_resources(adapter);
if((adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
}
return 0; return 0;
} }
/** /**
* e1000_check_64k_bound - check that memory doesn't cross 64kB boundary * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
* @adapter: address of board private structure * @adapter: address of board private structure
* @begin: address of beginning of memory * @start: address of beginning of memory
* @end: address of end of memory * @len: length of memory
**/ **/
static inline boolean_t static inline boolean_t
e1000_check_64k_bound(struct e1000_adapter *adapter, e1000_check_64k_bound(struct e1000_adapter *adapter,
...@@ -1039,7 +1125,7 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter) ...@@ -1039,7 +1125,7 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter)
{ {
struct e1000_desc_ring *rxdr = &adapter->rx_ring; struct e1000_desc_ring *rxdr = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
int size; int size, desc_len;
size = sizeof(struct e1000_buffer) * rxdr->count; size = sizeof(struct e1000_buffer) * rxdr->count;
rxdr->buffer_info = vmalloc(size); rxdr->buffer_info = vmalloc(size);
...@@ -1050,9 +1136,35 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter) ...@@ -1050,9 +1136,35 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter)
} }
memset(rxdr->buffer_info, 0, size); memset(rxdr->buffer_info, 0, size);
size = sizeof(struct e1000_ps_page) * rxdr->count;
rxdr->ps_page = kmalloc(size, GFP_KERNEL);
if(!rxdr->ps_page) {
vfree(rxdr->buffer_info);
DPRINTK(PROBE, ERR,
"Unable to allocate memory for the receive descriptor ring\n");
return -ENOMEM;
}
memset(rxdr->ps_page, 0, size);
size = sizeof(struct e1000_ps_page_dma) * rxdr->count;
rxdr->ps_page_dma = kmalloc(size, GFP_KERNEL);
if(!rxdr->ps_page_dma) {
vfree(rxdr->buffer_info);
kfree(rxdr->ps_page);
DPRINTK(PROBE, ERR,
"Unable to allocate memory for the receive descriptor ring\n");
return -ENOMEM;
}
memset(rxdr->ps_page_dma, 0, size);
if(adapter->hw.mac_type <= e1000_82547_rev_2)
desc_len = sizeof(struct e1000_rx_desc);
else
desc_len = sizeof(union e1000_rx_desc_packet_split);
/* Round up to nearest 4K */ /* Round up to nearest 4K */
rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc); rxdr->size = rxdr->count * desc_len;
E1000_ROUNDUP(rxdr->size, 4096); E1000_ROUNDUP(rxdr->size, 4096);
rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
...@@ -1062,6 +1174,8 @@ setup_rx_desc_die: ...@@ -1062,6 +1174,8 @@ setup_rx_desc_die:
DPRINTK(PROBE, ERR, DPRINTK(PROBE, ERR,
"Unble to Allocate Memory for the Recieve descriptor ring\n"); "Unble to Allocate Memory for the Recieve descriptor ring\n");
vfree(rxdr->buffer_info); vfree(rxdr->buffer_info);
kfree(rxdr->ps_page);
kfree(rxdr->ps_page_dma);
return -ENOMEM; return -ENOMEM;
} }
...@@ -1089,6 +1203,8 @@ setup_rx_desc_die: ...@@ -1089,6 +1203,8 @@ setup_rx_desc_die:
"Unable to Allocate aligned Memory for the" "Unable to Allocate aligned Memory for the"
" Receive descriptor ring\n"); " Receive descriptor ring\n");
vfree(rxdr->buffer_info); vfree(rxdr->buffer_info);
kfree(rxdr->ps_page);
kfree(rxdr->ps_page_dma);
return -ENOMEM; return -ENOMEM;
} else { } else {
/* free old, move on with the new one since its okay */ /* free old, move on with the new one since its okay */
...@@ -1111,7 +1227,8 @@ setup_rx_desc_die: ...@@ -1111,7 +1227,8 @@ setup_rx_desc_die:
static void static void
e1000_setup_rctl(struct e1000_adapter *adapter) e1000_setup_rctl(struct e1000_adapter *adapter)
{ {
uint32_t rctl; uint32_t rctl, rfctl;
uint32_t psrctl = 0;
rctl = E1000_READ_REG(&adapter->hw, RCTL); rctl = E1000_READ_REG(&adapter->hw, RCTL);
...@@ -1126,24 +1243,69 @@ e1000_setup_rctl(struct e1000_adapter *adapter) ...@@ -1126,24 +1243,69 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
else else
rctl &= ~E1000_RCTL_SBP; rctl &= ~E1000_RCTL_SBP;
if (adapter->netdev->mtu <= ETH_DATA_LEN)
rctl &= ~E1000_RCTL_LPE;
else
rctl |= E1000_RCTL_LPE;
/* Setup buffer sizes */ /* Setup buffer sizes */
rctl &= ~(E1000_RCTL_SZ_4096); if(adapter->hw.mac_type == e1000_82573) {
rctl |= (E1000_RCTL_BSEX | E1000_RCTL_LPE); /* We can now specify buffers in 1K increments.
switch (adapter->rx_buffer_len) { * BSIZE and BSEX are ignored in this case. */
case E1000_RXBUFFER_2048: rctl |= adapter->rx_buffer_len << 0x11;
default: } else {
rctl |= E1000_RCTL_SZ_2048; rctl &= ~E1000_RCTL_SZ_4096;
rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE); rctl |= E1000_RCTL_BSEX;
break; switch (adapter->rx_buffer_len) {
case E1000_RXBUFFER_4096: case E1000_RXBUFFER_2048:
rctl |= E1000_RCTL_SZ_4096; default:
break; rctl |= E1000_RCTL_SZ_2048;
case E1000_RXBUFFER_8192: rctl &= ~E1000_RCTL_BSEX;
rctl |= E1000_RCTL_SZ_8192; break;
break; case E1000_RXBUFFER_4096:
case E1000_RXBUFFER_16384: rctl |= E1000_RCTL_SZ_4096;
rctl |= E1000_RCTL_SZ_16384; break;
break; case E1000_RXBUFFER_8192:
rctl |= E1000_RCTL_SZ_8192;
break;
case E1000_RXBUFFER_16384:
rctl |= E1000_RCTL_SZ_16384;
break;
}
}
#ifdef CONFIG_E1000_PACKET_SPLIT
/* 82571 and greater support packet-split where the protocol
* header is placed in skb->data and the packet data is
* placed in pages hanging off of skb_shinfo(skb)->nr_frags.
* In the case of a non-split, skb->data is linearly filled,
* followed by the page buffers. Therefore, skb->data is
* sized to hold the largest protocol header.
*/
adapter->rx_ps = (adapter->hw.mac_type > e1000_82547_rev_2)
&& (adapter->netdev->mtu
< ((3 * PAGE_SIZE) + adapter->rx_ps_bsize0));
#endif
if(adapter->rx_ps) {
/* Configure extra packet-split registers */
rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
rfctl |= E1000_RFCTL_EXTEN;
/* disable IPv6 packet split support */
rfctl |= E1000_RFCTL_IPV6_DIS;
E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl);
rctl |= E1000_RCTL_DTYP_PS | E1000_RCTL_SECRC;
psrctl |= adapter->rx_ps_bsize0 >>
E1000_PSRCTL_BSIZE0_SHIFT;
psrctl |= PAGE_SIZE >>
E1000_PSRCTL_BSIZE1_SHIFT;
psrctl |= PAGE_SIZE <<
E1000_PSRCTL_BSIZE2_SHIFT;
psrctl |= PAGE_SIZE <<
E1000_PSRCTL_BSIZE3_SHIFT;
E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
} }
E1000_WRITE_REG(&adapter->hw, RCTL, rctl); E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
...@@ -1160,9 +1322,18 @@ static void ...@@ -1160,9 +1322,18 @@ static void
e1000_configure_rx(struct e1000_adapter *adapter) e1000_configure_rx(struct e1000_adapter *adapter)
{ {
uint64_t rdba = adapter->rx_ring.dma; uint64_t rdba = adapter->rx_ring.dma;
uint32_t rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc); uint32_t rdlen, rctl, rxcsum;
uint32_t rctl;
uint32_t rxcsum; if(adapter->rx_ps) {
rdlen = adapter->rx_ring.count *
sizeof(union e1000_rx_desc_packet_split);
adapter->clean_rx = e1000_clean_rx_irq_ps;
adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
} else {
rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc);
adapter->clean_rx = e1000_clean_rx_irq;
adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
}
/* disable receives while setting up the descriptors */ /* disable receives while setting up the descriptors */
rctl = E1000_READ_REG(&adapter->hw, RCTL); rctl = E1000_READ_REG(&adapter->hw, RCTL);
...@@ -1189,13 +1360,27 @@ e1000_configure_rx(struct e1000_adapter *adapter) ...@@ -1189,13 +1360,27 @@ e1000_configure_rx(struct e1000_adapter *adapter)
E1000_WRITE_REG(&adapter->hw, RDT, 0); E1000_WRITE_REG(&adapter->hw, RDT, 0);
/* Enable 82543 Receive Checksum Offload for TCP and UDP */ /* Enable 82543 Receive Checksum Offload for TCP and UDP */
if((adapter->hw.mac_type >= e1000_82543) && if(adapter->hw.mac_type >= e1000_82543) {
(adapter->rx_csum == TRUE)) {
rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM); rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM);
rxcsum |= E1000_RXCSUM_TUOFL; if(adapter->rx_csum == TRUE) {
rxcsum |= E1000_RXCSUM_TUOFL;
/* Enable 82573 IPv4 payload checksum for UDP fragments
* Must be used in conjunction with packet-split. */
if((adapter->hw.mac_type > e1000_82547_rev_2) &&
(adapter->rx_ps)) {
rxcsum |= E1000_RXCSUM_IPPCSE;
}
} else {
rxcsum &= ~E1000_RXCSUM_TUOFL;
/* don't need to clear IPPCSE as it defaults to 0 */
}
E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum); E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum);
} }
if (adapter->hw.mac_type == e1000_82573)
E1000_WRITE_REG(&adapter->hw, ERT, 0x0100);
/* Enable Receives */ /* Enable Receives */
E1000_WRITE_REG(&adapter->hw, RCTL, rctl); E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
} }
...@@ -1298,6 +1483,10 @@ e1000_free_rx_resources(struct e1000_adapter *adapter) ...@@ -1298,6 +1483,10 @@ e1000_free_rx_resources(struct e1000_adapter *adapter)
vfree(rx_ring->buffer_info); vfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL; rx_ring->buffer_info = NULL;
kfree(rx_ring->ps_page);
rx_ring->ps_page = NULL;
kfree(rx_ring->ps_page_dma);
rx_ring->ps_page_dma = NULL;
pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma); pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
...@@ -1314,16 +1503,19 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter) ...@@ -1314,16 +1503,19 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter)
{ {
struct e1000_desc_ring *rx_ring = &adapter->rx_ring; struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct e1000_buffer *buffer_info; struct e1000_buffer *buffer_info;
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
unsigned long size; unsigned long size;
unsigned int i; unsigned int i, j;
/* Free all the Rx ring sk_buffs */ /* Free all the Rx ring sk_buffs */
for(i = 0; i < rx_ring->count; i++) { for(i = 0; i < rx_ring->count; i++) {
buffer_info = &rx_ring->buffer_info[i]; buffer_info = &rx_ring->buffer_info[i];
if(buffer_info->skb) { if(buffer_info->skb) {
ps_page = &rx_ring->ps_page[i];
ps_page_dma = &rx_ring->ps_page_dma[i];
pci_unmap_single(pdev, pci_unmap_single(pdev,
buffer_info->dma, buffer_info->dma,
buffer_info->length, buffer_info->length,
...@@ -1331,11 +1523,25 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter) ...@@ -1331,11 +1523,25 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter)
dev_kfree_skb(buffer_info->skb); dev_kfree_skb(buffer_info->skb);
buffer_info->skb = NULL; buffer_info->skb = NULL;
for(j = 0; j < PS_PAGE_BUFFERS; j++) {
if(!ps_page->ps_page[j]) break;
pci_unmap_single(pdev,
ps_page_dma->ps_page_dma[j],
PAGE_SIZE, PCI_DMA_FROMDEVICE);
ps_page_dma->ps_page_dma[j] = 0;
put_page(ps_page->ps_page[j]);
ps_page->ps_page[j] = NULL;
}
} }
} }
size = sizeof(struct e1000_buffer) * rx_ring->count; size = sizeof(struct e1000_buffer) * rx_ring->count;
memset(rx_ring->buffer_info, 0, size); memset(rx_ring->buffer_info, 0, size);
size = sizeof(struct e1000_ps_page) * rx_ring->count;
memset(rx_ring->ps_page, 0, size);
size = sizeof(struct e1000_ps_page_dma) * rx_ring->count;
memset(rx_ring->ps_page_dma, 0, size);
/* Zero out the descriptor ring */ /* Zero out the descriptor ring */
...@@ -1573,6 +1779,11 @@ e1000_watchdog_task(struct e1000_adapter *adapter) ...@@ -1573,6 +1779,11 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
uint32_t link; uint32_t link;
e1000_check_for_link(&adapter->hw); e1000_check_for_link(&adapter->hw);
if (adapter->hw.mac_type == e1000_82573) {
e1000_enable_tx_pkt_filtering(&adapter->hw);
if(adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)
e1000_update_mng_vlan(adapter);
}
if((adapter->hw.media_type == e1000_media_type_internal_serdes) && if((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
!(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE)) !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE))
...@@ -1659,6 +1870,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter) ...@@ -1659,6 +1870,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
#define E1000_TX_FLAGS_CSUM 0x00000001 #define E1000_TX_FLAGS_CSUM 0x00000001
#define E1000_TX_FLAGS_VLAN 0x00000002 #define E1000_TX_FLAGS_VLAN 0x00000002
#define E1000_TX_FLAGS_TSO 0x00000004 #define E1000_TX_FLAGS_TSO 0x00000004
#define E1000_TX_FLAGS_IPV4 0x00000008
#define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000
#define E1000_TX_FLAGS_VLAN_SHIFT 16 #define E1000_TX_FLAGS_VLAN_SHIFT 16
...@@ -1669,7 +1881,7 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb) ...@@ -1669,7 +1881,7 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
struct e1000_context_desc *context_desc; struct e1000_context_desc *context_desc;
unsigned int i; unsigned int i;
uint32_t cmd_length = 0; uint32_t cmd_length = 0;
uint16_t ipcse, tucse, mss; uint16_t ipcse = 0, tucse, mss;
uint8_t ipcss, ipcso, tucss, tucso, hdr_len; uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
int err; int err;
...@@ -1682,23 +1894,37 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb) ...@@ -1682,23 +1894,37 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
mss = skb_shinfo(skb)->tso_size; mss = skb_shinfo(skb)->tso_size;
skb->nh.iph->tot_len = 0; if(skb->protocol == ntohs(ETH_P_IP)) {
skb->nh.iph->check = 0; skb->nh.iph->tot_len = 0;
skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->check = 0;
skb->nh.iph->daddr, skb->h.th->check =
0, ~csum_tcpudp_magic(skb->nh.iph->saddr,
IPPROTO_TCP, skb->nh.iph->daddr,
0); 0,
IPPROTO_TCP,
0);
cmd_length = E1000_TXD_CMD_IP;
ipcse = skb->h.raw - skb->data - 1;
#ifdef NETIF_F_TSO_IPV6
} else if(skb->protocol == ntohs(ETH_P_IPV6)) {
skb->nh.ipv6h->payload_len = 0;
skb->h.th->check =
~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
&skb->nh.ipv6h->daddr,
0,
IPPROTO_TCP,
0);
ipcse = 0;
#endif
}
ipcss = skb->nh.raw - skb->data; ipcss = skb->nh.raw - skb->data;
ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data; ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data;
ipcse = skb->h.raw - skb->data - 1;
tucss = skb->h.raw - skb->data; tucss = skb->h.raw - skb->data;
tucso = (void *)&(skb->h.th->check) - (void *)skb->data; tucso = (void *)&(skb->h.th->check) - (void *)skb->data;
tucse = 0; tucse = 0;
cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP | E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
(skb->len - (hdr_len)));
i = adapter->tx_ring.next_to_use; i = adapter->tx_ring.next_to_use;
context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i); context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
...@@ -1866,7 +2092,10 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags) ...@@ -1866,7 +2092,10 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
if(likely(tx_flags & E1000_TX_FLAGS_TSO)) { if(likely(tx_flags & E1000_TX_FLAGS_TSO)) {
txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D | txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
E1000_TXD_CMD_TSE; E1000_TXD_CMD_TSE;
txd_upper |= (E1000_TXD_POPTS_IXSM | E1000_TXD_POPTS_TXSM) << 8; txd_upper |= E1000_TXD_POPTS_TXSM << 8;
if(likely(tx_flags & E1000_TX_FLAGS_IPV4))
txd_upper |= E1000_TXD_POPTS_IXSM << 8;
} }
if(likely(tx_flags & E1000_TX_FLAGS_CSUM)) { if(likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
...@@ -1941,6 +2170,53 @@ no_fifo_stall_required: ...@@ -1941,6 +2170,53 @@ no_fifo_stall_required:
return 0; return 0;
} }
#define MINIMUM_DHCP_PACKET_SIZE 282
static inline int
e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
{
struct e1000_hw *hw = &adapter->hw;
uint16_t length, offset;
if(vlan_tx_tag_present(skb)) {
if(!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
( adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
return 0;
}
if(htons(ETH_P_IP) == skb->protocol) {
const struct iphdr *ip = skb->nh.iph;
if(IPPROTO_UDP == ip->protocol) {
struct udphdr *udp = (struct udphdr *)(skb->h.uh);
if(ntohs(udp->dest) == 67) {
offset = (uint8_t *)udp + 8 - skb->data;
length = skb->len - offset;
return e1000_mng_write_dhcp_info(hw,
(uint8_t *)udp + 8, length);
}
}
} else if((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
struct ethhdr *eth = (struct ethhdr *) skb->data;
if((htons(ETH_P_IP) == eth->h_proto)) {
const struct iphdr *ip =
(struct iphdr *)((uint8_t *)skb->data+14);
if(IPPROTO_UDP == ip->protocol) {
struct udphdr *udp =
(struct udphdr *)((uint8_t *)ip +
(ip->ihl << 2));
if(ntohs(udp->dest) == 67) {
offset = (uint8_t *)udp + 8 - skb->data;
length = skb->len - offset;
return e1000_mng_write_dhcp_info(hw,
(uint8_t *)udp + 8,
length);
}
}
}
}
return 0;
}
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 ) #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
static int static int
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
...@@ -2008,6 +2284,9 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -2008,6 +2284,9 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
local_irq_restore(flags); local_irq_restore(flags);
return NETDEV_TX_LOCKED; return NETDEV_TX_LOCKED;
} }
if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
e1000_transfer_dhcp_info(adapter, skb);
/* need: count + 2 desc gap to keep tail from touching /* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */ * head, otherwise try next time */
...@@ -2044,6 +2323,12 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -2044,6 +2323,12 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
else if(likely(e1000_tx_csum(adapter, skb))) else if(likely(e1000_tx_csum(adapter, skb)))
tx_flags |= E1000_TX_FLAGS_CSUM; tx_flags |= E1000_TX_FLAGS_CSUM;
/* Old method was to assume IPv4 packet by default if TSO was enabled.
* 82573 hardware supports TSO capabilities for IPv6 as well...
* no longer assume, we must. */
if(likely(skb->protocol == ntohs(ETH_P_IP)))
tx_flags |= E1000_TX_FLAGS_IPV4;
e1000_tx_queue(adapter, e1000_tx_queue(adapter,
e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss), e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss),
tx_flags); tx_flags);
...@@ -2110,7 +2395,6 @@ static int ...@@ -2110,7 +2395,6 @@ static int
e1000_change_mtu(struct net_device *netdev, int new_mtu) e1000_change_mtu(struct net_device *netdev, int new_mtu)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
int old_mtu = adapter->rx_buffer_len;
int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
...@@ -2119,29 +2403,45 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -2119,29 +2403,45 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL; return -EINVAL;
} }
if(max_frame <= MAXIMUM_ETHERNET_FRAME_SIZE) { #define MAX_STD_JUMBO_FRAME_SIZE 9216
adapter->rx_buffer_len = E1000_RXBUFFER_2048; /* might want this to be bigger enum check... */
if (adapter->hw.mac_type == e1000_82573 &&
} else if(adapter->hw.mac_type < e1000_82543) { max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
DPRINTK(PROBE, ERR, "Jumbo Frames not supported on 82542\n"); DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
"on 82573\n");
return -EINVAL; return -EINVAL;
}
} else if(max_frame <= E1000_RXBUFFER_4096) { if(adapter->hw.mac_type > e1000_82547_rev_2) {
adapter->rx_buffer_len = E1000_RXBUFFER_4096; adapter->rx_buffer_len = max_frame;
E1000_ROUNDUP(adapter->rx_buffer_len, 1024);
} else if(max_frame <= E1000_RXBUFFER_8192) {
adapter->rx_buffer_len = E1000_RXBUFFER_8192;
} else { } else {
adapter->rx_buffer_len = E1000_RXBUFFER_16384; if(unlikely((adapter->hw.mac_type < e1000_82543) &&
(max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) {
DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
"on 82542\n");
return -EINVAL;
} else {
if(max_frame <= E1000_RXBUFFER_2048) {
adapter->rx_buffer_len = E1000_RXBUFFER_2048;
} else if(max_frame <= E1000_RXBUFFER_4096) {
adapter->rx_buffer_len = E1000_RXBUFFER_4096;
} else if(max_frame <= E1000_RXBUFFER_8192) {
adapter->rx_buffer_len = E1000_RXBUFFER_8192;
} else if(max_frame <= E1000_RXBUFFER_16384) {
adapter->rx_buffer_len = E1000_RXBUFFER_16384;
}
}
} }
if(old_mtu != adapter->rx_buffer_len && netif_running(netdev)) { netdev->mtu = new_mtu;
if(netif_running(netdev)) {
e1000_down(adapter); e1000_down(adapter);
e1000_up(adapter); e1000_up(adapter);
} }
netdev->mtu = new_mtu;
adapter->hw.max_frame_size = max_frame; adapter->hw.max_frame_size = max_frame;
return 0; return 0;
...@@ -2232,6 +2532,17 @@ e1000_update_stats(struct e1000_adapter *adapter) ...@@ -2232,6 +2532,17 @@ e1000_update_stats(struct e1000_adapter *adapter)
adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC); adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC);
adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC); adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC);
} }
if(hw->mac_type > e1000_82547_rev_2) {
adapter->stats.iac += E1000_READ_REG(hw, IAC);
adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC);
adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC);
adapter->stats.icrxatc += E1000_READ_REG(hw, ICRXATC);
adapter->stats.ictxptc += E1000_READ_REG(hw, ICTXPTC);
adapter->stats.ictxatc += E1000_READ_REG(hw, ICTXATC);
adapter->stats.ictxqec += E1000_READ_REG(hw, ICTXQEC);
adapter->stats.ictxqmtc += E1000_READ_REG(hw, ICTXQMTC);
adapter->stats.icrxdmtc += E1000_READ_REG(hw, ICRXDMTC);
}
/* Fill out the OS statistics structure */ /* Fill out the OS statistics structure */
...@@ -2337,7 +2648,7 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) ...@@ -2337,7 +2648,7 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
} }
for(i = 0; i < E1000_MAX_INTR; i++) for(i = 0; i < E1000_MAX_INTR; i++)
if(unlikely(!e1000_clean_rx_irq(adapter) & if(unlikely(!adapter->clean_rx(adapter) &
!e1000_clean_tx_irq(adapter))) !e1000_clean_tx_irq(adapter)))
break; break;
...@@ -2363,7 +2674,7 @@ e1000_clean(struct net_device *netdev, int *budget) ...@@ -2363,7 +2674,7 @@ e1000_clean(struct net_device *netdev, int *budget)
int work_done = 0; int work_done = 0;
tx_cleaned = e1000_clean_tx_irq(adapter); tx_cleaned = e1000_clean_tx_irq(adapter);
e1000_clean_rx_irq(adapter, &work_done, work_to_do); adapter->clean_rx(adapter, &work_done, work_to_do);
*budget -= work_done; *budget -= work_done;
netdev->quota -= work_done; netdev->quota -= work_done;
...@@ -2501,41 +2812,57 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) ...@@ -2501,41 +2812,57 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
/** /**
* e1000_rx_checksum - Receive Checksum Offload for 82543 * e1000_rx_checksum - Receive Checksum Offload for 82543
* @adapter: board private structure * @adapter: board private structure
* @rx_desc: receive descriptor * @status_err: receive descriptor status and error fields
* @sk_buff: socket buffer with received data * @csum: receive descriptor csum field
* @sk_buff: socket buffer with received data
**/ **/
static inline void static inline void
e1000_rx_checksum(struct e1000_adapter *adapter, e1000_rx_checksum(struct e1000_adapter *adapter,
struct e1000_rx_desc *rx_desc, uint32_t status_err, uint32_t csum,
struct sk_buff *skb) struct sk_buff *skb)
{ {
uint16_t status = (uint16_t)status_err;
uint8_t errors = (uint8_t)(status_err >> 24);
skb->ip_summed = CHECKSUM_NONE;
/* 82543 or newer only */ /* 82543 or newer only */
if(unlikely((adapter->hw.mac_type < e1000_82543) || if(unlikely(adapter->hw.mac_type < e1000_82543)) return;
/* Ignore Checksum bit is set */ /* Ignore Checksum bit is set */
(rx_desc->status & E1000_RXD_STAT_IXSM) || if(unlikely(status & E1000_RXD_STAT_IXSM)) return;
/* TCP Checksum has not been calculated */ /* TCP/UDP checksum error bit is set */
(!(rx_desc->status & E1000_RXD_STAT_TCPCS)))) { if(unlikely(errors & E1000_RXD_ERR_TCPE)) {
skb->ip_summed = CHECKSUM_NONE;
return;
}
/* At this point we know the hardware did the TCP checksum */
/* now look at the TCP checksum error bit */
if(rx_desc->errors & E1000_RXD_ERR_TCPE) {
/* let the stack verify checksum errors */ /* let the stack verify checksum errors */
skb->ip_summed = CHECKSUM_NONE;
adapter->hw_csum_err++; adapter->hw_csum_err++;
return;
}
/* TCP/UDP Checksum has not been calculated */
if(adapter->hw.mac_type <= e1000_82547_rev_2) {
if(!(status & E1000_RXD_STAT_TCPCS))
return;
} else { } else {
if(!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
return;
}
/* It must be a TCP or UDP packet with a valid checksum */
if (likely(status & E1000_RXD_STAT_TCPCS)) {
/* TCP checksum is good */ /* TCP checksum is good */
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
adapter->hw_csum_good++; } else if (adapter->hw.mac_type > e1000_82547_rev_2) {
/* IP fragment with UDP payload */
/* Hardware complements the payload checksum, so we undo it
* and then put the value in host order for further stack use.
*/
csum = ntohl(csum ^ 0xFFFF);
skb->csum = csum;
skb->ip_summed = CHECKSUM_HW;
} }
adapter->hw_csum_good++;
} }
/** /**
* e1000_clean_rx_irq - Send received data up the network stack * e1000_clean_rx_irq - Send received data up the network stack; legacy
* @adapter: board private structure * @adapter: board private structure
**/ **/
...@@ -2608,15 +2935,17 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter) ...@@ -2608,15 +2935,17 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
skb_put(skb, length - ETHERNET_FCS_SIZE); skb_put(skb, length - ETHERNET_FCS_SIZE);
/* Receive Checksum Offload */ /* Receive Checksum Offload */
e1000_rx_checksum(adapter, rx_desc, skb); e1000_rx_checksum(adapter,
(uint32_t)(rx_desc->status) |
((uint32_t)(rx_desc->errors) << 24),
rx_desc->csum, skb);
skb->protocol = eth_type_trans(skb, netdev); skb->protocol = eth_type_trans(skb, netdev);
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
if(unlikely(adapter->vlgrp && if(unlikely(adapter->vlgrp &&
(rx_desc->status & E1000_RXD_STAT_VP))) { (rx_desc->status & E1000_RXD_STAT_VP))) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
le16_to_cpu(rx_desc->special) & le16_to_cpu(rx_desc->special) &
E1000_RXD_SPC_VLAN_MASK); E1000_RXD_SPC_VLAN_MASK);
} else { } else {
netif_receive_skb(skb); netif_receive_skb(skb);
} }
...@@ -2639,16 +2968,142 @@ next_desc: ...@@ -2639,16 +2968,142 @@ next_desc:
rx_desc = E1000_RX_DESC(*rx_ring, i); rx_desc = E1000_RX_DESC(*rx_ring, i);
} }
rx_ring->next_to_clean = i; rx_ring->next_to_clean = i;
adapter->alloc_rx_buf(adapter);
return cleaned;
}
/**
* e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
* @adapter: board private structure
**/
static boolean_t
#ifdef CONFIG_E1000_NAPI
e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, int *work_done,
int work_to_do)
#else
e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
#endif
{
struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
union e1000_rx_desc_packet_split *rx_desc;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
struct e1000_buffer *buffer_info;
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
struct sk_buff *skb;
unsigned int i, j;
uint32_t length, staterr;
boolean_t cleaned = FALSE;
i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
staterr = rx_desc->wb.middle.status_error;
while(staterr & E1000_RXD_STAT_DD) {
buffer_info = &rx_ring->buffer_info[i];
ps_page = &rx_ring->ps_page[i];
ps_page_dma = &rx_ring->ps_page_dma[i];
#ifdef CONFIG_E1000_NAPI
if(unlikely(*work_done >= work_to_do))
break;
(*work_done)++;
#endif
cleaned = TRUE;
pci_unmap_single(pdev, buffer_info->dma,
buffer_info->length,
PCI_DMA_FROMDEVICE);
skb = buffer_info->skb;
if(unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
E1000_DBG("%s: Packet Split buffers didn't pick up"
" the full packet\n", netdev->name);
dev_kfree_skb_irq(skb);
goto next_desc;
}
e1000_alloc_rx_buffers(adapter); if(unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
dev_kfree_skb_irq(skb);
goto next_desc;
}
length = le16_to_cpu(rx_desc->wb.middle.length0);
if(unlikely(!length)) {
E1000_DBG("%s: Last part of the packet spanning"
" multiple descriptors\n", netdev->name);
dev_kfree_skb_irq(skb);
goto next_desc;
}
/* Good Receive */
skb_put(skb, length);
for(j = 0; j < PS_PAGE_BUFFERS; j++) {
if(!(length = le16_to_cpu(rx_desc->wb.upper.length[j])))
break;
pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
PAGE_SIZE, PCI_DMA_FROMDEVICE);
ps_page_dma->ps_page_dma[j] = 0;
skb_shinfo(skb)->frags[j].page =
ps_page->ps_page[j];
ps_page->ps_page[j] = NULL;
skb_shinfo(skb)->frags[j].page_offset = 0;
skb_shinfo(skb)->frags[j].size = length;
skb_shinfo(skb)->nr_frags++;
skb->len += length;
skb->data_len += length;
}
e1000_rx_checksum(adapter, staterr,
rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
skb->protocol = eth_type_trans(skb, netdev);
#ifdef HAVE_RX_ZERO_COPY
if(likely(rx_desc->wb.upper.header_status &
E1000_RXDPS_HDRSTAT_HDRSP))
skb_shinfo(skb)->zero_copy = TRUE;
#endif
#ifdef CONFIG_E1000_NAPI
if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
le16_to_cpu(rx_desc->wb.middle.vlan &
E1000_RXD_SPC_VLAN_MASK));
} else {
netif_receive_skb(skb);
}
#else /* CONFIG_E1000_NAPI */
if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
vlan_hwaccel_rx(skb, adapter->vlgrp,
le16_to_cpu(rx_desc->wb.middle.vlan &
E1000_RXD_SPC_VLAN_MASK));
} else {
netif_rx(skb);
}
#endif /* CONFIG_E1000_NAPI */
netdev->last_rx = jiffies;
next_desc:
rx_desc->wb.middle.status_error &= ~0xFF;
buffer_info->skb = NULL;
if(unlikely(++i == rx_ring->count)) i = 0;
rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
staterr = rx_desc->wb.middle.status_error;
}
rx_ring->next_to_clean = i;
adapter->alloc_rx_buf(adapter);
return cleaned; return cleaned;
} }
/** /**
* e1000_alloc_rx_buffers - Replace used receive buffers * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
* @adapter: address of board private structure * @adapter: address of board private structure
**/ **/
...@@ -2752,6 +3207,95 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter) ...@@ -2752,6 +3207,95 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
rx_ring->next_to_use = i; rx_ring->next_to_use = i;
} }
/**
* e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
* @adapter: address of board private structure
**/
static void
e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
{
struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union e1000_rx_desc_packet_split *rx_desc;
struct e1000_buffer *buffer_info;
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
struct sk_buff *skb;
unsigned int i, j;
i = rx_ring->next_to_use;
buffer_info = &rx_ring->buffer_info[i];
ps_page = &rx_ring->ps_page[i];
ps_page_dma = &rx_ring->ps_page_dma[i];
while(!buffer_info->skb) {
rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
for(j = 0; j < PS_PAGE_BUFFERS; j++) {
if(unlikely(!ps_page->ps_page[j])) {
ps_page->ps_page[j] =
alloc_page(GFP_ATOMIC);
if(unlikely(!ps_page->ps_page[j]))
goto no_buffers;
ps_page_dma->ps_page_dma[j] =
pci_map_page(pdev,
ps_page->ps_page[j],
0, PAGE_SIZE,
PCI_DMA_FROMDEVICE);
}
/* Refresh the desc even if buffer_addrs didn't
* change because each write-back erases this info.
*/
rx_desc->read.buffer_addr[j+1] =
cpu_to_le64(ps_page_dma->ps_page_dma[j]);
}
skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
if(unlikely(!skb))
break;
/* Make buffer alignment 2 beyond a 16 byte boundary
* this will result in a 16 byte aligned IP header after
* the 14 byte MAC header is removed
*/
skb_reserve(skb, NET_IP_ALIGN);
skb->dev = netdev;
buffer_info->skb = skb;
buffer_info->length = adapter->rx_ps_bsize0;
buffer_info->dma = pci_map_single(pdev, skb->data,
adapter->rx_ps_bsize0,
PCI_DMA_FROMDEVICE);
rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
if(unlikely((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i)) {
/* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only
* applicable for weak-ordered memory model archs,
* such as IA-64). */
wmb();
/* Hardware increments by 16 bytes, but packet split
* descriptors are 32 bytes...so we increment tail
* twice as much.
*/
E1000_WRITE_REG(&adapter->hw, RDT, i<<1);
}
if(unlikely(++i == rx_ring->count)) i = 0;
buffer_info = &rx_ring->buffer_info[i];
ps_page = &rx_ring->ps_page[i];
ps_page_dma = &rx_ring->ps_page_dma[i];
}
no_buffers:
rx_ring->next_to_use = i;
}
/** /**
* e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers. * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
* @adapter: * @adapter:
...@@ -2986,6 +3530,7 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) ...@@ -2986,6 +3530,7 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
rctl |= E1000_RCTL_VFE; rctl |= E1000_RCTL_VFE;
rctl &= ~E1000_RCTL_CFIEN; rctl &= ~E1000_RCTL_CFIEN;
E1000_WRITE_REG(&adapter->hw, RCTL, rctl); E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
e1000_update_mng_vlan(adapter);
} else { } else {
/* disable VLAN tag insert/strip */ /* disable VLAN tag insert/strip */
ctrl = E1000_READ_REG(&adapter->hw, CTRL); ctrl = E1000_READ_REG(&adapter->hw, CTRL);
...@@ -2996,6 +3541,10 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) ...@@ -2996,6 +3541,10 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
rctl = E1000_READ_REG(&adapter->hw, RCTL); rctl = E1000_READ_REG(&adapter->hw, RCTL);
rctl &= ~E1000_RCTL_VFE; rctl &= ~E1000_RCTL_VFE;
E1000_WRITE_REG(&adapter->hw, RCTL, rctl); E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
if(adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) {
e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
}
} }
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
...@@ -3006,7 +3555,10 @@ e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) ...@@ -3006,7 +3555,10 @@ e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
uint32_t vfta, index; uint32_t vfta, index;
if((adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
(vid == adapter->mng_vlan_id))
return;
/* add VID to filter table */ /* add VID to filter table */
index = (vid >> 5) & 0x7F; index = (vid >> 5) & 0x7F;
vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index); vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
...@@ -3027,6 +3579,10 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) ...@@ -3027,6 +3579,10 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
if((adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
(vid == adapter->mng_vlan_id))
return;
/* remove VID from filter table */ /* remove VID from filter table */
index = (vid >> 5) & 0x7F; index = (vid >> 5) & 0x7F;
vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index); vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
...@@ -3102,7 +3658,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) ...@@ -3102,7 +3658,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
uint32_t ctrl, ctrl_ext, rctl, manc, status; uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm;
uint32_t wufc = adapter->wol; uint32_t wufc = adapter->wol;
netif_device_detach(netdev); netif_device_detach(netdev);
...@@ -3144,6 +3700,9 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) ...@@ -3144,6 +3700,9 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext); E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);
} }
/* Allow time for pending master requests to run */
e1000_disable_pciex_master(&adapter->hw);
E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN); E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
E1000_WRITE_REG(&adapter->hw, WUFC, wufc); E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
pci_enable_wake(pdev, 3, 1); pci_enable_wake(pdev, 3, 1);
...@@ -3168,6 +3727,16 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) ...@@ -3168,6 +3727,16 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
} }
} }
switch(adapter->hw.mac_type) {
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm & ~E1000_SWSM_DRV_LOAD);
break;
default:
break;
}
pci_disable_device(pdev); pci_disable_device(pdev);
state = (state > 0) ? 3 : 0; state = (state > 0) ? 3 : 0;
...@@ -3182,7 +3751,7 @@ e1000_resume(struct pci_dev *pdev) ...@@ -3182,7 +3751,7 @@ e1000_resume(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
uint32_t manc, ret; uint32_t manc, ret, swsm;
pci_set_power_state(pdev, 0); pci_set_power_state(pdev, 0);
pci_restore_state(pdev); pci_restore_state(pdev);
...@@ -3207,10 +3776,19 @@ e1000_resume(struct pci_dev *pdev) ...@@ -3207,10 +3776,19 @@ e1000_resume(struct pci_dev *pdev)
E1000_WRITE_REG(&adapter->hw, MANC, manc); E1000_WRITE_REG(&adapter->hw, MANC, manc);
} }
switch(adapter->hw.mac_type) {
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm | E1000_SWSM_DRV_LOAD);
break;
default:
break;
}
return 0; return 0;
} }
#endif #endif
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
/* /*
* Polling 'interrupt' - used by things like netconsole to send skbs * Polling 'interrupt' - used by things like netconsole to send skbs
......
...@@ -101,6 +101,29 @@ typedef enum { ...@@ -101,6 +101,29 @@ typedef enum {
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
((offset) << 2))) ((offset) << 2)))
#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) ( \
writew((value), ((a)->hw_addr + \
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
((offset) << 1))))
#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \
readw((a)->hw_addr + \
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
((offset) << 1)))
#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \
writeb((value), ((a)->hw_addr + \
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
(offset))))
#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \
readb((a)->hw_addr + \
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
(offset)))
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS) #define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
#endif /* _E1000_OSDEP_H_ */ #endif /* _E1000_OSDEP_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment