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
82544 PRO/1000 XF Server Adapter A50484-xxx
82544 PRO/1000 T Desktop Adapter A62947-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
82546 PRO/1000 MT Dual Port Server Adapter A92111-xxx
82545 PRO/1000 MF Server Adapter A91622-xxx
......
......@@ -95,6 +95,15 @@ struct e1000_adapter;
#define E1000_RXBUFFER_8192 8192
#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 */
#define E1000_FC_HIGH_THRESH 0xA9C8
......@@ -109,9 +118,6 @@ struct e1000_adapter;
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define E1000_RX_BUFFER_WRITE 16
#define E1000_JUMBO_PBA 0x00000028
#define E1000_DEFAULT_PBA 0x00000030
#define AUTO_ALL_MODES 0
#define E1000_EEPROM_APME 4
......@@ -155,6 +161,7 @@ struct e1000_desc_ring {
/* board specific private data structure */
struct e1000_adapter {
struct timer_list tx_fifo_stall_timer;
struct timer_list watchdog_timer;
struct timer_list phy_info_timer;
struct vlan_group *vlgrp;
......@@ -163,6 +170,7 @@ struct e1000_adapter {
uint32_t rx_buffer_len;
uint32_t part_num;
uint32_t wol;
uint32_t smartspeed;
uint16_t link_speed;
uint16_t link_duplex;
spinlock_t stats_lock;
......@@ -178,6 +186,10 @@ struct e1000_adapter {
uint32_t tx_int_delay;
uint32_t tx_abs_int_delay;
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 */
struct e1000_desc_ring rx_ring;
......
......@@ -145,16 +145,6 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
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
e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
struct ethtool_drvinfo *drvinfo)
......@@ -166,7 +156,7 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
drvinfo->n_stats = E1000_STATS_LEN;
#define E1000_REGS_LEN 32
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
......@@ -200,9 +190,8 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
{
struct e1000_hw *hw = &adapter->hw;
int max_len, first_word, last_word;
int first_word, last_word;
int ret_val = 0;
int i;
if(eeprom->len == 0) {
ret_val = -EINVAL;
......@@ -211,22 +200,28 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
max_len = e1000_eeprom_size(hw);
if(eeprom->offset > eeprom->offset + eeprom->len) {
ret_val = -EINVAL;
goto geeprom_error;
}
if((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
if((eeprom->offset + eeprom->len) > (hw->eeprom.word_size * 2))
eeprom->len = ((hw->eeprom.word_size * 2) - eeprom->offset);
first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
for(i = 0; i <= (last_word - first_word); i++)
e1000_read_eeprom(hw, first_word + i, &eeprom_buff[i]);
if(hw->eeprom.type == e1000_eeprom_spi)
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:
return ret_val;
}
......@@ -237,9 +232,8 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
{
struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff;
int max_len, first_word, last_word;
void *ptr;
int i;
int max_len, first_word, last_word, ret_val = 0;
if(eeprom->len == 0)
return -EOPNOTSUPP;
......@@ -247,7 +241,7 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT;
max_len = e1000_eeprom_size(hw);
max_len = hw->eeprom.word_size * 2;
if((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
......@@ -263,30 +257,31 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if(eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */
/* 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++;
}
if((eeprom->offset + eeprom->len) & 1) {
if(((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
/* need read/modify/write of last changed EEPROM word */
/* 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]);
}
if(copy_from_user(ptr, user_data, eeprom->len)) {
kfree(eeprom_buff);
return -EFAULT;
if((ret_val != 0) || copy_from_user(ptr, user_data, eeprom->len)) {
ret_val = -EFAULT;
goto seeprom_error;
}
for(i = 0; i <= (last_word - first_word); i++)
e1000_write_eeprom(hw, first_word + i, eeprom_buff[i]);
ret_val = e1000_write_eeprom(hw, first_word,
last_word - first_word + 1, eeprom_buff);
/* 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);
seeprom_error:
kfree(eeprom_buff);
return 0;
return ret_val;
}
static void
......
......@@ -32,6 +32,8 @@
#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_copper_link(struct e1000_hw *hw);
static int32_t e1000_phy_force_speed_duplex(struct e1000_hw *hw);
......@@ -42,16 +44,100 @@ 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 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_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_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 uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw);
static void e1000_setup_eeprom(struct e1000_hw *hw);
static void e1000_clock_eeprom(struct e1000_hw *hw);
static void e1000_cleanup_eeprom(struct e1000_hw *hw);
static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count);
static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
static void e1000_release_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);
/******************************************************************************
* 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.
*
......@@ -101,10 +187,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82546EB_FIBER:
hw->mac_type = e1000_82546;
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:
/* Should never have loaded on this device */
return -E1000_ERR_MAC_TYPE;
}
return E1000_SUCCESS;
}
/******************************************************************************
......@@ -119,6 +214,7 @@ e1000_reset_hw(struct e1000_hw *hw)
uint32_t ctrl_ext;
uint32_t icr;
uint32_t manc;
uint32_t led_ctrl;
DEBUGFUNC("e1000_reset_hw");
......@@ -156,6 +252,12 @@ e1000_reset_hw(struct e1000_hw *hw)
DEBUGOUT("Issuing a global reset to MAC\n");
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)
E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
else
......@@ -173,13 +275,25 @@ e1000_reset_hw(struct e1000_hw *hw)
msec_delay(2);
} else {
/* Wait for EEPROM reload (it happens automatically) */
msec_delay(4);
msec_delay(5);
/* Dissable HW ARPs on ASF enabled adapters */
manc = E1000_READ_REG(hw, MANC);
manc &= ~(E1000_MANC_ARP_EN);
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 */
DEBUGOUT("Masking off all interrupts\n");
E1000_WRITE_REG(hw, IMC, 0xffffffff);
......@@ -353,7 +467,7 @@ e1000_setup_link(struct e1000_hw *hw)
* control setting, then the variable hw->fc will
* 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");
return -E1000_ERR_EEPROM;
}
......@@ -574,7 +688,7 @@ e1000_setup_fiber_link(struct e1000_hw *hw)
static int32_t
e1000_setup_copper_link(struct e1000_hw *hw)
{
uint32_t ctrl;
uint32_t ctrl, led_ctrl;
int32_t ret_val;
uint16_t i;
uint16_t phy_data;
......@@ -604,6 +718,69 @@ e1000_setup_copper_link(struct e1000_hw *hw)
}
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. */
if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
......@@ -677,6 +854,7 @@ e1000_setup_copper_link(struct e1000_hw *hw)
DEBUGOUT("Error Resetting the PHY\n");
return ret_val;
}
}
/* Options:
* autoneg = 1 (default)
......@@ -736,6 +914,7 @@ e1000_setup_copper_link(struct e1000_hw *hw)
return ret_val;
}
}
hw->get_link_status = TRUE;
} else {
DEBUGOUT("Forcing speed and duplex\n");
ret_val = e1000_phy_force_speed_duplex(hw);
......@@ -1014,6 +1193,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
/* Write the configured values back to the Device Control Reg. */
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) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
......@@ -1031,6 +1211,23 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
/* Need to reset the PHY or these changes will be ignored */
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. */
if(e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg) < 0) {
......@@ -1094,6 +1291,7 @@ 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
* Extended PHY Specific Control Register to 25MHz clock. This value
* 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)
DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY;
}
}
return 0;
}
......@@ -1136,6 +1335,8 @@ e1000_config_collision_dist(struct e1000_hw *hw)
{
uint32_t tctl;
DEBUGFUNC("e1000_config_collision_dist");
tctl = E1000_READ_REG(hw, TCTL);
tctl &= ~E1000_TCTL_COLD;
......@@ -1172,6 +1373,26 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
/* Set up duplex in the Device Control and Transmit Control
* 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) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
......@@ -1188,6 +1409,7 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
ctrl |= E1000_CTRL_SPD_1000;
else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
ctrl |= E1000_CTRL_SPD_100;
}
/* Write the configured values back to the Device Control Reg. */
E1000_WRITE_REG(hw, CTRL, ctrl);
return 0;
......@@ -1519,6 +1741,10 @@ e1000_check_for_link(struct e1000_hw *hw)
if(phy_data & MII_SR_LINK_STATUS) {
hw->get_link_status = FALSE;
/* Check if there was DownShift, must be checked immediately after
* link-up */
e1000_check_downshift(hw);
} else {
/* No link detected */
return 0;
......@@ -2021,8 +2247,7 @@ e1000_write_phy_reg(struct e1000_hw *hw,
void
e1000_phy_hw_reset(struct e1000_hw *hw)
{
uint32_t ctrl;
uint32_t ctrl_ext;
uint32_t ctrl, ctrl_ext, led_ctrl;
DEBUGFUNC("e1000_phy_hw_reset");
......@@ -2053,6 +2278,21 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
E1000_WRITE_FLUSH(hw);
}
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)
return -E1000_ERR_PHY;
}
udelay(1);
if (hw->phy_type == e1000_phy_igp) {
e1000_phy_init_script(hw);
}
return 0;
}
......@@ -2092,6 +2335,7 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
{
uint16_t phy_id_high, phy_id_low;
boolean_t match = FALSE;
int32_t phy_init_status;
DEBUGFUNC("e1000_detect_gig_phy");
......@@ -2101,7 +2345,7 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
return -E1000_ERR_PHY;
}
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) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
......@@ -2121,11 +2365,17 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
case e1000_82546:
if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
break;
case e1000_82541:
case e1000_82547:
if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
break;
default:
DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
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);
return 0;
}
......@@ -2156,43 +2406,93 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
}
/******************************************************************************
* Get PHY information from various PHY registers
* 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_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
{
int32_t ret_val = -E1000_ERR_PHY;
uint16_t phy_data;
uint16_t phy_data, polarity, min_length, max_length, average;
DEBUGFUNC("e1000_phy_get_info");
DEBUGFUNC("e1000_phy_igp_get_info");
phy_info->cable_length = e1000_cable_length_undefined;
phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
phy_info->cable_polarity = e1000_rev_polarity_undefined;
phy_info->polarity_correction = e1000_polarity_reversal_undefined;
phy_info->mdix_mode = e1000_auto_x_mode_undefined;
phy_info->local_rx = e1000_1000t_rx_status_undefined;
phy_info->remote_rx = e1000_1000t_rx_status_undefined;
/* 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(hw->media_type != e1000_media_type_copper) {
DEBUGOUT("PHY info is only valid for copper media\n");
return -E1000_ERR_CONFIG;
}
/* IGP01E1000 does not need to support it. */
phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
do {
if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) break;
if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) break;
if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
DEBUGOUT("PHY info is only valid if link is up\n");
return -E1000_ERR_CONFIG;
/* 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)
break;
return -E1000_ERR_PHY;
phy_info->extended_10bt_distance =
(phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
......@@ -2200,30 +2500,83 @@ e1000_phy_get_info(struct e1000_hw *hw,
(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)
break;
phy_info->cable_polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
M88E1000_PSSR_REV_POLARITY_SHIFT;
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)
break;
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;
}
ret_val = 0;
} while(0);
if(ret_val < 0) DEBUGOUT("PHY Read Error\n");
return ret_val;
return E1000_SUCCESS;
}
/******************************************************************************
* Get PHY information from various PHY registers
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
int32_t
e1000_phy_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
{
uint16_t phy_data;
DEBUGFUNC("e1000_phy_get_info");
phy_info->cable_length = e1000_cable_length_undefined;
phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_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->mdix_mode = e1000_auto_x_mode_undefined;
phy_info->local_rx = e1000_1000t_rx_status_undefined;
phy_info->remote_rx = e1000_1000t_rx_status_undefined;
if(hw->media_type != e1000_media_type_copper) {
DEBUGOUT("PHY info is only valid for copper media\n");
return -E1000_ERR_CONFIG;
}
if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
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");
return -E1000_ERR_CONFIG;
}
if (hw->phy_type == e1000_phy_igp)
return e1000_phy_igp_get_info(hw, phy_info);
else
return e1000_phy_m88_get_info(hw, phy_info);
}
int32_t
......@@ -2239,23 +2592,126 @@ e1000_validate_mdi_setting(struct e1000_hw *hw)
return 0;
}
/******************************************************************************
* Raises the EEPROM's clock input.
* Sets up eeprom variables in the hw struct. Must be called after mac_type
* is configured.
*
* hw - Struct containing variables accessed by shared code
* eecd - EECD's current value
*****************************************************************************/
static void
e1000_raise_ee_clk(struct e1000_hw *hw,
uint32_t *eecd)
void
e1000_init_eeprom_params(struct e1000_hw *hw)
{
/* Raise the clock input to the EEPROM (by setting the SK bit), and then
* wait <delay> microseconds.
*/
*eecd = *eecd | E1000_EECD_SK;
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.
*
* hw - Struct containing variables accessed by shared code
* eecd - EECD's current value
*****************************************************************************/
static void
e1000_raise_ee_clk(struct e1000_hw *hw,
uint32_t *eecd)
{
/* Raise the clock input to the EEPROM (by setting the SK bit), and then
* wait <delay> microseconds.
*/
*eecd = *eecd | E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
udelay(hw->eeprom.delay_usec);
}
/******************************************************************************
......@@ -2274,7 +2730,7 @@ e1000_lower_ee_clk(struct e1000_hw *hw,
*eecd = *eecd & ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
udelay(hw->eeprom.delay_usec);
}
/******************************************************************************
......@@ -2289,6 +2745,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
uint16_t data,
uint16_t count)
{
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd;
uint32_t mask;
......@@ -2298,7 +2755,11 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
*/
mask = 0x01 << (count - 1);
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 {
/* 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
......@@ -2313,7 +2774,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
udelay(eeprom->delay_usec);
e1000_raise_ee_clk(hw, &eecd);
e1000_lower_ee_clk(hw, &eecd);
......@@ -2333,7 +2794,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
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 i;
......@@ -2351,7 +2812,7 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw)
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
data = 0;
for(i = 0; i < 16; i++) {
for(i = 0; i < count; i++) {
data = data << 1;
e1000_raise_ee_clk(hw, &eecd);
......@@ -2375,20 +2836,53 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw)
* Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
* function should be called before issuing a command to the EEPROM.
*****************************************************************************/
static void
e1000_setup_eeprom(struct e1000_hw *hw)
static int32_t
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);
/* Request EEPROM Access */
if(hw->mac_type > e1000_82544) {
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;
}
}
/* Setup EEPROM for Read/Write */
if (eeprom->type == e1000_eeprom_microwire) {
/* Clear SK and DI */
eecd &= ~(E1000_EECD_SK | E1000_EECD_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;
}
/******************************************************************************
......@@ -2399,77 +2893,136 @@ e1000_setup_eeprom(struct e1000_hw *hw)
static void
e1000_standby_eeprom(struct e1000_hw *hw)
{
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd;
eecd = E1000_READ_REG(hw, EECD);
/* Deselct EEPROM */
if(eeprom->type == e1000_eeprom_microwire) {
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
udelay(eeprom->delay_usec);
/* Clock high */
eecd |= E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
udelay(eeprom->delay_usec);
/* Select EEPROM */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
udelay(eeprom->delay_usec);
/* Clock low */
eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
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
*****************************************************************************/
static void
e1000_clock_eeprom(struct e1000_hw *hw)
e1000_release_eeprom(struct e1000_hw *hw)
{
uint32_t eecd;
DEBUGFUNC("e1000_release_eeprom");
eecd = E1000_READ_REG(hw, EECD);
if (hw->eeprom.type == e1000_eeprom_spi) {
eecd |= E1000_EECD_CS; /* Pull CS high */
eecd &= ~E1000_EECD_SK; /* Lower SCK */
E1000_WRITE_REG(hw, EECD, eecd);
udelay(hw->eeprom.delay_usec);
} else if(hw->eeprom.type == e1000_eeprom_microwire) {
/* 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(50);
udelay(hw->eeprom.delay_usec);
/* Falling edge of clock */
eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
udelay(50);
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
*****************************************************************************/
static void
e1000_cleanup_eeprom(struct e1000_hw *hw)
int32_t
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;
e1000_clock_eeprom(hw);
} while(retry_count < EEPROM_MAX_RETRY_SPI);
/* 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;
}
/******************************************************************************
......@@ -2478,64 +3031,69 @@ e1000_cleanup_eeprom(struct e1000_hw *hw)
* hw - Struct containing variables accessed by shared code
* offset - offset of word in the EEPROM to read
* data - word read from the EEPROM
* words - number of words to read
*****************************************************************************/
int32_t
e1000_read_eeprom(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
uint16_t *data)
{
uint32_t eecd;
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t i = 0;
boolean_t large_eeprom = FALSE;
DEBUGFUNC("e1000_read_eeprom");
/* Request EEPROM Access */
if(hw->mac_type > e1000_82544) {
eecd = E1000_READ_REG(hw, EECD);
if(eecd & E1000_EECD_SIZE) large_eeprom = TRUE;
eecd |= E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
eecd = E1000_READ_REG(hw, EECD);
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");
/* A check for invalid values: offset too large, too many words, and not
* enough words.
*/
if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
(words == 0)) {
DEBUGOUT("\"words\" parameter out of bounds\n");
return -E1000_ERR_EEPROM;
}
}
/* 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) */
e1000_shift_out_ee_bits(hw, EEPROM_READ_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);
} else {
/* If we have a 64 word EEPROM, there are 6 address bits */
e1000_shift_out_ee_bits(hw, offset, 6);
}
if(eeprom->type == e1000_eeprom_spi) {
uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
/* Read the data */
*data = e1000_shift_in_ee_bits(hw);
if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
/* End this read operation */
e1000_standby_eeprom(hw);
/* Stop requesting EEPROM access */
if(hw->mac_type > e1000_82544) {
eecd = E1000_READ_REG(hw, EECD);
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
/* Some SPI eeproms use the 8th address bit embedded in the opcode */
if((eeprom->address_bits == 8) && (offset >= 128))
read_opcode |= EEPROM_A8_OPCODE_SPI;
/* 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;
}
......@@ -2557,7 +3115,7 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw)
DEBUGFUNC("e1000_validate_eeprom_checksum");
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");
return -E1000_ERR_EEPROM;
}
......@@ -2589,14 +3147,14 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
DEBUGFUNC("e1000_update_eeprom_checksum");
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");
return -E1000_ERR_EEPROM;
}
checksum += eeprom_data;
}
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");
return -E1000_ERR_EEPROM;
}
......@@ -2604,11 +3162,12 @@ 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
* 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
* EEPROM will most likely contain an invalid checksum.
......@@ -2616,69 +3175,157 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
int32_t
e1000_write_eeprom(struct e1000_hw *hw,
uint16_t offset,
uint16_t data)
uint16_t words,
uint16_t *data)
{
uint32_t eecd;
uint32_t i = 0;
struct e1000_eeprom_info *eeprom = &hw->eeprom;
int32_t status = 0;
boolean_t large_eeprom = FALSE;
DEBUGFUNC("e1000_write_eeprom");
/* Request EEPROM Access */
if(hw->mac_type > e1000_82544) {
eecd = E1000_READ_REG(hw, EECD);
if(eecd & E1000_EECD_SIZE) large_eeprom = TRUE;
eecd |= E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
eecd = E1000_READ_REG(hw, EECD);
while((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
i++;
udelay(5);
eecd = E1000_READ_REG(hw, EECD);
/* A check for invalid values: offset too large, too many words, and not
* enough words.
*/
if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
(words == 0)) {
DEBUGOUT("\"words\" parameter out of bounds\n");
return -E1000_ERR_EEPROM;
}
if(!(eecd & E1000_EECD_GNT)) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
DEBUGOUT("Could not acquire EEPROM grant\n");
/* Prepare the EEPROM for writing */
if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
return -E1000_ERR_EEPROM;
if(eeprom->type == e1000_eeprom_microwire)
status = e1000_write_eeprom_microwire(hw, offset, words, data);
else
status = e1000_write_eeprom_spi(hw, offset, words, data);
/* Done with writing */
e1000_release_eeprom(hw);
return status;
}
/******************************************************************************
* Writes a 16 bit word to a given offset in an SPI 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 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;
DEBUGFUNC("e1000_write_eeprom_spi");
while (widx < words) {
uint8_t write_opcode = EEPROM_WRITE_OPCODE_SPI;
if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
e1000_standby_eeprom(hw);
/* Send the WRITE ENABLE command (8 bit opcode ) */
e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
eeprom->opcode_bits);
e1000_standby_eeprom(hw);
/* Some SPI eeproms use the 8th address bit embedded in the opcode */
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;
}
}
}
/* Prepare the EEPROM for writing */
e1000_setup_eeprom(hw);
return E1000_SUCCESS;
}
/******************************************************************************
* 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;
DEBUGFUNC("e1000_write_eeprom_microwire");
/* Send the 9-bit (or 11-bit on large EEPROM) EWEN (write enable) command
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This puts the EEPROM
* into 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_EWEN_OPCODE, 5);
if(large_eeprom)
e1000_shift_out_ee_bits(hw, 0, 6);
else
e1000_shift_out_ee_bits(hw, 0, 4);
e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
(uint16_t)(eeprom->opcode_bits + 2));
e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
/* Prepare the EEPROM */
e1000_standby_eeprom(hw);
while (words_written < words) {
/* Send the Write command (3-bit opcode + addr) */
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);
else
/* If we have a 64 word EEPROM, there are 6 address bits */
e1000_shift_out_ee_bits(hw, offset, 6);
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, 16);
e1000_shift_out_ee_bits(hw, data[words_written], 16);
/* Toggle the CS line. This in effect tells to EEPROM to actually execute
* the command in question.
/* Toggle the CS line. This in effect tells the EEPROM to execute
* the previous command.
*/
e1000_standby_eeprom(hw);
/* Now read DO repeatedly until is high (equal to '1'). The EEEPROM will
/* 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.
*/
......@@ -2689,33 +3336,27 @@ e1000_write_eeprom(struct e1000_hw *hw,
}
if(i == 200) {
DEBUGOUT("EEPROM Write did not complete\n");
status = -E1000_ERR_EEPROM;
return -E1000_ERR_EEPROM;
}
/* Recover from write */
e1000_standby_eeprom(hw);
/* Send the 9-bit (or 11-bit on large EEPROM) EWDS (write disable) command
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This takes the EEPROM
* out of write/erase mode.
*/
e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5);
if(large_eeprom)
e1000_shift_out_ee_bits(hw, 0, 6);
else
e1000_shift_out_ee_bits(hw, 0, 4);
words_written++;
}
/* Done with writing */
e1000_cleanup_eeprom(hw);
/* 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));
/* Stop requesting EEPROM access */
if(hw->mac_type > e1000_82544) {
eecd = E1000_READ_REG(hw, EECD);
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
}
e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
return status;
return 0;
}
/******************************************************************************
......@@ -2734,7 +3375,7 @@ e1000_read_part_num(struct e1000_hw *hw,
DEBUGFUNC("e1000_read_part_num");
/* 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");
return -E1000_ERR_EEPROM;
}
......@@ -2742,7 +3383,7 @@ e1000_read_part_num(struct e1000_hw *hw,
*part_num = (uint32_t) (eeprom_data << 16);
/* 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");
return -E1000_ERR_EEPROM;
}
......@@ -2768,7 +3409,7 @@ e1000_read_mac_addr(struct e1000_hw * hw)
for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
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");
return -E1000_ERR_EEPROM;
}
......@@ -3068,7 +3709,7 @@ e1000_id_led_init(struct e1000_hw * hw)
hw->ledctl_mode1 = 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");
return -E1000_ERR_EEPROM;
}
......@@ -3155,6 +3796,9 @@ e1000_setup_led(struct e1000_hw *hw)
case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_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);
break;
default:
......@@ -3193,6 +3837,9 @@ e1000_cleanup_led(struct e1000_hw *hw)
case E1000_DEV_ID_82545EM_FIBER:
case E1000_DEV_ID_82546EB_COPPER:
case E1000_DEV_ID_82546EB_FIBER:
case E1000_DEV_ID_82541EI:
case E1000_DEV_ID_82541EP:
case E1000_DEV_ID_82547EI:
/* Restore LEDCTL settings */
E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
break;
......@@ -3244,6 +3891,9 @@ e1000_led_on(struct e1000_hw *hw)
case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_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);
break;
default:
......@@ -3294,6 +3944,9 @@ e1000_led_off(struct e1000_hw *hw)
case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_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);
break;
default:
......@@ -3608,3 +4261,221 @@ e1000_write_reg_io(struct e1000_hw *hw,
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 {
e1000_82540,
e1000_82545,
e1000_82546,
e1000_82541,
e1000_82547,
e1000_num_macs
} e1000_mac_type;
typedef enum {
e1000_eeprom_uninitialized = 0,
e1000_eeprom_spi,
e1000_eeprom_microwire,
e1000_num_eeprom_types
} e1000_eeprom_type;
/* Media Types */
typedef enum {
e1000_media_type_copper = 0,
......@@ -110,6 +119,27 @@ typedef enum {
e1000_cable_length_undefined = 0xFF
} 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 {
e1000_10bt_ext_dist_enable_normal = 0,
e1000_10bt_ext_dist_enable_lower,
......@@ -122,6 +152,12 @@ typedef enum {
e1000_rev_polarity_undefined = 0xFF
} e1000_rev_polarity;
typedef enum {
e1000_downshift_normal = 0,
e1000_downshift_activated,
e1000_downshift_undefined = 0xFF
} e1000_downshift;
typedef enum {
e1000_polarity_reversal_enabled = 0,
e1000_polarity_reversal_disabled,
......@@ -142,10 +178,17 @@ typedef enum {
e1000_1000t_rx_status_undefined = 0xFF
} e1000_1000t_rx_status;
typedef enum {
e1000_phy_m88 = 0,
e1000_phy_igp,
e1000_phy_undefined = 0xFF
} e1000_phy_type;
struct e1000_phy_info {
e1000_cable_length cable_length;
e1000_10bt_ext_dist_enable extended_10bt_distance;
e1000_rev_polarity cable_polarity;
e1000_downshift downshift;
e1000_polarity_reversal polarity_correction;
e1000_auto_x_mode mdix_mode;
e1000_1000t_rx_status local_rx;
......@@ -157,6 +200,15 @@ struct e1000_phy_stats {
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 */
......@@ -166,6 +218,7 @@ struct e1000_phy_stats {
#define E1000_ERR_CONFIG 3
#define E1000_ERR_PARAM 4
#define E1000_ERR_MAC_TYPE 5
#define E1000_ERR_PHY_TYPE 6
/* Function prototypes */
/* Initialization */
......@@ -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_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_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);
/* 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_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_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);
#define E1000_DEV_ID_82545EM_FIBER 0x1011
#define E1000_DEV_ID_82546EB_COPPER 0x1010
#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 ETH_LENGTH_OF_ADDRESS 6
......@@ -324,7 +386,7 @@ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
* reserve one of these spots for our directed address, allowing us room for
* E1000_RAR_ENTRIES - 1 multicast addresses.
*/
#define E1000_RAR_ENTRIES 16
#define E1000_RAR_ENTRIES 15
#define MIN_NUMBER_OF_DESCRIPTORS 8
#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
......@@ -537,6 +599,7 @@ struct e1000_ffvt_entry {
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - 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_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
......@@ -569,6 +632,11 @@ struct e1000_ffvt_entry {
#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - 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_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
......@@ -664,6 +732,7 @@ struct e1000_ffvt_entry {
#define E1000_82542_EECD E1000_EECD
#define E1000_82542_EERD E1000_EERD
#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
#define E1000_82542_FLA E1000_FLA
#define E1000_82542_MDIC E1000_MDIC
#define E1000_82542_FCAL E1000_FCAL
#define E1000_82542_FCAH E1000_FCAH
......@@ -705,6 +774,9 @@ struct e1000_ffvt_entry {
#define E1000_82542_RADV E1000_RADV
#define E1000_82542_RSRPD E1000_RSRPD
#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_TADV E1000_TADV
#define E1000_82542_TSPMT E1000_TSPMT
......@@ -777,6 +849,8 @@ struct e1000_ffvt_entry {
#define E1000_82542_WUPL E1000_WUPL
#define E1000_82542_WUPM E1000_WUPM
#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_FFVT E1000_FFVT
......@@ -846,12 +920,15 @@ struct e1000_hw_stats {
struct e1000_hw {
uint8_t *hw_addr;
e1000_mac_type mac_type;
e1000_phy_type phy_type;
uint32_t phy_init_script;
e1000_media_type media_type;
void *back;
e1000_fc_type fc;
e1000_bus_speed bus_speed;
e1000_bus_width bus_width;
e1000_bus_type bus_type;
struct e1000_eeprom_info eeprom;
uint32_t io_base;
uint32_t phy_id;
uint32_t phy_revision;
......@@ -891,6 +968,7 @@ struct e1000_hw {
uint8_t mac_addr[NODE_ADDRESS_SIZE];
uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
boolean_t disable_polarity_correction;
boolean_t speed_downgraded;
boolean_t get_link_status;
boolean_t tbi_compatibility_en;
boolean_t tbi_compatibility_on;
......@@ -971,10 +1049,16 @@ struct e1000_hw {
#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */
#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */
#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_GNT 0x00000080 /* EEPROM Access Grant */
#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 */
#define E1000_EERD_START 0x00000001 /* Start Read */
......@@ -984,6 +1068,13 @@ struct e1000_hw {
#define E1000_EERD_DATA_SHIFT 16
#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 */
#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */
#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
......@@ -1239,6 +1330,7 @@ struct e1000_hw {
#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
#define E1000_WUC_SPM 0x80000000 /* Enable SPM */
/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
......@@ -1302,18 +1394,40 @@ struct e1000_hw {
#define E1000_MDALIGN 4096
/* EEPROM Commands */
#define EEPROM_READ_OPCODE 0x6 /* EERPOM read opcode */
#define EEPROM_WRITE_OPCODE 0x5 /* EERPOM write opcode */
#define EEPROM_ERASE_OPCODE 0x7 /* EERPOM erase opcode */
#define EEPROM_EWEN_OPCODE 0x13 /* EERPOM erase/write enable */
#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */
/* EEPROM Commands - Microwire */
#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */
#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */
#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 */
#define EEPROM_COMPAT 0x0003
#define EEPROM_ID_LED_SETTINGS 0x0004
#define EEPROM_INIT_CONTROL1_REG 0x000A
#define EEPROM_INIT_CONTROL2_REG 0x000F
#define EEPROM_CFG 0x0012
#define EEPROM_FLASH_VERSION 0x0032
#define EEPROM_CHECKSUM_REG 0x003F
......@@ -1334,9 +1448,10 @@ struct e1000_hw {
#define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9
/* Mask bits for fields in Word 0x03 of the EEPROM */
#define EEPROM_COMPAT_SERVER 0x0400
#define EEPROM_COMPAT_CLIENT 0x0200
#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
#define IGP_ACTIVITY_LED_ENABLE 0x0300
#define IGP_LED3_MODE 0x07000000
/* Mask bits for fields in Word 0x0a of the EEPROM */
#define EEPROM_WORD0A_ILOS 0x0010
......@@ -1409,7 +1524,9 @@ struct e1000_hw {
/* PBA constants */
#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
#define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018
#define E1000_PBA_30K 0x001E
#define E1000_PBA_40K 0x0028
#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
......@@ -1547,6 +1664,29 @@ struct e1000_hw {
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
#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) */
/* PHY Control Register */
......@@ -1712,6 +1852,7 @@ struct e1000_hw {
/* M88E1000 PHY Specific Status Register */
#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */
#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_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M;
* 3=110-140M;4=>140M */
......@@ -1725,6 +1866,7 @@ struct e1000_hw {
#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
#define M88E1000_PSSR_DOWNSHIFT_SHIFT 5
#define M88E1000_PSSR_MDIX_SHIFT 6
#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
......@@ -1753,10 +1895,93 @@ struct e1000_hw {
#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz 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. */
#define M88E1000_E_PHY_ID 0x01410C50
#define M88E1000_I_PHY_ID 0x01410C30
#define M88E1011_I_PHY_ID 0x01410C20
#define IGP01E1000_I_PHY_ID 0x02A80380
#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
#define M88E1011_I_REV_4 0x04
......
......@@ -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, 0x1017, 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 */
{0,}
};
......@@ -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_update_phy_info(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 struct net_device_stats * e1000_get_stats(struct net_device *netdev);
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,
struct sk_buff *skb);
static void e1000_tx_timeout(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_add_vid(struct net_device *netdev, uint16_t vid);
......@@ -284,6 +290,7 @@ e1000_down(struct e1000_adapter *adapter)
e1000_irq_disable(adapter);
free_irq(netdev->irq, netdev);
del_timer_sync(&adapter->tx_fifo_stall_timer);
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_info_timer);
adapter->link_speed = 0;
......@@ -299,14 +306,28 @@ e1000_down(struct e1000_adapter *adapter)
void
e1000_reset(struct e1000_adapter *adapter)
{
uint32_t pba;
/* Repartition Pba for greater than 9k mtu
* To take effect CTRL.RST is required.
*/
if(adapter->hw.mac_type < e1000_82547) {
if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
pba = E1000_PBA_40K;
else
pba = E1000_PBA_48K;
} else {
if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
E1000_WRITE_REG(&adapter->hw, PBA, E1000_JUMBO_PBA);
pba = E1000_PBA_22K;
else
E1000_WRITE_REG(&adapter->hw, PBA, E1000_DEFAULT_PBA);
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;
e1000_reset_hw(&adapter->hw);
......@@ -397,11 +418,11 @@ e1000_probe(struct pci_dev *pdev,
netdev->change_mtu = &e1000_change_mtu;
netdev->do_ioctl = &e1000_ioctl;
netdev->tx_timeout = &e1000_tx_timeout;
netdev->watchdog_timeo = HZ;
#ifdef CONFIG_E1000_NAPI
netdev->poll = &e1000_poll;
netdev->weight = 64;
#endif
netdev->watchdog_timeo = 5 * HZ;
netdev->vlan_rx_register = e1000_vlan_rx_register;
netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
......@@ -429,7 +450,8 @@ e1000_probe(struct pci_dev *pdev,
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;
if(pci_using_dac)
......@@ -461,6 +483,9 @@ e1000_probe(struct pci_dev *pdev,
else
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);
adapter->watchdog_timer.function = &e1000_watchdog;
......@@ -490,11 +515,12 @@ e1000_probe(struct pci_dev *pdev,
* 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) &&
(eeprom_data & E1000_EEPROM_APME))
adapter->wol |= E1000_WUFC_MAG;
/* reset the hardware with the new settings */
e1000_reset(adapter);
......@@ -586,6 +612,10 @@ e1000_sw_init(struct e1000_adapter *adapter)
return -1;
}
/* initialize eeprom parameters */
e1000_init_eeprom_params(hw);
/* flow control settings */
hw->fc_high_water = E1000_FC_HIGH_THRESH;
......@@ -593,6 +623,9 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw->fc_pause_time = E1000_FC_PAUSE_TIME;
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 */
if(hw->mac_type >= e1000_82543) {
......@@ -1192,9 +1225,9 @@ e1000_set_multi(struct net_device *netdev)
if(hw->mac_type == e1000_82542_rev2_0)
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
* 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;
......@@ -1234,6 +1267,48 @@ e1000_update_phy_info(unsigned long data)
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
* @data: pointer to netdev cast into an unsigned long
......@@ -1264,6 +1339,7 @@ e1000_watchdog(unsigned long data)
netif_carrier_on(netdev);
netif_wake_queue(netdev);
mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
adapter->smartspeed = 0;
}
} else {
if(netif_carrier_ok(netdev)) {
......@@ -1276,6 +1352,8 @@ e1000_watchdog(unsigned long data)
netif_stop_queue(netdev);
mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
}
e1000_smartspeed(adapter);
}
e1000_update_stats(adapter);
......@@ -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))
/**
* 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
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;
}
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)) {
tx_flags |= E1000_TX_FLAGS_VLAN;
tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
......@@ -2222,6 +2351,61 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
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 -
* @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