Commit 908a658e authored by Jeb J. Cramer's avatar Jeb J. Cramer Committed by Jeff Garzik

[E1000] Added 82541 & 82547 support

* Added support for 82541 and 82547 gigabit ethernet adapters
parent 5f3529cc
...@@ -1904,6 +1904,7 @@ config E1000 ...@@ -1904,6 +1904,7 @@ config E1000
82544 PRO/1000 XF Server Adapter A50484-xxx 82544 PRO/1000 XF Server Adapter A50484-xxx
82544 PRO/1000 T Desktop Adapter A62947-xxx 82544 PRO/1000 T Desktop Adapter A62947-xxx
82540 PRO/1000 MT Desktop Adapter A78408-xxx 82540 PRO/1000 MT Desktop Adapter A78408-xxx
82541 PRO/1000 MT Desktop Adapter C91016-xxx
82545 PRO/1000 MT Server Adapter A92165-xxx 82545 PRO/1000 MT Server Adapter A92165-xxx
82546 PRO/1000 MT Dual Port Server Adapter A92111-xxx 82546 PRO/1000 MT Dual Port Server Adapter A92111-xxx
82545 PRO/1000 MF Server Adapter A91622-xxx 82545 PRO/1000 MF Server Adapter A91622-xxx
......
...@@ -95,6 +95,15 @@ struct e1000_adapter; ...@@ -95,6 +95,15 @@ struct e1000_adapter;
#define E1000_RXBUFFER_8192 8192 #define E1000_RXBUFFER_8192 8192
#define E1000_RXBUFFER_16384 16384 #define E1000_RXBUFFER_16384 16384
/* SmartSpeed delimiters */
#define E1000_SMARTSPEED_DOWNSHIFT 3
#define E1000_SMARTSPEED_MAX 15
/* Packet Buffer allocations */
#define E1000_TX_FIFO_SIZE_SHIFT 0xA
#define E1000_TX_HEAD_ADDR_SHIFT 7
#define E1000_PBA_TX_MASK 0xFFFF0000
/* Flow Control High-Watermark: 43464 bytes */ /* Flow Control High-Watermark: 43464 bytes */
#define E1000_FC_HIGH_THRESH 0xA9C8 #define E1000_FC_HIGH_THRESH 0xA9C8
...@@ -109,9 +118,6 @@ struct e1000_adapter; ...@@ -109,9 +118,6 @@ struct e1000_adapter;
/* How many Rx Buffers do we bundle into one write to the hardware ? */ /* How many Rx Buffers do we bundle into one write to the hardware ? */
#define E1000_RX_BUFFER_WRITE 16 #define E1000_RX_BUFFER_WRITE 16
#define E1000_JUMBO_PBA 0x00000028
#define E1000_DEFAULT_PBA 0x00000030
#define AUTO_ALL_MODES 0 #define AUTO_ALL_MODES 0
#define E1000_EEPROM_APME 4 #define E1000_EEPROM_APME 4
...@@ -155,6 +161,7 @@ struct e1000_desc_ring { ...@@ -155,6 +161,7 @@ struct e1000_desc_ring {
/* board specific private data structure */ /* board specific private data structure */
struct e1000_adapter { struct e1000_adapter {
struct timer_list tx_fifo_stall_timer;
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;
...@@ -163,6 +170,7 @@ struct e1000_adapter { ...@@ -163,6 +170,7 @@ struct e1000_adapter {
uint32_t rx_buffer_len; uint32_t rx_buffer_len;
uint32_t part_num; uint32_t part_num;
uint32_t wol; uint32_t wol;
uint32_t smartspeed;
uint16_t link_speed; uint16_t link_speed;
uint16_t link_duplex; uint16_t link_duplex;
spinlock_t stats_lock; spinlock_t stats_lock;
...@@ -178,6 +186,10 @@ struct e1000_adapter { ...@@ -178,6 +186,10 @@ struct e1000_adapter {
uint32_t tx_int_delay; uint32_t tx_int_delay;
uint32_t tx_abs_int_delay; uint32_t tx_abs_int_delay;
int max_data_per_txd; int max_data_per_txd;
uint32_t tx_fifo_head;
uint32_t tx_head_addr;
uint32_t tx_fifo_size;
atomic_t tx_fifo_stall;
/* RX */ /* RX */
struct e1000_desc_ring rx_ring; struct e1000_desc_ring rx_ring;
......
...@@ -145,16 +145,6 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd) ...@@ -145,16 +145,6 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
return 0; return 0;
} }
static inline int
e1000_eeprom_size(struct e1000_hw *hw)
{
if((hw->mac_type > e1000_82544) &&
(E1000_READ_REG(hw, EECD) & E1000_EECD_SIZE))
return 512;
else
return 128;
}
static void static void
e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter, e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
struct ethtool_drvinfo *drvinfo) struct ethtool_drvinfo *drvinfo)
...@@ -166,7 +156,7 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter, ...@@ -166,7 +156,7 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
drvinfo->n_stats = E1000_STATS_LEN; drvinfo->n_stats = E1000_STATS_LEN;
#define E1000_REGS_LEN 32 #define E1000_REGS_LEN 32
drvinfo->regdump_len = E1000_REGS_LEN * sizeof(uint32_t); drvinfo->regdump_len = E1000_REGS_LEN * sizeof(uint32_t);
drvinfo->eedump_len = e1000_eeprom_size(&adapter->hw); drvinfo->eedump_len = adapter->hw.eeprom.word_size * 2;
} }
static void static void
...@@ -200,9 +190,8 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter, ...@@ -200,9 +190,8 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff) struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
int max_len, first_word, last_word; int first_word, last_word;
int ret_val = 0; int ret_val = 0;
int i;
if(eeprom->len == 0) { if(eeprom->len == 0) {
ret_val = -EINVAL; ret_val = -EINVAL;
...@@ -211,22 +200,28 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter, ...@@ -211,22 +200,28 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
eeprom->magic = hw->vendor_id | (hw->device_id << 16); eeprom->magic = hw->vendor_id | (hw->device_id << 16);
max_len = e1000_eeprom_size(hw);
if(eeprom->offset > eeprom->offset + eeprom->len) { if(eeprom->offset > eeprom->offset + eeprom->len) {
ret_val = -EINVAL; ret_val = -EINVAL;
goto geeprom_error; goto geeprom_error;
} }
if((eeprom->offset + eeprom->len) > max_len) if((eeprom->offset + eeprom->len) > (hw->eeprom.word_size * 2))
eeprom->len = (max_len - eeprom->offset); eeprom->len = ((hw->eeprom.word_size * 2) - eeprom->offset);
first_word = eeprom->offset >> 1; first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1;
for(i = 0; i <= (last_word - first_word); i++) if(hw->eeprom.type == e1000_eeprom_spi)
e1000_read_eeprom(hw, first_word + i, &eeprom_buff[i]); ret_val = e1000_read_eeprom(hw, first_word,
last_word - first_word + 1,
eeprom_buff);
else {
uint16_t i;
for (i = 0; i < last_word - first_word + 1; i++)
if((ret_val = e1000_read_eeprom(hw, first_word + i, 1,
&eeprom_buff[i])))
break;
}
geeprom_error: geeprom_error:
return ret_val; return ret_val;
} }
...@@ -237,9 +232,8 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter, ...@@ -237,9 +232,8 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff; uint16_t *eeprom_buff;
int max_len, first_word, last_word;
void *ptr; void *ptr;
int i; int max_len, first_word, last_word, ret_val = 0;
if(eeprom->len == 0) if(eeprom->len == 0)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -247,7 +241,7 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter, ...@@ -247,7 +241,7 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT; return -EFAULT;
max_len = e1000_eeprom_size(hw); max_len = hw->eeprom.word_size * 2;
if((eeprom->offset + eeprom->len) > max_len) if((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset); eeprom->len = (max_len - eeprom->offset);
...@@ -263,30 +257,31 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter, ...@@ -263,30 +257,31 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if(eeprom->offset & 1) { if(eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */ /* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */ /* only the second byte of the word is being modified */
e1000_read_eeprom(hw, first_word, &eeprom_buff[0]); ret_val = e1000_read_eeprom(hw, first_word, 1,
&eeprom_buff[0]);
ptr++; ptr++;
} }
if((eeprom->offset + eeprom->len) & 1) { if(((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
/* need read/modify/write of last changed EEPROM word */ /* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */ /* only the first byte of the word is being modified */
e1000_read_eeprom(hw, last_word, ret_val = e1000_read_eeprom(hw, last_word, 1,
&eeprom_buff[last_word - first_word]); &eeprom_buff[last_word - first_word]);
} }
if(copy_from_user(ptr, user_data, eeprom->len)) { if((ret_val != 0) || copy_from_user(ptr, user_data, eeprom->len)) {
kfree(eeprom_buff); ret_val = -EFAULT;
return -EFAULT; goto seeprom_error;
} }
for(i = 0; i <= (last_word - first_word); i++) ret_val = e1000_write_eeprom(hw, first_word,
e1000_write_eeprom(hw, first_word + i, eeprom_buff[i]); last_word - first_word + 1, eeprom_buff);
/* Update the checksum over the first part of the EEPROM if needed */ /* Update the checksum over the first part of the EEPROM if needed */
if(first_word <= EEPROM_CHECKSUM_REG) if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
e1000_update_eeprom_checksum(hw); e1000_update_eeprom_checksum(hw);
seeprom_error:
kfree(eeprom_buff); kfree(eeprom_buff);
return ret_val;
return 0;
} }
static void static void
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "e1000_hw.h" #include "e1000_hw.h"
static int32_t e1000_set_phy_type(struct e1000_hw *hw);
static void e1000_phy_init_script(struct e1000_hw *hw);
static int32_t e1000_setup_fiber_link(struct e1000_hw *hw); static int32_t e1000_setup_fiber_link(struct e1000_hw *hw);
static int32_t e1000_setup_copper_link(struct e1000_hw *hw); static int32_t e1000_setup_copper_link(struct e1000_hw *hw);
static int32_t e1000_phy_force_speed_duplex(struct e1000_hw *hw); static int32_t e1000_phy_force_speed_duplex(struct e1000_hw *hw);
...@@ -42,19 +44,103 @@ static void e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl); ...@@ -42,19 +44,103 @@ static void e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);
static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count); static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count);
static uint16_t e1000_shift_in_mdi_bits(struct e1000_hw *hw); static uint16_t e1000_shift_in_mdi_bits(struct e1000_hw *hw);
static int32_t e1000_phy_reset_dsp(struct e1000_hw *hw); static int32_t e1000_phy_reset_dsp(struct e1000_hw *hw);
static int32_t e1000_write_eeprom_spi(struct e1000_hw *hw, uint16_t offset,
uint16_t words, uint16_t *data);
static int32_t e1000_write_eeprom_microwire(struct e1000_hw *hw,
uint16_t offset, uint16_t words,
uint16_t *data);
static int32_t e1000_spi_eeprom_ready(struct e1000_hw *hw);
static void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd); static void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
static void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd); static void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count); static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count);
static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw); static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count);
static void e1000_setup_eeprom(struct e1000_hw *hw); static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
static void e1000_clock_eeprom(struct e1000_hw *hw); static void e1000_release_eeprom(struct e1000_hw *hw);
static void e1000_cleanup_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_id_led_init(struct e1000_hw * hw);
/******************************************************************************
* Set the phy type member in the hw struct.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
int32_t
e1000_set_phy_type(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_set_phy_type");
switch(hw->phy_id) {
case M88E1000_E_PHY_ID:
case M88E1000_I_PHY_ID:
case M88E1011_I_PHY_ID:
hw->phy_type = e1000_phy_m88;
break;
case IGP01E1000_I_PHY_ID:
hw->phy_type = e1000_phy_igp;
break;
default:
/* Should never have loaded on this device */
hw->phy_type = e1000_phy_undefined;
return -E1000_ERR_PHY_TYPE;
}
return E1000_SUCCESS;
}
/******************************************************************************
* IGP phy init script - initializes the GbE PHY
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
e1000_phy_init_script(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_phy_init_script");
if(hw->phy_init_script) {
msec_delay(10);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
e1000_write_phy_reg(hw,0x0000,0x0140);
msec_delay(5);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F95);
e1000_write_phy_reg(hw,0x0015,0x0001);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F71);
e1000_write_phy_reg(hw,0x0011,0xBD21);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F79);
e1000_write_phy_reg(hw,0x0019,0x0018);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F30);
e1000_write_phy_reg(hw,0x0010,0x1600);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F31);
e1000_write_phy_reg(hw,0x0011,0x0014);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F32);
e1000_write_phy_reg(hw,0x0012,0x161C);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F94);
e1000_write_phy_reg(hw,0x0014,0x0003);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F96);
e1000_write_phy_reg(hw,0x0016,0x003F);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x2010);
e1000_write_phy_reg(hw,0x0010,0x0008);
e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
e1000_write_phy_reg(hw,0x0000,0x3300);
}
}
/****************************************************************************** /******************************************************************************
* Set the mac type member in the hw struct. * Set the mac type member in the hw struct.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
int32_t int32_t
...@@ -101,10 +187,19 @@ e1000_set_mac_type(struct e1000_hw *hw) ...@@ -101,10 +187,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82546EB_FIBER: case E1000_DEV_ID_82546EB_FIBER:
hw->mac_type = e1000_82546; hw->mac_type = e1000_82546;
break; break;
case E1000_DEV_ID_82541EI:
case E1000_DEV_ID_82541EP:
hw->mac_type = e1000_82541;
break;
case E1000_DEV_ID_82547EI:
hw->mac_type = e1000_82547;
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;
} }
return E1000_SUCCESS; return E1000_SUCCESS;
} }
/****************************************************************************** /******************************************************************************
...@@ -119,9 +214,10 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -119,9 +214,10 @@ e1000_reset_hw(struct e1000_hw *hw)
uint32_t ctrl_ext; uint32_t ctrl_ext;
uint32_t icr; uint32_t icr;
uint32_t manc; uint32_t manc;
uint32_t led_ctrl;
DEBUGFUNC("e1000_reset_hw"); DEBUGFUNC("e1000_reset_hw");
/* For 82542 (rev 2.0), disable MWI before issuing a device reset */ /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
if(hw->mac_type == e1000_82542_rev2_0) { if(hw->mac_type == e1000_82542_rev2_0) {
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
...@@ -156,6 +252,12 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -156,6 +252,12 @@ e1000_reset_hw(struct e1000_hw *hw)
DEBUGOUT("Issuing a global reset to MAC\n"); DEBUGOUT("Issuing a global reset to MAC\n");
ctrl = E1000_READ_REG(hw, CTRL); ctrl = E1000_READ_REG(hw, CTRL);
/* Must reset the PHY before resetting the MAC */
if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
msec_delay(5);
}
if(hw->mac_type > e1000_82543) if(hw->mac_type > e1000_82543)
E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST)); E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
else else
...@@ -173,13 +275,25 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -173,13 +275,25 @@ e1000_reset_hw(struct e1000_hw *hw)
msec_delay(2); msec_delay(2);
} else { } else {
/* Wait for EEPROM reload (it happens automatically) */ /* Wait for EEPROM reload (it happens automatically) */
msec_delay(4); msec_delay(5);
/* Dissable HW ARPs on ASF enabled adapters */ /* Dissable HW ARPs on ASF enabled adapters */
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);
} }
if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
e1000_phy_init_script(hw);
/* 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;
if(hw->mac_type == e1000_82547)
led_ctrl |= IGP_LED3_MODE;
E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
}
/* 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);
...@@ -353,7 +467,7 @@ e1000_setup_link(struct e1000_hw *hw) ...@@ -353,7 +467,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, &eeprom_data) < 0) { if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n"); DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
...@@ -571,10 +685,10 @@ e1000_setup_fiber_link(struct e1000_hw *hw) ...@@ -571,10 +685,10 @@ e1000_setup_fiber_link(struct e1000_hw *hw)
* *
* 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_setup_copper_link(struct e1000_hw *hw)
{ {
uint32_t ctrl; uint32_t ctrl, led_ctrl;
int32_t ret_val; int32_t ret_val;
uint16_t i; uint16_t i;
uint16_t phy_data; uint16_t phy_data;
...@@ -604,6 +718,69 @@ e1000_setup_copper_link(struct e1000_hw *hw) ...@@ -604,6 +718,69 @@ e1000_setup_copper_link(struct e1000_hw *hw)
} }
DEBUGOUT1("Phy ID = %x \n", hw->phy_id); DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
if (hw->phy_type == e1000_phy_igp) {
ret_val = e1000_phy_reset(hw);
if(ret_val < 0) {
DEBUGOUT("Error Resetting the PHY\n");
return ret_val;
}
/* Wait 10ms for MAC to configure PHY from eeprom settings */
msec_delay(15);
if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY;
}
/* 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;
if(hw->mac_type == e1000_82547)
led_ctrl |= IGP_LED3_MODE;
E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
/* Disable SmartSpeed */
if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data) < 0) {
DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY;
}
/* Set auto Master/Slave resolution process */
if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
phy_data &= ~CR_1000T_MS_ENABLE;
if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data) < 0) {
DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY;
}
}
if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
/* Force MDI for IGP PHY */
phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | IGP01E1000_PSCR_FORCE_MDI_MDIX);
hw->mdix = 1;
if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY;
}
} else {
/* Enable CRS on TX. This must be set for half-duplex operation. */ /* Enable CRS on TX. This must be set for half-duplex operation. */
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) { if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n"); DEBUGOUT("PHY Read Error\n");
...@@ -677,7 +854,8 @@ e1000_setup_copper_link(struct e1000_hw *hw) ...@@ -677,7 +854,8 @@ e1000_setup_copper_link(struct e1000_hw *hw)
DEBUGOUT("Error Resetting the PHY\n"); DEBUGOUT("Error Resetting the PHY\n");
return ret_val; return ret_val;
} }
}
/* Options: /* Options:
* autoneg = 1 (default) * autoneg = 1 (default)
* PHY will advertise value(s) parsed from * PHY will advertise value(s) parsed from
...@@ -736,6 +914,7 @@ e1000_setup_copper_link(struct e1000_hw *hw) ...@@ -736,6 +914,7 @@ e1000_setup_copper_link(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
} }
hw->get_link_status = TRUE;
} else { } else {
DEBUGOUT("Forcing speed and duplex\n"); DEBUGOUT("Forcing speed and duplex\n");
ret_val = e1000_phy_force_speed_duplex(hw); ret_val = e1000_phy_force_speed_duplex(hw);
...@@ -1014,6 +1193,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) ...@@ -1014,6 +1193,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
/* 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);
if (hw->phy_type == e1000_phy_m88) {
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) { if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n"); DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
...@@ -1031,6 +1211,23 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) ...@@ -1031,6 +1211,23 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
/* Need to reset the PHY or these changes will be ignored */ /* Need to reset the PHY or these changes will be ignored */
mii_ctrl_reg |= MII_CR_RESET; mii_ctrl_reg |= MII_CR_RESET;
} else {
/* Clear Auto-Crossover to force MDI manually. IGP requires MDI
* forced whenever speed or duplex are forced.
*/
if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY;
}
}
/* Write back the modified PHY MII control register. */ /* Write back the modified PHY MII control register. */
if(e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg) < 0) { if(e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg) < 0) {
...@@ -1093,7 +1290,8 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) ...@@ -1093,7 +1290,8 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
} }
} }
} }
if (hw->phy_type == e1000_phy_m88) {
/* Because we reset the PHY above, we need to re-force TX_CLK in the /* Because we reset the PHY above, we need to re-force TX_CLK in the
* Extended PHY Specific Control Register to 25MHz clock. This value * Extended PHY Specific Control Register to 25MHz clock. This value
* defaults back to a 2.5MHz clock when the PHY is reset. * defaults back to a 2.5MHz clock when the PHY is reset.
...@@ -1120,6 +1318,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) ...@@ -1120,6 +1318,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
DEBUGOUT("PHY Write Error\n"); DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
} }
}
return 0; return 0;
} }
...@@ -1136,6 +1335,8 @@ e1000_config_collision_dist(struct e1000_hw *hw) ...@@ -1136,6 +1335,8 @@ e1000_config_collision_dist(struct e1000_hw *hw)
{ {
uint32_t tctl; uint32_t tctl;
DEBUGFUNC("e1000_config_collision_dist");
tctl = E1000_READ_REG(hw, TCTL); tctl = E1000_READ_REG(hw, TCTL);
tctl &= ~E1000_TCTL_COLD; tctl &= ~E1000_TCTL_COLD;
...@@ -1172,6 +1373,26 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) ...@@ -1172,6 +1373,26 @@ 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) {
if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
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
* negotiated values.
*/
if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
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 {
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) { if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n"); DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
...@@ -1188,6 +1409,7 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) ...@@ -1188,6 +1409,7 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
ctrl |= E1000_CTRL_SPD_1000; ctrl |= E1000_CTRL_SPD_1000;
else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS) else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
ctrl |= E1000_CTRL_SPD_100; 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 0; return 0;
...@@ -1519,6 +1741,10 @@ e1000_check_for_link(struct e1000_hw *hw) ...@@ -1519,6 +1741,10 @@ e1000_check_for_link(struct e1000_hw *hw)
if(phy_data & MII_SR_LINK_STATUS) { if(phy_data & MII_SR_LINK_STATUS) {
hw->get_link_status = FALSE; hw->get_link_status = FALSE;
/* Check if there was DownShift, must be checked immediately after
* link-up */
e1000_check_downshift(hw);
} else { } else {
/* No link detected */ /* No link detected */
return 0; return 0;
...@@ -2021,8 +2247,7 @@ e1000_write_phy_reg(struct e1000_hw *hw, ...@@ -2021,8 +2247,7 @@ e1000_write_phy_reg(struct e1000_hw *hw,
void void
e1000_phy_hw_reset(struct e1000_hw *hw) e1000_phy_hw_reset(struct e1000_hw *hw)
{ {
uint32_t ctrl; uint32_t ctrl, ctrl_ext, led_ctrl;
uint32_t ctrl_ext;
DEBUGFUNC("e1000_phy_hw_reset"); DEBUGFUNC("e1000_phy_hw_reset");
...@@ -2053,6 +2278,21 @@ e1000_phy_hw_reset(struct e1000_hw *hw) ...@@ -2053,6 +2278,21 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
} }
udelay(150); udelay(150);
if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
DEBUGOUT("PHY Write Error\n");
return;
}
/* 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;
if(hw->mac_type == e1000_82547)
led_ctrl |= IGP_LED3_MODE;
E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
}
} }
/****************************************************************************** /******************************************************************************
...@@ -2079,6 +2319,9 @@ e1000_phy_reset(struct e1000_hw *hw) ...@@ -2079,6 +2319,9 @@ e1000_phy_reset(struct e1000_hw *hw)
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
} }
udelay(1); udelay(1);
if (hw->phy_type == e1000_phy_igp) {
e1000_phy_init_script(hw);
}
return 0; return 0;
} }
...@@ -2092,6 +2335,7 @@ e1000_detect_gig_phy(struct e1000_hw *hw) ...@@ -2092,6 +2335,7 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
{ {
uint16_t phy_id_high, phy_id_low; uint16_t phy_id_high, phy_id_low;
boolean_t match = FALSE; boolean_t match = FALSE;
int32_t phy_init_status;
DEBUGFUNC("e1000_detect_gig_phy"); DEBUGFUNC("e1000_detect_gig_phy");
...@@ -2101,7 +2345,7 @@ e1000_detect_gig_phy(struct e1000_hw *hw) ...@@ -2101,7 +2345,7 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
} }
hw->phy_id = (uint32_t) (phy_id_high << 16); hw->phy_id = (uint32_t) (phy_id_high << 16);
udelay(2); udelay(20);
if(e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) { if(e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) {
DEBUGOUT("PHY Read Error\n"); DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
...@@ -2121,11 +2365,17 @@ e1000_detect_gig_phy(struct e1000_hw *hw) ...@@ -2121,11 +2365,17 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
case e1000_82546: case e1000_82546:
if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE; if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
break; break;
case e1000_82541:
case e1000_82547:
if(hw->phy_id == IGP01E1000_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;
} }
if(match) { phy_init_status = e1000_set_phy_type(hw);
if ((match) && (phy_init_status == E1000_SUCCESS)) {
DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id); DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
return 0; return 0;
} }
...@@ -2155,6 +2405,133 @@ e1000_phy_reset_dsp(struct e1000_hw *hw) ...@@ -2155,6 +2405,133 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
/******************************************************************************
* Get PHY information from various PHY registers for igp PHY only.
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
int32_t
e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
{
uint16_t phy_data, polarity, min_length, max_length, average;
DEBUGFUNC("e1000_phy_igp_get_info");
/* The downshift status is checked only once, after link is established,
* and it stored in the hw->speed_downgraded parameter. */
phy_info->downshift = hw->speed_downgraded;
/* IGP01E1000 does not need to support it. */
phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
/* IGP01E1000 always correct polarity reversal */
phy_info->polarity_correction = e1000_polarity_reversal_enabled;
/* Check polarity status */
if(e1000_check_polarity(hw, &polarity) < 0)
return -E1000_ERR_PHY;
phy_info->cable_polarity = polarity;
if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
return -E1000_ERR_PHY;
phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
IGP01E1000_PSSR_MDIX_SHIFT;
if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
IGP01E1000_PSSR_SPEED_1000MBPS) {
/* Local/Remote Receiver Information are only valid at 1000 Mbps */
if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
return -E1000_ERR_PHY;
phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
SR_1000T_LOCAL_RX_STATUS_SHIFT;
phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
SR_1000T_REMOTE_RX_STATUS_SHIFT;
/* Get cable length */
if(e1000_get_cable_length(hw, &min_length, &max_length) < 0)
return -E1000_ERR_PHY;
/* transalte to old method */
average = (max_length + min_length) / 2;
if(average <= e1000_igp_cable_length_50)
phy_info->cable_length = e1000_cable_length_50;
else if(average <= e1000_igp_cable_length_80)
phy_info->cable_length = e1000_cable_length_50_80;
else if(average <= e1000_igp_cable_length_110)
phy_info->cable_length = e1000_cable_length_80_110;
else if(average <= e1000_igp_cable_length_140)
phy_info->cable_length = e1000_cable_length_110_140;
else
phy_info->cable_length = e1000_cable_length_140;
}
return E1000_SUCCESS;
}
/******************************************************************************
* Get PHY information from various PHY registers fot m88 PHY only.
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
int32_t
e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
{
uint16_t phy_data, polarity;
DEBUGFUNC("e1000_phy_m88_get_info");
/* The downshift status is checked only once, after link is established,
* and it stored in the hw->speed_downgraded parameter. */
phy_info->downshift = hw->speed_downgraded;
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0)
return -E1000_ERR_PHY;
phy_info->extended_10bt_distance =
(phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
phy_info->polarity_correction =
(phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
/* Check polarity status */
if(e1000_check_polarity(hw, &polarity) < 0)
return -E1000_ERR_PHY;
phy_info->cable_polarity = polarity;
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
return -E1000_ERR_PHY;
phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
M88E1000_PSSR_MDIX_SHIFT;
if(phy_data & M88E1000_PSSR_1000MBS) {
/* Cable Length Estimation and Local/Remote Receiver Informatoion
* are only valid at 1000 Mbps
*/
phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
M88E1000_PSSR_CABLE_LENGTH_SHIFT);
if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
return -E1000_ERR_PHY;
phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
SR_1000T_LOCAL_RX_STATUS_SHIFT;
phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
SR_1000T_REMOTE_RX_STATUS_SHIFT;
}
return E1000_SUCCESS;
}
/****************************************************************************** /******************************************************************************
* Get PHY information from various PHY registers * Get PHY information from various PHY registers
* *
...@@ -2165,7 +2542,6 @@ int32_t ...@@ -2165,7 +2542,6 @@ int32_t
e1000_phy_get_info(struct e1000_hw *hw, e1000_phy_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info) struct e1000_phy_info *phy_info)
{ {
int32_t ret_val = -E1000_ERR_PHY;
uint16_t phy_data; uint16_t phy_data;
DEBUGFUNC("e1000_phy_get_info"); DEBUGFUNC("e1000_phy_get_info");
...@@ -2173,6 +2549,7 @@ e1000_phy_get_info(struct e1000_hw *hw, ...@@ -2173,6 +2549,7 @@ e1000_phy_get_info(struct e1000_hw *hw,
phy_info->cable_length = e1000_cable_length_undefined; phy_info->cable_length = e1000_cable_length_undefined;
phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined; phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
phy_info->cable_polarity = e1000_rev_polarity_undefined; phy_info->cable_polarity = e1000_rev_polarity_undefined;
phy_info->downshift = e1000_downshift_undefined;
phy_info->polarity_correction = e1000_polarity_reversal_undefined; phy_info->polarity_correction = e1000_polarity_reversal_undefined;
phy_info->mdix_mode = e1000_auto_x_mode_undefined; phy_info->mdix_mode = e1000_auto_x_mode_undefined;
phy_info->local_rx = e1000_1000t_rx_status_undefined; phy_info->local_rx = e1000_1000t_rx_status_undefined;
...@@ -2183,47 +2560,23 @@ e1000_phy_get_info(struct e1000_hw *hw, ...@@ -2183,47 +2560,23 @@ e1000_phy_get_info(struct e1000_hw *hw,
return -E1000_ERR_CONFIG; return -E1000_ERR_CONFIG;
} }
do { if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) break; DEBUGOUT("PHY Read Error\n");
if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) break; return -E1000_ERR_PHY;
if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) { }
DEBUGOUT("PHY info is only valid if link is up\n"); if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
return -E1000_ERR_CONFIG; DEBUGOUT("PHY Read Error\n");
} return -E1000_ERR_PHY;
}
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
break; DEBUGOUT("PHY info is only valid if link is up\n");
phy_info->extended_10bt_distance = return -E1000_ERR_CONFIG;
(phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >> }
M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
phy_info->polarity_correction =
(phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
break;
phy_info->cable_polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
M88E1000_PSSR_REV_POLARITY_SHIFT;
phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
M88E1000_PSSR_MDIX_SHIFT;
if(phy_data & M88E1000_PSSR_1000MBS) {
/* Cable Length Estimation and Local/Remote Receiver Informatoion
* are only valid at 1000 Mbps
*/
phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
M88E1000_PSSR_CABLE_LENGTH_SHIFT);
if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
break;
phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
SR_1000T_LOCAL_RX_STATUS_SHIFT;
phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
SR_1000T_REMOTE_RX_STATUS_SHIFT;
}
ret_val = 0;
} while(0);
if(ret_val < 0) DEBUGOUT("PHY Read Error\n"); if (hw->phy_type == e1000_phy_igp)
return ret_val; return e1000_phy_igp_get_info(hw, phy_info);
else
return e1000_phy_m88_get_info(hw, phy_info);
} }
int32_t int32_t
...@@ -2239,6 +2592,109 @@ e1000_validate_mdi_setting(struct e1000_hw *hw) ...@@ -2239,6 +2592,109 @@ e1000_validate_mdi_setting(struct e1000_hw *hw)
return 0; return 0;
} }
/******************************************************************************
* Sets up eeprom variables in the hw struct. Must be called after mac_type
* is configured.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
void
e1000_init_eeprom_params(struct e1000_hw *hw)
{
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd = E1000_READ_REG(hw, EECD);
uint16_t eeprom_size;
DEBUGFUNC("e1000_init_eeprom_params");
switch (hw->mac_type) {
case e1000_82542_rev2_0:
case e1000_82542_rev2_1:
case e1000_82543:
case e1000_82544:
eeprom->type = e1000_eeprom_microwire;
eeprom->word_size = 64;
eeprom->opcode_bits = 3;
eeprom->address_bits = 6;
eeprom->delay_usec = 50;
break;
case e1000_82540:
case e1000_82545:
case e1000_82546:
eeprom->type = e1000_eeprom_microwire;
eeprom->opcode_bits = 3;
eeprom->delay_usec = 50;
if(eecd & E1000_EECD_SIZE) {
eeprom->word_size = 256;
eeprom->address_bits = 8;
} else {
eeprom->word_size = 64;
eeprom->address_bits = 6;
}
break;
case e1000_82541:
case e1000_82547:
default:
if (eecd & E1000_EECD_TYPE) {
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;
}
} else {
eeprom->type = e1000_eeprom_microwire;
eeprom->opcode_bits = 3;
eeprom->delay_usec = 50;
if (eecd & E1000_EECD_ADDR_BITS) {
eeprom->word_size = 256;
eeprom->address_bits = 8;
} else {
eeprom->word_size = 64;
eeprom->address_bits = 6;
}
}
break;
}
if (eeprom->type == e1000_eeprom_spi) {
eeprom->word_size = 64;
if (e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) {
eeprom_size &= EEPROM_SIZE_MASK;
switch (eeprom_size) {
case EEPROM_SIZE_16KB:
eeprom->word_size = 8192;
break;
case EEPROM_SIZE_8KB:
eeprom->word_size = 4096;
break;
case EEPROM_SIZE_4KB:
eeprom->word_size = 2048;
break;
case EEPROM_SIZE_2KB:
eeprom->word_size = 1024;
break;
case EEPROM_SIZE_1KB:
eeprom->word_size = 512;
break;
case EEPROM_SIZE_512B:
eeprom->word_size = 256;
break;
case EEPROM_SIZE_128B:
default:
eeprom->word_size = 64;
break;
}
}
}
}
/****************************************************************************** /******************************************************************************
* Raises the EEPROM's clock input. * Raises the EEPROM's clock input.
* *
...@@ -2255,26 +2711,26 @@ e1000_raise_ee_clk(struct e1000_hw *hw, ...@@ -2255,26 +2711,26 @@ e1000_raise_ee_clk(struct e1000_hw *hw,
*eecd = *eecd | E1000_EECD_SK; *eecd = *eecd | E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd); E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
udelay(50); udelay(hw->eeprom.delay_usec);
} }
/****************************************************************************** /******************************************************************************
* Lowers the EEPROM's clock input. * Lowers the EEPROM's clock input.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* eecd - EECD's current value * eecd - EECD's current value
*****************************************************************************/ *****************************************************************************/
static void static void
e1000_lower_ee_clk(struct e1000_hw *hw, e1000_lower_ee_clk(struct e1000_hw *hw,
uint32_t *eecd) uint32_t *eecd)
{ {
/* Lower the clock input to the EEPROM (by clearing the SK bit), and then /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
* wait 50 microseconds. * wait 50 microseconds.
*/ */
*eecd = *eecd & ~E1000_EECD_SK; *eecd = *eecd & ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd); E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
udelay(50); udelay(hw->eeprom.delay_usec);
} }
/****************************************************************************** /******************************************************************************
...@@ -2289,16 +2745,21 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw, ...@@ -2289,16 +2745,21 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
uint16_t data, uint16_t data,
uint16_t count) uint16_t count)
{ {
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd; uint32_t eecd;
uint32_t mask; uint32_t mask;
/* We need to shift "count" bits out to the EEPROM. So, value in the /* We need to shift "count" bits out to the EEPROM. So, value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time. * "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits. * In order to do this, "data" must be broken down into bits.
*/ */
mask = 0x01 << (count - 1); mask = 0x01 << (count - 1);
eecd = E1000_READ_REG(hw, EECD); eecd = E1000_READ_REG(hw, EECD);
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); if (eeprom->type == e1000_eeprom_microwire) {
eecd &= ~E1000_EECD_DO;
} else if (eeprom->type == e1000_eeprom_spi) {
eecd |= E1000_EECD_DO;
}
do { do {
/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1", /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
* and then raising and then lowering the clock (the SK bit controls * and then raising and then lowering the clock (the SK bit controls
...@@ -2313,7 +2774,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw, ...@@ -2313,7 +2774,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
E1000_WRITE_REG(hw, EECD, eecd); E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
udelay(50); udelay(eeprom->delay_usec);
e1000_raise_ee_clk(hw, &eecd); e1000_raise_ee_clk(hw, &eecd);
e1000_lower_ee_clk(hw, &eecd); e1000_lower_ee_clk(hw, &eecd);
...@@ -2333,7 +2794,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw, ...@@ -2333,7 +2794,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
static uint16_t static uint16_t
e1000_shift_in_ee_bits(struct e1000_hw *hw) e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count)
{ {
uint32_t eecd; uint32_t eecd;
uint32_t i; uint32_t i;
...@@ -2351,7 +2812,7 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw) ...@@ -2351,7 +2812,7 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw)
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
data = 0; data = 0;
for(i = 0; i < 16; i++) { for(i = 0; i < count; i++) {
data = data << 1; data = data << 1;
e1000_raise_ee_clk(hw, &eecd); e1000_raise_ee_clk(hw, &eecd);
...@@ -2372,104 +2833,196 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw) ...@@ -2372,104 +2833,196 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
* function should be called before issuing a command to the EEPROM. * function should be called before issuing a command to the EEPROM.
*****************************************************************************/ *****************************************************************************/
static void static int32_t
e1000_setup_eeprom(struct e1000_hw *hw) e1000_acquire_eeprom(struct e1000_hw *hw)
{ {
uint32_t eecd; struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd, i=0;
DEBUGFUNC("e1000_acquire_eeprom");
eecd = E1000_READ_REG(hw, EECD); eecd = E1000_READ_REG(hw, EECD);
/* Clear SK and DI */ /* Request EEPROM Access */
eecd &= ~(E1000_EECD_SK | E1000_EECD_DI); if(hw->mac_type > e1000_82544) {
E1000_WRITE_REG(hw, EECD, eecd); eecd |= E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
eecd = E1000_READ_REG(hw, EECD);
while((!(eecd & E1000_EECD_GNT)) &&
(i < E1000_EEPROM_GRANT_ATTEMPTS)) {
i++;
udelay(5);
eecd = E1000_READ_REG(hw, EECD);
}
if(!(eecd & E1000_EECD_GNT)) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
DEBUGOUT("Could not acquire EEPROM grant\n");
return -E1000_ERR_EEPROM;
}
}
/* Set CS */ /* Setup EEPROM for Read/Write */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, EECD, eecd); if (eeprom->type == e1000_eeprom_microwire) {
/* Clear SK and DI */
eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
E1000_WRITE_REG(hw, EECD, eecd);
/* Set CS */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, EECD, eecd);
} else if (eeprom->type == e1000_eeprom_spi) {
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, EECD, eecd);
udelay(1);
}
return E1000_SUCCESS;
} }
/****************************************************************************** /******************************************************************************
* Returns EEPROM to a "standby" state * Returns EEPROM to a "standby" state
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
static void static void
e1000_standby_eeprom(struct e1000_hw *hw) e1000_standby_eeprom(struct e1000_hw *hw)
{ {
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd; uint32_t eecd;
eecd = E1000_READ_REG(hw, EECD); eecd = E1000_READ_REG(hw, EECD);
/* Deselct EEPROM */ if(eeprom->type == e1000_eeprom_microwire) {
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, EECD, eecd); E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
udelay(50); udelay(eeprom->delay_usec);
/* Clock high */ /* Clock high */
eecd |= E1000_EECD_SK; eecd |= E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd); E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
udelay(50); udelay(eeprom->delay_usec);
/* Select EEPROM */ /* Select EEPROM */
eecd |= E1000_EECD_CS; eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, EECD, eecd); E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
udelay(50); udelay(eeprom->delay_usec);
/* Clock low */ /* Clock low */
eecd &= ~E1000_EECD_SK; eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd); E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
udelay(50); udelay(eeprom->delay_usec);
} else if(eeprom->type == e1000_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(eeprom->delay_usec);
eecd &= ~E1000_EECD_CS;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(eeprom->delay_usec);
}
} }
/****************************************************************************** /******************************************************************************
* Raises then lowers the EEPROM's clock pin * Terminates a command by inverting the EEPROM's chip select pin
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
static void static void
e1000_clock_eeprom(struct e1000_hw *hw) e1000_release_eeprom(struct e1000_hw *hw)
{ {
uint32_t eecd; uint32_t eecd;
DEBUGFUNC("e1000_release_eeprom");
eecd = E1000_READ_REG(hw, EECD); eecd = E1000_READ_REG(hw, EECD);
/* Rising edge of clock */ if (hw->eeprom.type == e1000_eeprom_spi) {
eecd |= E1000_EECD_SK; eecd |= E1000_EECD_CS; /* Pull CS high */
E1000_WRITE_REG(hw, EECD, eecd); eecd &= ~E1000_EECD_SK; /* Lower SCK */
E1000_WRITE_FLUSH(hw);
udelay(50);
/* Falling edge of clock */ E1000_WRITE_REG(hw, EECD, eecd);
eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd); udelay(hw->eeprom.delay_usec);
E1000_WRITE_FLUSH(hw); } else if(hw->eeprom.type == e1000_eeprom_microwire) {
udelay(50); /* cleanup eeprom */
/* CS on Microwire is active-high */
eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
E1000_WRITE_REG(hw, EECD, eecd);
/* Rising edge of clock */
eecd |= E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(hw->eeprom.delay_usec);
/* Falling edge of clock */
eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(hw->eeprom.delay_usec);
}
/* Stop requesting EEPROM access */
if(hw->mac_type > e1000_82544) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
}
} }
/****************************************************************************** /******************************************************************************
* Terminates a command by lowering the EEPROM's chip select pin * Reads a 16 bit word from the EEPROM.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
static void int32_t
e1000_cleanup_eeprom(struct e1000_hw *hw) e1000_spi_eeprom_ready(struct e1000_hw *hw)
{ {
uint32_t eecd; uint16_t retry_count = 0;
uint8_t spi_stat_reg;
eecd = E1000_READ_REG(hw, EECD); DEBUGFUNC("e1000_spi_eeprom_ready");
eecd &= ~(E1000_EECD_CS | E1000_EECD_DI); /* Read "Status Register" repeatedly until the LSB is cleared. The
* EEPROM will signal that the command has been completed by clearing
* bit 0 of the internal status register. If it's not cleared within
* 5 milliseconds, then error out.
*/
retry_count = 0;
do {
e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
hw->eeprom.opcode_bits);
spi_stat_reg = (uint8_t)e1000_shift_in_ee_bits(hw, 8);
if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
break;
E1000_WRITE_REG(hw, EECD, eecd); udelay(5);
retry_count += 5;
} while(retry_count < EEPROM_MAX_RETRY_SPI);
e1000_clock_eeprom(hw); /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
* only 0-5mSec on 5V devices)
*/
if(retry_count >= EEPROM_MAX_RETRY_SPI) {
DEBUGOUT("SPI EEPROM Status error\n");
return -E1000_ERR_EEPROM;
}
return E1000_SUCCESS;
} }
/****************************************************************************** /******************************************************************************
...@@ -2477,71 +3030,76 @@ e1000_cleanup_eeprom(struct e1000_hw *hw) ...@@ -2477,71 +3030,76 @@ e1000_cleanup_eeprom(struct e1000_hw *hw)
* *
* 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 * offset - offset of word in the EEPROM to read
* data - word read from the EEPROM * data - word read from the EEPROM
* words - number of words to read
*****************************************************************************/ *****************************************************************************/
int32_t int32_t
e1000_read_eeprom(struct e1000_hw *hw, e1000_read_eeprom(struct e1000_hw *hw,
uint16_t offset, uint16_t offset,
uint16_t words,
uint16_t *data) uint16_t *data)
{ {
uint32_t eecd; struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t i = 0; uint32_t i = 0;
boolean_t large_eeprom = FALSE;
DEBUGFUNC("e1000_read_eeprom"); DEBUGFUNC("e1000_read_eeprom");
/* Request EEPROM Access */ /* A check for invalid values: offset too large, too many words, and not
if(hw->mac_type > e1000_82544) { * enough words.
eecd = E1000_READ_REG(hw, EECD); */
if(eecd & E1000_EECD_SIZE) large_eeprom = TRUE; if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
eecd |= E1000_EECD_REQ; (words == 0)) {
E1000_WRITE_REG(hw, EECD, eecd); DEBUGOUT("\"words\" parameter out of bounds\n");
eecd = E1000_READ_REG(hw, EECD); return -E1000_ERR_EEPROM;
while((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
i++;
udelay(5);
eecd = E1000_READ_REG(hw, EECD);
}
if(!(eecd & E1000_EECD_GNT)) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
DEBUGOUT("Could not acquire EEPROM grant\n");
return -E1000_ERR_EEPROM;
}
} }
/* Prepare the EEPROM for reading */ /* Prepare the EEPROM for reading */
e1000_setup_eeprom(hw); if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
return -E1000_ERR_EEPROM;
/* Send the READ command (opcode + addr) */ if(eeprom->type == e1000_eeprom_spi) {
e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE, 3); uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
if(large_eeprom) {
/* If we have a 256 word EEPROM, there are 8 address bits */
e1000_shift_out_ee_bits(hw, offset, 8);
} else {
/* If we have a 64 word EEPROM, there are 6 address bits */
e1000_shift_out_ee_bits(hw, offset, 6);
}
/* Read the data */ if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
*data = e1000_shift_in_ee_bits(hw);
/* End this read operation */ e1000_standby_eeprom(hw);
e1000_standby_eeprom(hw);
/* Stop requesting EEPROM access */ /* Some SPI eeproms use the 8th address bit embedded in the opcode */
if(hw->mac_type > e1000_82544) { if((eeprom->address_bits == 8) && (offset >= 128))
eecd = E1000_READ_REG(hw, EECD); read_opcode |= EEPROM_A8_OPCODE_SPI;
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd); /* Send the READ command (opcode + addr) */
e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits);
}
else if(eeprom->type == e1000_eeprom_microwire) {
/* Send the READ command (opcode + addr) */
e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
eeprom->opcode_bits);
e1000_shift_out_ee_bits(hw, offset, eeprom->address_bits);
} }
/* Read the data. The address of the eeprom internally increments with
* each word (microwire) or byte (spi) being read, saving on the overhead
* of eeprom setup and tear-down. The address counter will roll over if
* reading beyond the size of the eeprom, thus allowing the entire memory
* to be read starting from any offset. */
for (i = 0; i < words; i++) {
uint16_t word_in = e1000_shift_in_ee_bits(hw, 16);
if (eeprom->type == e1000_eeprom_spi)
word_in = (word_in >> 8) | (word_in << 8);
data[i] = word_in;
}
/* End this read operation */
e1000_release_eeprom(hw);
return 0; return 0;
} }
/****************************************************************************** /******************************************************************************
* Verifies that the EEPROM has a valid checksum * Verifies that the EEPROM has a valid checksum
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Reads the first 64 16 bit words of the EEPROM and sums the values read. * Reads the first 64 16 bit words of the EEPROM and sums the values read.
...@@ -2557,7 +3115,7 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw) ...@@ -2557,7 +3115,7 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw)
DEBUGFUNC("e1000_validate_eeprom_checksum"); DEBUGFUNC("e1000_validate_eeprom_checksum");
for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
if(e1000_read_eeprom(hw, i, &eeprom_data) < 0) { if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n"); DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
...@@ -2589,14 +3147,14 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw) ...@@ -2589,14 +3147,14 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
DEBUGFUNC("e1000_update_eeprom_checksum"); DEBUGFUNC("e1000_update_eeprom_checksum");
for(i = 0; i < EEPROM_CHECKSUM_REG; i++) { for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
if(e1000_read_eeprom(hw, i, &eeprom_data) < 0) { if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n"); DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
checksum += eeprom_data; checksum += eeprom_data;
} }
checksum = (uint16_t) EEPROM_SUM - checksum; checksum = (uint16_t) EEPROM_SUM - checksum;
if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 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;
} }
...@@ -2604,118 +3162,201 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw) ...@@ -2604,118 +3162,201 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
} }
/****************************************************************************** /******************************************************************************
* Writes a 16 bit word to a given offset in the EEPROM. * Parent function for writing words to the different EEPROM types.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* offset - offset within the EEPROM to be written to * offset - offset within the EEPROM to be written to
* data - 16 bit word to be writen to the EEPROM * words - number of words to write
* data - 16 bit word to be written to the EEPROM
* *
* If e1000_update_eeprom_checksum is not called after this function, the * If e1000_update_eeprom_checksum is not called after this function, the
* EEPROM will most likely contain an invalid checksum. * EEPROM will most likely contain an invalid checksum.
*****************************************************************************/ *****************************************************************************/
int32_t int32_t
e1000_write_eeprom(struct e1000_hw *hw, e1000_write_eeprom(struct e1000_hw *hw,
uint16_t offset, uint16_t offset,
uint16_t data) uint16_t words,
uint16_t *data)
{ {
uint32_t eecd; struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t i = 0;
int32_t status = 0; int32_t status = 0;
boolean_t large_eeprom = FALSE;
DEBUGFUNC("e1000_write_eeprom"); DEBUGFUNC("e1000_write_eeprom");
/* Request EEPROM Access */ /* A check for invalid values: offset too large, too many words, and not
if(hw->mac_type > e1000_82544) { * enough words.
eecd = E1000_READ_REG(hw, EECD); */
if(eecd & E1000_EECD_SIZE) large_eeprom = TRUE; if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
eecd |= E1000_EECD_REQ; (words == 0)) {
E1000_WRITE_REG(hw, EECD, eecd); DEBUGOUT("\"words\" parameter out of bounds\n");
eecd = E1000_READ_REG(hw, EECD); return -E1000_ERR_EEPROM;
while((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
i++;
udelay(5);
eecd = E1000_READ_REG(hw, EECD);
}
if(!(eecd & E1000_EECD_GNT)) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
DEBUGOUT("Could not acquire EEPROM grant\n");
return -E1000_ERR_EEPROM;
}
} }
/* Prepare the EEPROM for writing */ /* Prepare the EEPROM for writing */
e1000_setup_eeprom(hw); if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
return -E1000_ERR_EEPROM;
/* Send the 9-bit (or 11-bit on large EEPROM) EWEN (write enable) command if(eeprom->type == e1000_eeprom_microwire)
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This puts the EEPROM status = e1000_write_eeprom_microwire(hw, offset, words, data);
* into write/erase mode.
*/
e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE, 5);
if(large_eeprom)
e1000_shift_out_ee_bits(hw, 0, 6);
else else
e1000_shift_out_ee_bits(hw, 0, 4); status = e1000_write_eeprom_spi(hw, offset, words, data);
/* Prepare the EEPROM */ /* Done with writing */
e1000_standby_eeprom(hw); e1000_release_eeprom(hw);
/* Send the Write command (3-bit opcode + addr) */ return status;
e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE, 3); }
if(large_eeprom)
/* If we have a 256 word EEPROM, there are 8 address bits */ /******************************************************************************
e1000_shift_out_ee_bits(hw, offset, 8); * Writes a 16 bit word to a given offset in an SPI EEPROM.
else *
/* If we have a 64 word EEPROM, there are 6 address bits */ * hw - Struct containing variables accessed by shared code
e1000_shift_out_ee_bits(hw, offset, 6); * offset - offset within the EEPROM to be written to
* words - number of words to write
* data - pointer to array of 8 bit words to be written to the EEPROM
*
*****************************************************************************/
int32_t
e1000_write_eeprom_spi(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
uint16_t *data)
{
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint16_t widx = 0;
/* Send the data */ DEBUGFUNC("e1000_write_eeprom_spi");
e1000_shift_out_ee_bits(hw, data, 16);
/* Toggle the CS line. This in effect tells to EEPROM to actually execute while (widx < words) {
* the command in question. uint8_t write_opcode = EEPROM_WRITE_OPCODE_SPI;
*/
e1000_standby_eeprom(hw);
/* Now read DO repeatedly until is high (equal to '1'). The EEEPROM will if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
* signal that the command has been completed by raising the DO signal.
* If DO does not go high in 10 milliseconds, then error out. e1000_standby_eeprom(hw);
*/
for(i = 0; i < 200; i++) { /* Send the WRITE ENABLE command (8 bit opcode ) */
eecd = E1000_READ_REG(hw, EECD); e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
if(eecd & E1000_EECD_DO) break; eeprom->opcode_bits);
udelay(50);
} e1000_standby_eeprom(hw);
if(i == 200) {
DEBUGOUT("EEPROM Write did not complete\n"); /* Some SPI eeproms use the 8th address bit embedded in the opcode */
status = -E1000_ERR_EEPROM; if((eeprom->address_bits == 8) && (offset >= 128))
write_opcode |= EEPROM_A8_OPCODE_SPI;
/* Send the Write command (8-bit opcode + addr) */
e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
e1000_shift_out_ee_bits(hw, (uint16_t)((offset + widx)*2),
eeprom->address_bits);
/* Send the data */
/* Loop to allow for up to whole page write (32 bytes) of eeprom */
while (widx < words) {
uint16_t word_out = data[widx];
word_out = (word_out >> 8) | (word_out << 8);
e1000_shift_out_ee_bits(hw, word_out, 16);
widx++;
/* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
* operation, while the smaller eeproms are capable of an 8-byte
* PAGE WRITE operation. Break the inner loop to pass new address
*/
if((((offset + widx)*2) % eeprom->page_size) == 0) {
e1000_standby_eeprom(hw);
break;
}
}
} }
/* Recover from write */ return E1000_SUCCESS;
e1000_standby_eeprom(hw); }
/******************************************************************************
* Writes a 16 bit word to a given offset in a Microwire EEPROM.
*
* hw - Struct containing variables accessed by shared code
* offset - offset within the EEPROM to be written to
* words - number of words to write
* data - pointer to array of 16 bit words to be written to the EEPROM
*
*****************************************************************************/
int32_t
e1000_write_eeprom_microwire(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
uint16_t *data)
{
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd;
uint16_t words_written = 0;
uint16_t i = 0;
/* Send the 9-bit (or 11-bit on large EEPROM) EWDS (write disable) command DEBUGFUNC("e1000_write_eeprom_microwire");
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This takes the EEPROM
* out of write/erase mode. /* Send the write enable command to the EEPROM (3-bit opcode plus
* 6/8-bit dummy address beginning with 11). It's less work to include
* the 11 of the dummy address as part of the opcode than it is to shift
* it over the correct number of bits for the address. This puts the
* EEPROM into write/erase mode.
*/ */
e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5); e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
if(large_eeprom) (uint16_t)(eeprom->opcode_bits + 2));
e1000_shift_out_ee_bits(hw, 0, 6);
else
e1000_shift_out_ee_bits(hw, 0, 4);
/* Done with writing */ e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
e1000_cleanup_eeprom(hw);
/* Stop requesting EEPROM access */ /* Prepare the EEPROM */
if(hw->mac_type > e1000_82544) { e1000_standby_eeprom(hw);
eecd = E1000_READ_REG(hw, EECD);
eecd &= ~E1000_EECD_REQ; while (words_written < words) {
E1000_WRITE_REG(hw, EECD, eecd); /* Send the Write command (3-bit opcode + addr) */
e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
eeprom->opcode_bits);
e1000_shift_out_ee_bits(hw, (uint16_t)(offset + words_written),
eeprom->address_bits);
/* Send the data */
e1000_shift_out_ee_bits(hw, data[words_written], 16);
/* Toggle the CS line. This in effect tells the EEPROM to execute
* the previous command.
*/
e1000_standby_eeprom(hw);
/* Read DO repeatedly until it is high (equal to '1'). The EEPROM will
* signal that the command has been completed by raising the DO signal.
* If DO does not go high in 10 milliseconds, then error out.
*/
for(i = 0; i < 200; i++) {
eecd = E1000_READ_REG(hw, EECD);
if(eecd & E1000_EECD_DO) break;
udelay(50);
}
if(i == 200) {
DEBUGOUT("EEPROM Write did not complete\n");
return -E1000_ERR_EEPROM;
}
/* Recover from write */
e1000_standby_eeprom(hw);
words_written++;
} }
return status; /* Send the write disable command to the EEPROM (3-bit opcode plus
* 6/8-bit dummy address beginning with 10). It's less work to include
* the 10 of the dummy address as part of the opcode than it is to shift
* it over the correct number of bits for the address. This takes the
* EEPROM out of write/erase mode.
*/
e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
(uint16_t)(eeprom->opcode_bits + 2));
e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
return 0;
} }
/****************************************************************************** /******************************************************************************
...@@ -2734,7 +3375,7 @@ e1000_read_part_num(struct e1000_hw *hw, ...@@ -2734,7 +3375,7 @@ e1000_read_part_num(struct e1000_hw *hw,
DEBUGFUNC("e1000_read_part_num"); DEBUGFUNC("e1000_read_part_num");
/* Get word 0 from EEPROM */ /* Get word 0 from EEPROM */
if(e1000_read_eeprom(hw, offset, &eeprom_data) < 0) { if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n"); DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
...@@ -2742,7 +3383,7 @@ e1000_read_part_num(struct e1000_hw *hw, ...@@ -2742,7 +3383,7 @@ e1000_read_part_num(struct e1000_hw *hw,
*part_num = (uint32_t) (eeprom_data << 16); *part_num = (uint32_t) (eeprom_data << 16);
/* Get word 1 from EEPROM */ /* Get word 1 from EEPROM */
if(e1000_read_eeprom(hw, ++offset, &eeprom_data) < 0) { if(e1000_read_eeprom(hw, ++offset, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n"); DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
...@@ -2768,7 +3409,7 @@ e1000_read_mac_addr(struct e1000_hw * hw) ...@@ -2768,7 +3409,7 @@ e1000_read_mac_addr(struct e1000_hw * hw)
for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) { for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
offset = i >> 1; offset = i >> 1;
if(e1000_read_eeprom(hw, offset, &eeprom_data) < 0) { if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n"); DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
...@@ -3055,24 +3696,24 @@ e1000_id_led_init(struct e1000_hw * hw) ...@@ -3055,24 +3696,24 @@ e1000_id_led_init(struct e1000_hw * hw)
const uint32_t ledctl_off = E1000_LEDCTL_MODE_LED_OFF; const uint32_t ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
uint16_t eeprom_data, i, temp; uint16_t eeprom_data, i, temp;
const uint16_t led_mask = 0x0F; const uint16_t led_mask = 0x0F;
DEBUGFUNC("e1000_id_led_init"); DEBUGFUNC("e1000_id_led_init");
if(hw->mac_type < e1000_82540) { if(hw->mac_type < e1000_82540) {
/* Nothing to do */ /* Nothing to do */
return 0; return 0;
} }
ledctl = E1000_READ_REG(hw, LEDCTL); ledctl = E1000_READ_REG(hw, LEDCTL);
hw->ledctl_default = ledctl; hw->ledctl_default = ledctl;
hw->ledctl_mode1 = hw->ledctl_default; hw->ledctl_mode1 = hw->ledctl_default;
hw->ledctl_mode2 = hw->ledctl_default; hw->ledctl_mode2 = hw->ledctl_default;
if(e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, &eeprom_data) < 0) { if(e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n"); DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM; return -E1000_ERR_EEPROM;
} }
if((eeprom_data== ID_LED_RESERVED_0000) || if((eeprom_data== ID_LED_RESERVED_0000) ||
(eeprom_data == ID_LED_RESERVED_FFFF)) eeprom_data = ID_LED_DEFAULT; (eeprom_data == ID_LED_RESERVED_FFFF)) eeprom_data = ID_LED_DEFAULT;
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
temp = (eeprom_data >> (i << 2)) & led_mask; temp = (eeprom_data >> (i << 2)) & led_mask;
...@@ -3155,6 +3796,9 @@ e1000_setup_led(struct e1000_hw *hw) ...@@ -3155,6 +3796,9 @@ e1000_setup_led(struct e1000_hw *hw)
case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_COPPER: case E1000_DEV_ID_82545EM_COPPER:
case E1000_DEV_ID_82546EB_COPPER: case E1000_DEV_ID_82546EB_COPPER:
case E1000_DEV_ID_82541EI:
case E1000_DEV_ID_82541EP:
case E1000_DEV_ID_82547EI:
E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1); E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
break; break;
default: default:
...@@ -3193,6 +3837,9 @@ e1000_cleanup_led(struct e1000_hw *hw) ...@@ -3193,6 +3837,9 @@ e1000_cleanup_led(struct e1000_hw *hw)
case E1000_DEV_ID_82545EM_FIBER: case E1000_DEV_ID_82545EM_FIBER:
case E1000_DEV_ID_82546EB_COPPER: case E1000_DEV_ID_82546EB_COPPER:
case E1000_DEV_ID_82546EB_FIBER: case E1000_DEV_ID_82546EB_FIBER:
case E1000_DEV_ID_82541EI:
case E1000_DEV_ID_82541EP:
case E1000_DEV_ID_82547EI:
/* Restore LEDCTL settings */ /* Restore LEDCTL settings */
E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default); E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
break; break;
...@@ -3244,6 +3891,9 @@ e1000_led_on(struct e1000_hw *hw) ...@@ -3244,6 +3891,9 @@ e1000_led_on(struct e1000_hw *hw)
case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_COPPER: case E1000_DEV_ID_82545EM_COPPER:
case E1000_DEV_ID_82546EB_COPPER: case E1000_DEV_ID_82546EB_COPPER:
case E1000_DEV_ID_82541EI:
case E1000_DEV_ID_82541EP:
case E1000_DEV_ID_82547EI:
E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2); E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
break; break;
default: default:
...@@ -3294,6 +3944,9 @@ e1000_led_off(struct e1000_hw *hw) ...@@ -3294,6 +3944,9 @@ e1000_led_off(struct e1000_hw *hw)
case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_COPPER: case E1000_DEV_ID_82545EM_COPPER:
case E1000_DEV_ID_82546EB_COPPER: case E1000_DEV_ID_82546EB_COPPER:
case E1000_DEV_ID_82541EI:
case E1000_DEV_ID_82541EP:
case E1000_DEV_ID_82547EI:
E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1); E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
break; break;
default: default:
...@@ -3608,3 +4261,221 @@ e1000_write_reg_io(struct e1000_hw *hw, ...@@ -3608,3 +4261,221 @@ e1000_write_reg_io(struct e1000_hw *hw,
e1000_io_write(hw, io_data, value); e1000_io_write(hw, io_data, value);
} }
/******************************************************************************
* Estimates the cable length.
*
* hw - Struct containing variables accessed by shared code
* min_length - The estimated minimum length
* max_length - The estimated maximum length
*
* returns: E1000_SUCCESS / -E1000_ERR_XXX
*
* This function always returns a ranged length (minimum & maximum).
* So for M88 phy's, this function interprets the one value returned from the
* register to the minimum and maximum range.
* For IGP phy's, the function calculates the range by the AGC registers.
*****************************************************************************/
int32_t
e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length,
uint16_t *max_length)
{
uint16_t agc_value = 0;
uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
uint16_t i, phy_data;
DEBUGFUNC("e1000_get_cable_length");
*min_length = *max_length = 0;
/* Use old method for Phy older than IGP */
if(hw->phy_type == e1000_phy_m88) {
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
return -E1000_ERR_PHY;
/* Convert the enum value to ranged values */
switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
M88E1000_PSSR_CABLE_LENGTH_SHIFT) {
case e1000_cable_length_50:
*min_length = 0;
*max_length = e1000_igp_cable_length_50;
break;
case e1000_cable_length_50_80:
*min_length = e1000_igp_cable_length_50;
*max_length = e1000_igp_cable_length_80;
break;
case e1000_cable_length_80_110:
*min_length = e1000_igp_cable_length_80;
*max_length = e1000_igp_cable_length_110;
break;
case e1000_cable_length_110_140:
*min_length = e1000_igp_cable_length_110;
*max_length = e1000_igp_cable_length_140;
break;
case e1000_cable_length_140:
*min_length = e1000_igp_cable_length_140;
*max_length = e1000_igp_cable_length_170;
break;
default:
return -E1000_ERR_PHY;
break;
}
} else if(hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
uint16_t agc_reg_array[IGP01E1000_PHY_AGC_NUM] = {IGP01E1000_PHY_AGC_A,
IGP01E1000_PHY_AGC_B,
IGP01E1000_PHY_AGC_C,
IGP01E1000_PHY_AGC_D};
/* Read the AGC registers for all channels */
for(i = 0; i < IGP01E1000_PHY_AGC_NUM; i++) {
if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
agc_reg_array[i]) != E1000_SUCCESS)
return -E1000_ERR_PHY;
if(e1000_read_phy_reg(hw, agc_reg_array[i] &
IGP01E1000_PHY_PAGE_SELECT, &phy_data) !=
E1000_SUCCESS)
return -E1000_ERR_PHY;
cur_agc = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
/* Array bound check. */
if((cur_agc >= IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1) ||
(cur_agc == 0))
return -E1000_ERR_PHY;
agc_value += cur_agc;
/* Update minimal AGC value. */
if(min_agc > cur_agc)
min_agc = cur_agc;
}
/* Return to page 0 */
if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
E1000_SUCCESS)
return -E1000_ERR_PHY;
/* Remove the minimal AGC result for length < 50m */
if(agc_value < IGP01E1000_PHY_AGC_NUM * e1000_igp_cable_length_50) {
agc_value -= min_agc;
/* Get the average length of the remaining 3 channels */
agc_value /= (IGP01E1000_PHY_AGC_NUM - 1);
} else {
/* Get the average length of all the 4 channels. */
agc_value /= IGP01E1000_PHY_AGC_NUM;
}
/* Set the range of the calculated length. */
*min_length = ((e1000_igp_cable_length_table[agc_value] -
IGP01E1000_AGC_RANGE) > 0) ?
(e1000_igp_cable_length_table[agc_value] -
IGP01E1000_AGC_RANGE) : 0;
*max_length = e1000_igp_cable_length_table[agc_value] +
IGP01E1000_AGC_RANGE;
}
return E1000_SUCCESS;
}
/******************************************************************************
* Check the cable polarity
*
* hw - Struct containing variables accessed by shared code
* polarity - output parameter : 0 - Polarity is not reversed
* 1 - Polarity is reversed.
*
* returns: E1000_SUCCESS / -E1000_ERR_XXX
*
* For phy's older then IGP, this function simply reads the polarity bit in the
* Phy Status register. For IGP phy's, this bit is valid only if link speed is
* 10 Mbps. If the link speed is 100 Mbps there is no polarity so this bit will
* return 0. If the link speed is 1000 Mbps the polarity status is in the
* IGP01E1000_PHY_PCS_INIT_REG.
*****************************************************************************/
int32_t
e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity)
{
uint16_t phy_data;
DEBUGFUNC("e1000_check_polarity");
if(hw->phy_type == e1000_phy_m88) {
/* return the Polarity bit in the Status register. */
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
return -E1000_ERR_PHY;
*polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
M88E1000_PSSR_REV_POLARITY_SHIFT;
} else if(hw->phy_type == e1000_phy_igp) {
/* Read the Status register to check the speed */
if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
return -E1000_ERR_PHY;
/* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
* find the polarity status */
if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
IGP01E1000_PSSR_SPEED_1000MBPS) {
/* Read the GIG initialization PCS register (0x00B4) */
if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
IGP01E1000_PHY_PCS_INIT_REG) < 0)
return -E1000_ERR_PHY;
if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG &
IGP01E1000_PHY_PAGE_SELECT, &phy_data) < 0)
return -E1000_ERR_PHY;
/* Return to page 0 */
if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
E1000_SUCCESS)
return -E1000_ERR_PHY;
/* Check the polarity bits */
*polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
} else {
/* For 10 Mbps, read the polarity bit in the status register. (for
* 100 Mbps this bit is always 0) */
*polarity = phy_data & IGP01E1000_PSSR_POLARITY_REVERSED;
}
}
return E1000_SUCCESS;
}
/******************************************************************************
* Check if Downshift occured
*
* hw - Struct containing variables accessed by shared code
* downshift - output parameter : 0 - No Downshift ocured.
* 1 - Downshift ocured.
*
* returns: E1000_SUCCESS / -E1000_ERR_XXX
*
* For phy's older then IGP, this function reads the Downshift bit in the Phy
* Specific Status register. For IGP phy's, it reads the Downgrade bit in the
* Link Health register. In IGP this bit is latched high, so the driver must
* read it immediately after link is established.
*****************************************************************************/
int32_t
e1000_check_downshift(struct e1000_hw *hw)
{
uint16_t phy_data;
DEBUGFUNC("e1000_check_downshift");
if(hw->phy_type == e1000_phy_igp) {
if(e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
}
else if(hw->phy_type == e1000_phy_m88) {
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
M88E1000_PSSR_DOWNSHIFT_SHIFT;
}
return E1000_SUCCESS;
}
...@@ -50,9 +50,18 @@ typedef enum { ...@@ -50,9 +50,18 @@ typedef enum {
e1000_82540, e1000_82540,
e1000_82545, e1000_82545,
e1000_82546, e1000_82546,
e1000_82541,
e1000_82547,
e1000_num_macs e1000_num_macs
} e1000_mac_type; } e1000_mac_type;
typedef enum {
e1000_eeprom_uninitialized = 0,
e1000_eeprom_spi,
e1000_eeprom_microwire,
e1000_num_eeprom_types
} e1000_eeprom_type;
/* Media Types */ /* Media Types */
typedef enum { typedef enum {
e1000_media_type_copper = 0, e1000_media_type_copper = 0,
...@@ -110,6 +119,27 @@ typedef enum { ...@@ -110,6 +119,27 @@ typedef enum {
e1000_cable_length_undefined = 0xFF e1000_cable_length_undefined = 0xFF
} e1000_cable_length; } e1000_cable_length;
typedef enum {
e1000_igp_cable_length_10 = 10,
e1000_igp_cable_length_20 = 20,
e1000_igp_cable_length_30 = 30,
e1000_igp_cable_length_40 = 40,
e1000_igp_cable_length_50 = 50,
e1000_igp_cable_length_60 = 60,
e1000_igp_cable_length_70 = 70,
e1000_igp_cable_length_80 = 80,
e1000_igp_cable_length_90 = 90,
e1000_igp_cable_length_100 = 100,
e1000_igp_cable_length_110 = 110,
e1000_igp_cable_length_120 = 120,
e1000_igp_cable_length_130 = 130,
e1000_igp_cable_length_140 = 140,
e1000_igp_cable_length_150 = 150,
e1000_igp_cable_length_160 = 160,
e1000_igp_cable_length_170 = 170,
e1000_igp_cable_length_180 = 180
} e1000_igp_cable_length;
typedef enum { typedef enum {
e1000_10bt_ext_dist_enable_normal = 0, e1000_10bt_ext_dist_enable_normal = 0,
e1000_10bt_ext_dist_enable_lower, e1000_10bt_ext_dist_enable_lower,
...@@ -122,6 +152,12 @@ typedef enum { ...@@ -122,6 +152,12 @@ typedef enum {
e1000_rev_polarity_undefined = 0xFF e1000_rev_polarity_undefined = 0xFF
} e1000_rev_polarity; } e1000_rev_polarity;
typedef enum {
e1000_downshift_normal = 0,
e1000_downshift_activated,
e1000_downshift_undefined = 0xFF
} e1000_downshift;
typedef enum { typedef enum {
e1000_polarity_reversal_enabled = 0, e1000_polarity_reversal_enabled = 0,
e1000_polarity_reversal_disabled, e1000_polarity_reversal_disabled,
...@@ -142,10 +178,17 @@ typedef enum { ...@@ -142,10 +178,17 @@ typedef enum {
e1000_1000t_rx_status_undefined = 0xFF e1000_1000t_rx_status_undefined = 0xFF
} e1000_1000t_rx_status; } e1000_1000t_rx_status;
typedef enum {
e1000_phy_m88 = 0,
e1000_phy_igp,
e1000_phy_undefined = 0xFF
} e1000_phy_type;
struct e1000_phy_info { struct e1000_phy_info {
e1000_cable_length cable_length; e1000_cable_length cable_length;
e1000_10bt_ext_dist_enable extended_10bt_distance; e1000_10bt_ext_dist_enable extended_10bt_distance;
e1000_rev_polarity cable_polarity; e1000_rev_polarity cable_polarity;
e1000_downshift downshift;
e1000_polarity_reversal polarity_correction; e1000_polarity_reversal polarity_correction;
e1000_auto_x_mode mdix_mode; e1000_auto_x_mode mdix_mode;
e1000_1000t_rx_status local_rx; e1000_1000t_rx_status local_rx;
...@@ -157,6 +200,15 @@ struct e1000_phy_stats { ...@@ -157,6 +200,15 @@ struct e1000_phy_stats {
uint32_t receive_errors; uint32_t receive_errors;
}; };
struct e1000_eeprom_info {
e1000_eeprom_type type;
uint16_t word_size;
uint16_t opcode_bits;
uint16_t address_bits;
uint16_t delay_usec;
uint16_t page_size;
};
/* Error Codes */ /* Error Codes */
...@@ -166,6 +218,7 @@ struct e1000_phy_stats { ...@@ -166,6 +218,7 @@ struct e1000_phy_stats {
#define E1000_ERR_CONFIG 3 #define E1000_ERR_CONFIG 3
#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
/* Function prototypes */ /* Function prototypes */
/* Initialization */ /* Initialization */
...@@ -189,13 +242,19 @@ void e1000_phy_hw_reset(struct e1000_hw *hw); ...@@ -189,13 +242,19 @@ void 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);
int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
int32_t e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, uint16_t *max_length);
int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
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 */
int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t *data); void e1000_init_eeprom_params(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_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 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);
...@@ -253,7 +312,10 @@ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value); ...@@ -253,7 +312,10 @@ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
#define E1000_DEV_ID_82545EM_FIBER 0x1011 #define E1000_DEV_ID_82545EM_FIBER 0x1011
#define E1000_DEV_ID_82546EB_COPPER 0x1010 #define E1000_DEV_ID_82546EB_COPPER 0x1010
#define E1000_DEV_ID_82546EB_FIBER 0x1012 #define E1000_DEV_ID_82546EB_FIBER 0x1012
#define NUM_DEV_IDS 16 #define E1000_DEV_ID_82541EI 0x1013
#define E1000_DEV_ID_82541EP 0x1018
#define E1000_DEV_ID_82547EI 0x1019
#define NUM_DEV_IDS 19
#define NODE_ADDRESS_SIZE 6 #define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6 #define ETH_LENGTH_OF_ADDRESS 6
...@@ -322,9 +384,9 @@ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value); ...@@ -322,9 +384,9 @@ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
/* The number of high/low register pairs in the RAR. The RAR (Receive Address /* The 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
* E1000_RAR_ENTRIES - 1 multicast addresses. * E1000_RAR_ENTRIES - 1 multicast addresses.
*/ */
#define E1000_RAR_ENTRIES 16 #define E1000_RAR_ENTRIES 15
#define MIN_NUMBER_OF_DESCRIPTORS 8 #define MIN_NUMBER_OF_DESCRIPTORS 8
#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8 #define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
...@@ -537,6 +599,7 @@ struct e1000_ffvt_entry { ...@@ -537,6 +599,7 @@ struct e1000_ffvt_entry {
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ #define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - RW */ #define E1000_EERD 0x00014 /* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ #define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_FLA 0x0001C /* Flash Access Register - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */ #define E1000_MDIC 0x00020 /* MDI Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ #define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
...@@ -569,6 +632,11 @@ struct e1000_ffvt_entry { ...@@ -569,6 +632,11 @@ struct e1000_ffvt_entry {
#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_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_TDFT 0x03418 /* TX Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */
#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */ #define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */ #define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */ #define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
...@@ -664,6 +732,7 @@ struct e1000_ffvt_entry { ...@@ -664,6 +732,7 @@ struct e1000_ffvt_entry {
#define E1000_82542_EECD E1000_EECD #define E1000_82542_EECD E1000_EECD
#define E1000_82542_EERD E1000_EERD #define E1000_82542_EERD E1000_EERD
#define E1000_82542_CTRL_EXT E1000_CTRL_EXT #define E1000_82542_CTRL_EXT E1000_CTRL_EXT
#define E1000_82542_FLA E1000_FLA
#define E1000_82542_MDIC E1000_MDIC #define E1000_82542_MDIC E1000_MDIC
#define E1000_82542_FCAL E1000_FCAL #define E1000_82542_FCAL E1000_FCAL
#define E1000_82542_FCAH E1000_FCAH #define E1000_82542_FCAH E1000_FCAH
...@@ -705,6 +774,9 @@ struct e1000_ffvt_entry { ...@@ -705,6 +774,9 @@ struct e1000_ffvt_entry {
#define E1000_82542_RADV E1000_RADV #define E1000_82542_RADV E1000_RADV
#define E1000_82542_RSRPD E1000_RSRPD #define E1000_82542_RSRPD E1000_RSRPD
#define E1000_82542_TXDMAC E1000_TXDMAC #define E1000_82542_TXDMAC E1000_TXDMAC
#define E1000_82542_TDFHS E1000_TDFHS
#define E1000_82542_TDFTS E1000_TDFTS
#define E1000_82542_TDFPC E1000_TDFPC
#define E1000_82542_TXDCTL E1000_TXDCTL #define E1000_82542_TXDCTL E1000_TXDCTL
#define E1000_82542_TADV E1000_TADV #define E1000_82542_TADV E1000_TADV
#define E1000_82542_TSPMT E1000_TSPMT #define E1000_82542_TSPMT E1000_TSPMT
...@@ -777,6 +849,8 @@ struct e1000_ffvt_entry { ...@@ -777,6 +849,8 @@ struct e1000_ffvt_entry {
#define E1000_82542_WUPL E1000_WUPL #define E1000_82542_WUPL E1000_WUPL
#define E1000_82542_WUPM E1000_WUPM #define E1000_82542_WUPM E1000_WUPM
#define E1000_82542_FFLT E1000_FFLT #define E1000_82542_FFLT E1000_FFLT
#define E1000_82542_TDFH 0x08010
#define E1000_82542_TDFT 0x08018
#define E1000_82542_FFMT E1000_FFMT #define E1000_82542_FFMT E1000_FFMT
#define E1000_82542_FFVT E1000_FFVT #define E1000_82542_FFVT E1000_FFVT
...@@ -846,12 +920,15 @@ struct e1000_hw_stats { ...@@ -846,12 +920,15 @@ struct e1000_hw_stats {
struct e1000_hw { struct e1000_hw {
uint8_t *hw_addr; uint8_t *hw_addr;
e1000_mac_type mac_type; e1000_mac_type mac_type;
e1000_phy_type phy_type;
uint32_t phy_init_script;
e1000_media_type media_type; e1000_media_type media_type;
void *back; void *back;
e1000_fc_type fc; e1000_fc_type fc;
e1000_bus_speed bus_speed; e1000_bus_speed bus_speed;
e1000_bus_width bus_width; e1000_bus_width bus_width;
e1000_bus_type bus_type; e1000_bus_type bus_type;
struct e1000_eeprom_info eeprom;
uint32_t io_base; uint32_t io_base;
uint32_t phy_id; uint32_t phy_id;
uint32_t phy_revision; uint32_t phy_revision;
...@@ -891,6 +968,7 @@ struct e1000_hw { ...@@ -891,6 +968,7 @@ struct e1000_hw {
uint8_t mac_addr[NODE_ADDRESS_SIZE]; uint8_t mac_addr[NODE_ADDRESS_SIZE];
uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
boolean_t disable_polarity_correction; boolean_t disable_polarity_correction;
boolean_t speed_downgraded;
boolean_t get_link_status; boolean_t get_link_status;
boolean_t tbi_compatibility_en; boolean_t tbi_compatibility_en;
boolean_t tbi_compatibility_on; boolean_t tbi_compatibility_on;
...@@ -967,14 +1045,20 @@ struct e1000_hw { ...@@ -967,14 +1045,20 @@ struct e1000_hw {
#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */ #define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */
#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */ #define E1000_EECD_DI 0x00000004 /* EEPROM Data In */
#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */ #define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */
#define E1000_EECD_FWE_MASK 0x00000030 #define E1000_EECD_FWE_MASK 0x00000030
#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */ #define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */
#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */ #define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */
#define E1000_EECD_FWE_SHIFT 4 #define E1000_EECD_FWE_SHIFT 4
#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */ #define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */
#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */ #define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */
#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */ #define E1000_EECD_PRES 0x00000100 /* EEPROM Present */
#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
* (0-small, 1-large) */
#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
#ifndef E1000_EEPROM_GRANT_ATTEMPTS
#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
#endif
/* EEPROM Read */ /* EEPROM Read */
#define E1000_EERD_START 0x00000001 /* Start Read */ #define E1000_EERD_START 0x00000001 /* Start Read */
...@@ -984,8 +1068,15 @@ struct e1000_hw { ...@@ -984,8 +1068,15 @@ struct e1000_hw {
#define E1000_EERD_DATA_SHIFT 16 #define E1000_EERD_DATA_SHIFT 16
#define E1000_EERD_DATA_MASK 0xFFFF0000 /* Read Data */ #define E1000_EERD_DATA_MASK 0xFFFF0000 /* Read Data */
/* SPI EEPROM Status Register */
#define EEPROM_STATUS_RDY_SPI 0x01
#define EEPROM_STATUS_WEN_SPI 0x02
#define EEPROM_STATUS_BP0_SPI 0x04
#define EEPROM_STATUS_BP1_SPI 0x08
#define EEPROM_STATUS_WPEN_SPI 0x80
/* Extended Device Control */ /* Extended Device Control */
#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */ #define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */
#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */ #define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN #define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */ #define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */
...@@ -1239,6 +1330,7 @@ struct e1000_hw { ...@@ -1239,6 +1330,7 @@ struct e1000_hw {
#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ #define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */ #define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */ #define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
#define E1000_WUC_SPM 0x80000000 /* Enable SPM */
/* Wake Up Filter Control */ /* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ #define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
...@@ -1302,18 +1394,40 @@ struct e1000_hw { ...@@ -1302,18 +1394,40 @@ struct e1000_hw {
#define E1000_MDALIGN 4096 #define E1000_MDALIGN 4096
/* EEPROM Commands */ /* EEPROM Commands - Microwire */
#define EEPROM_READ_OPCODE 0x6 /* EERPOM read opcode */ #define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE 0x5 /* EERPOM write opcode */ #define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
#define EEPROM_ERASE_OPCODE 0x7 /* EERPOM erase opcode */ #define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */
#define EEPROM_EWEN_OPCODE 0x13 /* EERPOM erase/write enable */ #define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */
#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */ #define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */
/* EEPROM Commands - SPI */
#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
#define EEPROM_READ_OPCODE_SPI 0x3 /* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_SPI 0x2 /* EEPROM write opcode */
#define EEPROM_A8_OPCODE_SPI 0x8 /* opcode bit-3 = address bit-8 */
#define EEPROM_WREN_OPCODE_SPI 0x6 /* EEPROM set Write Enable latch */
#define EEPROM_WRDI_OPCODE_SPI 0x4 /* EEPROM reset Write Enable latch */
#define EEPROM_RDSR_OPCODE_SPI 0x5 /* EEPROM read Status register */
#define EEPROM_WRSR_OPCODE_SPI 0x1 /* EEPROM write Status register */
/* EEPROM Size definitions */
#define EEPROM_SIZE_16KB 0x1800
#define EEPROM_SIZE_8KB 0x1400
#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
/* EEPROM Word Offsets */ /* EEPROM Word Offsets */
#define EEPROM_COMPAT 0x0003 #define EEPROM_COMPAT 0x0003
#define EEPROM_ID_LED_SETTINGS 0x0004 #define EEPROM_ID_LED_SETTINGS 0x0004
#define EEPROM_INIT_CONTROL1_REG 0x000A #define EEPROM_INIT_CONTROL1_REG 0x000A
#define EEPROM_INIT_CONTROL2_REG 0x000F #define EEPROM_INIT_CONTROL2_REG 0x000F
#define EEPROM_CFG 0x0012
#define EEPROM_FLASH_VERSION 0x0032 #define EEPROM_FLASH_VERSION 0x0032
#define EEPROM_CHECKSUM_REG 0x003F #define EEPROM_CHECKSUM_REG 0x003F
...@@ -1334,9 +1448,10 @@ struct e1000_hw { ...@@ -1334,9 +1448,10 @@ struct e1000_hw {
#define ID_LED_OFF1_ON2 0x8 #define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9 #define ID_LED_OFF1_OFF2 0x9
/* Mask bits for fields in Word 0x03 of the EEPROM */ #define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
#define EEPROM_COMPAT_SERVER 0x0400 #define IGP_ACTIVITY_LED_ENABLE 0x0300
#define EEPROM_COMPAT_CLIENT 0x0200 #define IGP_LED3_MODE 0x07000000
/* Mask bits for fields in Word 0x0a of the EEPROM */ /* Mask bits for fields in Word 0x0a of the EEPROM */
#define EEPROM_WORD0A_ILOS 0x0010 #define EEPROM_WORD0A_ILOS 0x0010
...@@ -1409,7 +1524,9 @@ struct e1000_hw { ...@@ -1409,7 +1524,9 @@ struct e1000_hw {
/* PBA constants */ /* PBA constants */
#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_24K 0x0018 #define E1000_PBA_24K 0x0018
#define E1000_PBA_30K 0x001E
#define E1000_PBA_40K 0x0028 #define E1000_PBA_40K 0x0028
#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */ #define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
...@@ -1547,6 +1664,29 @@ struct e1000_hw { ...@@ -1547,6 +1664,29 @@ struct e1000_hw {
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */ #define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */ #define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */
#define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* PHY Specific Control Register */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */
#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */
#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */
/* IGP01E1000 AGC Registers - stores the cable length values*/
#define IGP01E1000_PHY_AGC_A 0x1172
#define IGP01E1000_PHY_AGC_B 0x1272
#define IGP01E1000_PHY_AGC_C 0x1472
#define IGP01E1000_PHY_AGC_D 0x1872
/* Number of AGC registers */
#define IGP01E1000_PHY_AGC_NUM 4
/* IGP01E1000 PCS Initialization register - stores the polarity status when
* speed = 1000 Mbps. */
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ #define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
/* PHY Control Register */ /* PHY Control Register */
...@@ -1712,6 +1852,7 @@ struct e1000_hw { ...@@ -1712,6 +1852,7 @@ struct e1000_hw {
/* M88E1000 PHY Specific Status Register */ /* M88E1000 PHY Specific Status Register */
#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */ #define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */
#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */ #define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */
#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */ #define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
#define M88E1000_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M; #define M88E1000_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M;
* 3=110-140M;4=>140M */ * 3=110-140M;4=>140M */
...@@ -1725,6 +1866,7 @@ struct e1000_hw { ...@@ -1725,6 +1866,7 @@ struct e1000_hw {
#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ #define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
#define M88E1000_PSSR_REV_POLARITY_SHIFT 1 #define M88E1000_PSSR_REV_POLARITY_SHIFT 1
#define M88E1000_PSSR_DOWNSHIFT_SHIFT 5
#define M88E1000_PSSR_MDIX_SHIFT 6 #define M88E1000_PSSR_MDIX_SHIFT 6
#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7 #define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
...@@ -1753,10 +1895,93 @@ struct e1000_hw { ...@@ -1753,10 +1895,93 @@ struct e1000_hw {
#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */ #define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */ #define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
/* IGP01E1000 Specific Port Config Register - R/W */
#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT 0x0010
#define IGP01E1000_PSCFR_PRE_EN 0x0020
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK 0x0100
#define IGP01E1000_PSCFR_DISABLE_JABBER 0x0400
#define IGP01E1000_PSCFR_DISABLE_TRANSMIT 0x2000
/* IGP01E1000 Specific Port Status Register - R/O */
#define IGP01E1000_PSSR_AUTONEG_FAILED 0x0001 /* RO LH SC */
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
#define IGP01E1000_PSSR_CABLE_LENGTH 0x007C
#define IGP01E1000_PSSR_FULL_DUPLEX 0x0200
#define IGP01E1000_PSSR_LINK_UP 0x0400
#define IGP01E1000_PSSR_MDIX 0x0800
#define IGP01E1000_PSSR_SPEED_MASK 0xC000 /* speed bits mask */
#define IGP01E1000_PSSR_SPEED_10MBPS 0x4000
#define IGP01E1000_PSSR_SPEED_100MBPS 0x8000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP01E1000_PSSR_CABLE_LENGTH_SHIFT 0x0002 /* shift right 2 */
#define IGP01E1000_PSSR_MDIX_SHIFT 0x000B /* shift right 11 */
/* IGP01E1000 Specific Port Control Register - R/W */
#define IGP01E1000_PSCR_TP_LOOPBACK 0x0001
#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR 0x0200
#define IGP01E1000_PSCR_TEN_CRS_SELECT 0x0400
#define IGP01E1000_PSCR_FLIP_CHIP 0x0800
#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0-MDI, 1-MDIX */
/* IGP01E1000 Specific Port Link Health Register */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR 0x4000
#define IGP01E1000_PLHR_GIG_REM_RCVR_NOK 0x0800 /* LH */
#define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW 0x0400 /* LH */
#define IGP01E1000_PLHR_DATA_ERR_1 0x0200 /* LH */
#define IGP01E1000_PLHR_DATA_ERR_0 0x0100
#define IGP01E1000_PLHR_AUTONEG_FAULT 0x0010
#define IGP01E1000_PLHR_AUTONEG_ACTIVE 0x0008
#define IGP01E1000_PLHR_VALID_CHANNEL_D 0x0004
#define IGP01E1000_PLHR_VALID_CHANNEL_C 0x0002
#define IGP01E1000_PLHR_VALID_CHANNEL_B 0x0001
#define IGP01E1000_PLHR_VALID_CHANNEL_A 0x0000
/* IGP01E1000 Channel Quality Register */
#define IGP01E1000_MSE_CHANNEL_D 0x000F
#define IGP01E1000_MSE_CHANNEL_C 0x00F0
#define IGP01E1000_MSE_CHANNEL_B 0x0F00
#define IGP01E1000_MSE_CHANNEL_A 0xF000
/* IGP01E1000 AGC Registers */
#define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */
/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
/* The precision of the length is +/- 10 meters */
#define IGP01E1000_AGC_RANGE 10
/* IGP cable length table */
static const
uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
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};
/* IGP01E1000 PCS Initialization register */
/* bits 3:6 in the PCS registers stores the channels polarity */
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
/* IGP01E1000 GMII FIFO Register */
#define IGP01E1000_GMII_FLEX_SPD 0x10 /* Enable flexible speed
* on Link-Up */
#define IGP01E1000_GMII_SPD 0x20 /* Enable SPD */
/* Bit definitions for valid PHY IDs. */ /* Bit definitions for valid PHY IDs. */
#define M88E1000_E_PHY_ID 0x01410C50 #define M88E1000_E_PHY_ID 0x01410C50
#define M88E1000_I_PHY_ID 0x01410C30 #define M88E1000_I_PHY_ID 0x01410C30
#define M88E1011_I_PHY_ID 0x01410C20 #define M88E1011_I_PHY_ID 0x01410C20
#define IGP01E1000_I_PHY_ID 0x02A80380
#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
......
...@@ -106,6 +106,8 @@ static struct pci_device_id e1000_pci_tbl[] __devinitdata = { ...@@ -106,6 +106,8 @@ static struct pci_device_id e1000_pci_tbl[] __devinitdata = {
{0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
/* required last entry */ /* required last entry */
{0,} {0,}
}; };
...@@ -144,6 +146,7 @@ static void e1000_free_rx_resources(struct e1000_adapter *adapter); ...@@ -144,6 +146,7 @@ static void e1000_free_rx_resources(struct e1000_adapter *adapter);
static void e1000_set_multi(struct net_device *netdev); static void e1000_set_multi(struct net_device *netdev);
static void e1000_update_phy_info(unsigned long data); static void e1000_update_phy_info(unsigned long data);
static void e1000_watchdog(unsigned long data); static void e1000_watchdog(unsigned long data);
static void e1000_82547_tx_fifo_stall(unsigned long data);
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev); static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
static struct net_device_stats * e1000_get_stats(struct net_device *netdev); static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
static int e1000_change_mtu(struct net_device *netdev, int new_mtu); static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
...@@ -167,6 +170,9 @@ static inline void e1000_rx_checksum(struct e1000_adapter *adapter, ...@@ -167,6 +170,9 @@ static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
struct sk_buff *skb); struct sk_buff *skb);
static void e1000_tx_timeout(struct net_device *dev); static void e1000_tx_timeout(struct net_device *dev);
static void e1000_tx_timeout_task(struct net_device *dev); static void e1000_tx_timeout_task(struct net_device *dev);
static void e1000_smartspeed(struct e1000_adapter *adapter);
static inline int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
struct sk_buff *skb);
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
...@@ -284,6 +290,7 @@ e1000_down(struct e1000_adapter *adapter) ...@@ -284,6 +290,7 @@ e1000_down(struct e1000_adapter *adapter)
e1000_irq_disable(adapter); e1000_irq_disable(adapter);
free_irq(netdev->irq, netdev); free_irq(netdev->irq, netdev);
del_timer_sync(&adapter->tx_fifo_stall_timer);
del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_info_timer); del_timer_sync(&adapter->phy_info_timer);
adapter->link_speed = 0; adapter->link_speed = 0;
...@@ -299,14 +306,28 @@ e1000_down(struct e1000_adapter *adapter) ...@@ -299,14 +306,28 @@ e1000_down(struct e1000_adapter *adapter)
void void
e1000_reset(struct e1000_adapter *adapter) e1000_reset(struct e1000_adapter *adapter)
{ {
uint32_t pba;
/* 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->rx_buffer_len > E1000_RXBUFFER_8192) if(adapter->hw.mac_type < e1000_82547) {
E1000_WRITE_REG(&adapter->hw, PBA, E1000_JUMBO_PBA); if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
else pba = E1000_PBA_40K;
E1000_WRITE_REG(&adapter->hw, PBA, E1000_DEFAULT_PBA); else
pba = E1000_PBA_48K;
} else {
if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
pba = E1000_PBA_22K;
else
pba = E1000_PBA_30K;
adapter->tx_fifo_head = 0;
adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
adapter->tx_fifo_size =
(E1000_PBA_40K - pba) << E1000_TX_FIFO_SIZE_SHIFT;
atomic_set(&adapter->tx_fifo_stall, 0);
}
E1000_WRITE_REG(&adapter->hw, PBA, pba);
adapter->hw.fc = adapter->hw.original_fc; adapter->hw.fc = adapter->hw.original_fc;
e1000_reset_hw(&adapter->hw); e1000_reset_hw(&adapter->hw);
...@@ -397,11 +418,11 @@ e1000_probe(struct pci_dev *pdev, ...@@ -397,11 +418,11 @@ e1000_probe(struct pci_dev *pdev,
netdev->change_mtu = &e1000_change_mtu; netdev->change_mtu = &e1000_change_mtu;
netdev->do_ioctl = &e1000_ioctl; netdev->do_ioctl = &e1000_ioctl;
netdev->tx_timeout = &e1000_tx_timeout; netdev->tx_timeout = &e1000_tx_timeout;
netdev->watchdog_timeo = HZ;
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
netdev->poll = &e1000_poll; netdev->poll = &e1000_poll;
netdev->weight = 64; netdev->weight = 64;
#endif #endif
netdev->watchdog_timeo = 5 * HZ;
netdev->vlan_rx_register = e1000_vlan_rx_register; netdev->vlan_rx_register = e1000_vlan_rx_register;
netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid; netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid; netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
...@@ -421,17 +442,18 @@ e1000_probe(struct pci_dev *pdev, ...@@ -421,17 +442,18 @@ e1000_probe(struct pci_dev *pdev,
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 |
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER; NETIF_F_HW_VLAN_FILTER;
} else { } else {
netdev->features = NETIF_F_SG; netdev->features = NETIF_F_SG;
} }
if(adapter->hw.mac_type >= e1000_82544) if((adapter->hw.mac_type >= e1000_82544) &&
(adapter->hw.mac_type != e1000_82547))
netdev->features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO;
if(pci_using_dac) if(pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA; netdev->features |= NETIF_F_HIGHDMA;
...@@ -461,6 +483,9 @@ e1000_probe(struct pci_dev *pdev, ...@@ -461,6 +483,9 @@ e1000_probe(struct pci_dev *pdev,
else else
adapter->max_data_per_txd = MAX_JUMBO_FRAME_SIZE; adapter->max_data_per_txd = MAX_JUMBO_FRAME_SIZE;
init_timer(&adapter->tx_fifo_stall_timer);
adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
adapter->tx_fifo_stall_timer.data = (unsigned long) adapter;
init_timer(&adapter->watchdog_timer); init_timer(&adapter->watchdog_timer);
adapter->watchdog_timer.function = &e1000_watchdog; adapter->watchdog_timer.function = &e1000_watchdog;
...@@ -490,11 +515,12 @@ e1000_probe(struct pci_dev *pdev, ...@@ -490,11 +515,12 @@ e1000_probe(struct pci_dev *pdev,
* enable the ACPI Magic Packet filter * enable the ACPI Magic Packet filter
*/ */
e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data); e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG,1, &eeprom_data);
if((adapter->hw.mac_type >= e1000_82544) && if((adapter->hw.mac_type >= e1000_82544) &&
(eeprom_data & E1000_EEPROM_APME)) (eeprom_data & E1000_EEPROM_APME))
adapter->wol |= E1000_WUFC_MAG; adapter->wol |= E1000_WUFC_MAG;
/* reset the hardware with the new settings */ /* reset the hardware with the new settings */
e1000_reset(adapter); e1000_reset(adapter);
...@@ -586,6 +612,10 @@ e1000_sw_init(struct e1000_adapter *adapter) ...@@ -586,6 +612,10 @@ e1000_sw_init(struct e1000_adapter *adapter)
return -1; return -1;
} }
/* initialize eeprom parameters */
e1000_init_eeprom_params(hw);
/* flow control settings */ /* flow control settings */
hw->fc_high_water = E1000_FC_HIGH_THRESH; hw->fc_high_water = E1000_FC_HIGH_THRESH;
...@@ -593,6 +623,9 @@ e1000_sw_init(struct e1000_adapter *adapter) ...@@ -593,6 +623,9 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw->fc_pause_time = E1000_FC_PAUSE_TIME; hw->fc_pause_time = E1000_FC_PAUSE_TIME;
hw->fc_send_xon = 1; hw->fc_send_xon = 1;
if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547))
hw->phy_init_script = 1;
/* Media type - copper or fiber */ /* Media type - copper or fiber */
if(hw->mac_type >= e1000_82543) { if(hw->mac_type >= e1000_82543) {
...@@ -1192,9 +1225,9 @@ e1000_set_multi(struct net_device *netdev) ...@@ -1192,9 +1225,9 @@ e1000_set_multi(struct net_device *netdev)
if(hw->mac_type == e1000_82542_rev2_0) if(hw->mac_type == e1000_82542_rev2_0)
e1000_enter_82542_rst(adapter); e1000_enter_82542_rst(adapter);
/* load the first 15 multicast address into the exact filters 1-15 /* load the first 14 multicast address into the exact filters 1-14
* RAR 0 is used for the station MAC adddress * RAR 0 is used for the station MAC adddress
* if there are not 15 addresses, go ahead and clear the filters * if there are not 14 addresses, go ahead and clear the filters
*/ */
mc_ptr = netdev->mc_list; mc_ptr = netdev->mc_list;
...@@ -1234,6 +1267,48 @@ e1000_update_phy_info(unsigned long data) ...@@ -1234,6 +1267,48 @@ e1000_update_phy_info(unsigned long data)
e1000_phy_get_info(&adapter->hw, &adapter->phy_info); e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
} }
/**
* e1000_82547_tx_fifo_stall - Timer Call-back
* @data: pointer to adapter cast into an unsigned long
**/
static void
e1000_82547_tx_fifo_stall(unsigned long data)
{
struct e1000_adapter *adapter = (struct e1000_adapter *) data;
struct net_device *netdev = adapter->netdev;
uint32_t tctl;
if(atomic_read(&adapter->tx_fifo_stall)) {
if((E1000_READ_REG(&adapter->hw, TDT) ==
E1000_READ_REG(&adapter->hw, TDH)) &&
(E1000_READ_REG(&adapter->hw, TDFT) ==
E1000_READ_REG(&adapter->hw, TDFH)) &&
(E1000_READ_REG(&adapter->hw, TDFTS) ==
E1000_READ_REG(&adapter->hw, TDFHS))) {
tctl = E1000_READ_REG(&adapter->hw, TCTL);
E1000_WRITE_REG(&adapter->hw, TCTL,
tctl & ~E1000_TCTL_EN);
E1000_WRITE_REG(&adapter->hw, TDFT,
adapter->tx_head_addr);
E1000_WRITE_REG(&adapter->hw, TDFH,
adapter->tx_head_addr);
E1000_WRITE_REG(&adapter->hw, TDFTS,
adapter->tx_head_addr);
E1000_WRITE_REG(&adapter->hw, TDFHS,
adapter->tx_head_addr);
E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
E1000_WRITE_FLUSH(&adapter->hw);
adapter->tx_fifo_head = 0;
atomic_set(&adapter->tx_fifo_stall, 0);
netif_wake_queue(netdev);
} else {
mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
}
}
}
/** /**
* e1000_watchdog - Timer Call-back * e1000_watchdog - Timer Call-back
* @data: pointer to netdev cast into an unsigned long * @data: pointer to netdev cast into an unsigned long
...@@ -1264,6 +1339,7 @@ e1000_watchdog(unsigned long data) ...@@ -1264,6 +1339,7 @@ e1000_watchdog(unsigned long data)
netif_carrier_on(netdev); netif_carrier_on(netdev);
netif_wake_queue(netdev); netif_wake_queue(netdev);
mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
adapter->smartspeed = 0;
} }
} else { } else {
if(netif_carrier_ok(netdev)) { if(netif_carrier_ok(netdev)) {
...@@ -1276,6 +1352,8 @@ e1000_watchdog(unsigned long data) ...@@ -1276,6 +1352,8 @@ e1000_watchdog(unsigned long data)
netif_stop_queue(netdev); netif_stop_queue(netdev);
mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
} }
e1000_smartspeed(adapter);
} }
e1000_update_stats(adapter); e1000_update_stats(adapter);
...@@ -1501,6 +1579,49 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags) ...@@ -1501,6 +1579,49 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
} }
#define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0)) #define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0))
/**
* 82547 workaround to avoid controller hang in half-duplex environment.
* The workaround is to avoid queuing a large packet that would span
* the internal Tx FIFO ring boundary by notifying the stack to resend
* the packet at a later time. This gives the Tx FIFO an opportunity to
* flush all packets. When that occurs, we reset the Tx FIFO pointers
* to the beginning of the Tx FIFO.
**/
#define E1000_FIFO_HDR 0x10
#define E1000_82547_PAD_LEN 0x3E0
static inline int
e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb)
{
uint32_t fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
uint32_t skb_fifo_len = skb->len + E1000_FIFO_HDR;
E1000_ROUNDUP(skb_fifo_len, E1000_FIFO_HDR);
if(adapter->link_duplex != HALF_DUPLEX)
goto no_fifo_stall_required;
if(atomic_read(&adapter->tx_fifo_stall))
return 1;
if(skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
atomic_set(&adapter->tx_fifo_stall, 1);
return 1;
}
no_fifo_stall_required:
adapter->tx_fifo_head += skb_fifo_len;
if(adapter->tx_fifo_head >= adapter->tx_fifo_size)
adapter->tx_fifo_head -= adapter->tx_fifo_size;
return 0;
}
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) (((S) >> E1000_MAX_TXD_PWR) + \
(((S) & (E1000_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
#define DESC_NEEDED TXD_USE_COUNT(MAX_JUMBO_FRAME_SIZE) + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 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)
...@@ -1528,6 +1649,14 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -1528,6 +1649,14 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return 1; return 1;
} }
if(adapter->hw.mac_type == e1000_82547) {
if(e1000_82547_fifo_workaround(adapter, skb)) {
netif_stop_queue(netdev);
mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
return 1;
}
}
if(adapter->vlgrp && vlan_tx_tag_present(skb)) { if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= E1000_TX_FLAGS_VLAN; tx_flags |= E1000_TX_FLAGS_VLAN;
tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
...@@ -2222,6 +2351,61 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter) ...@@ -2222,6 +2351,61 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
rx_ring->next_to_use = i; rx_ring->next_to_use = i;
} }
/**
* e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
* @adapter:
**/
static void
e1000_smartspeed(struct e1000_adapter *adapter)
{
uint16_t phy_status;
uint16_t phy_ctrl;
if((adapter->hw.phy_type != e1000_phy_igp) || !adapter->hw.autoneg ||
!(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL))
return;
if(adapter->smartspeed == 0) {
/* If Master/Slave config fault is asserted twice,
* we assume back-to-back */
e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
if(phy_ctrl & CR_1000T_MS_ENABLE) {
phy_ctrl &= ~CR_1000T_MS_ENABLE;
e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL,
phy_ctrl);
adapter->smartspeed++;
if(!e1000_phy_setup_autoneg(&adapter->hw) &&
!e1000_read_phy_reg(&adapter->hw, PHY_CTRL,
&phy_ctrl)) {
phy_ctrl |= (MII_CR_AUTO_NEG_EN |
MII_CR_RESTART_AUTO_NEG);
e1000_write_phy_reg(&adapter->hw, PHY_CTRL,
phy_ctrl);
}
}
return;
} else if(adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
/* If still no link, perhaps using 2/3 pair cable */
e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
phy_ctrl |= CR_1000T_MS_ENABLE;
e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_ctrl);
if(!e1000_phy_setup_autoneg(&adapter->hw) &&
!e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_ctrl)) {
phy_ctrl |= (MII_CR_AUTO_NEG_EN |
MII_CR_RESTART_AUTO_NEG);
e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_ctrl);
}
}
/* Restart process after E1000_SMARTSPEED_MAX iterations */
if(adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
adapter->smartspeed = 0;
}
/** /**
* e1000_ioctl - * e1000_ioctl -
* @netdev: * @netdev:
......
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