This change introduces a split to the Intel E1000 driver, now rather than

just em, there is an igb driver (this follows behavior with our Linux drivers).
All adapters up to the 82575 are supported in em, and new client/desktop support
will continue to be in that adapter.

The igb driver is for new server NICs like the 82575 and its followons.
Advanced features for virtualization and performance will be in this driver.

Also, both drivers now have shared code that is up to the latest we have
released. Some stylistic changes as well.

Enjoy :)
This commit is contained in:
jfv 2008-02-29 21:50:11 +00:00
parent 6f13a6466b
commit 57f8ad0238
50 changed files with 16276 additions and 1173 deletions

View File

@ -708,6 +708,20 @@ dev/ieee488/ibfoo.c optional pcii | tnt4882
dev/ieee488/pcii.c optional pcii
dev/ieee488/tnt4882.c optional tnt4882
dev/ieee488/upd7210.c optional pcii | tnt4882
dev/igb/if_igb.c optional igb \
compile-with "${NORMAL_C} -I$S/dev/igb"
dev/igb/e1000_82575.c optional igb \
compile-with "${NORMAL_C} -I$S/dev/igb"
dev/igb/e1000_api.c optional igb \
compile-with "${NORMAL_C} -I$S/dev/igb"
dev/igb/e1000_mac.c optional igb \
compile-with "${NORMAL_C} -I$S/dev/igb"
dev/igb/e1000_manage.c optional igb \
compile-with "${NORMAL_C} -I$S/dev/igb"
dev/igb/e1000_nvm.c optional igb \
compile-with "${NORMAL_C} -I$S/dev/igb"
dev/igb/e1000_phy.c optional igb \
compile-with "${NORMAL_C} -I$S/dev/igb"
dev/iicbus/ad7418.c optional ad7418
dev/iicbus/ds1672.c optional ds1672
dev/iicbus/icee.c optional icee

View File

@ -1,6 +1,6 @@
$FreeBSD$
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -32,14 +32,13 @@
*******************************************************************************/
/* $FreeBSD$ */
/* e1000_80003es2lan
*/
#include "e1000_api.h"
#include "e1000_80003es2lan.h"
void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw);
@ -70,6 +69,7 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw);
static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw);
static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw);
static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
STATIC s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw);
STATIC void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw);
/*
@ -274,6 +274,8 @@ STATIC s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw)
func->clear_vfta = e1000_clear_vfta_generic;
/* setting MTA */
func->mta_set = e1000_mta_set_generic;
/* read mac address */
func->read_mac_addr = e1000_read_mac_addr_80003es2lan;
/* blink LED */
func->blink_led = e1000_blink_led_generic;
/* setup LED */
@ -324,6 +326,7 @@ STATIC s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_acquire_phy_80003es2lan");
mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
mask |= E1000_SWFW_CSR_SM;
return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
}
@ -342,6 +345,8 @@ STATIC void e1000_release_phy_80003es2lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_release_phy_80003es2lan");
mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
mask |= E1000_SWFW_CSR_SM;
e1000_release_swfw_sync_80003es2lan(hw, mask);
}
@ -480,6 +485,10 @@ STATIC s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
DEBUGFUNC("e1000_read_phy_reg_gg82563_80003es2lan");
ret_val = e1000_acquire_phy_80003es2lan(hw);
if (ret_val)
goto out;
/* Select Configuration Page */
if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
page_select = GG82563_PHY_PAGE_SELECT;
@ -492,9 +501,11 @@ STATIC s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
}
temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT);
ret_val = e1000_write_phy_reg_m88(hw, page_select, temp);
if (ret_val)
ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp);
if (ret_val) {
e1000_release_phy_80003es2lan(hw);
goto out;
}
/*
* The "ready" bit in the MDIC register may be incorrectly set
@ -504,20 +515,22 @@ STATIC s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
usec_delay(200);
/* ...and verify the command was successful. */
ret_val = e1000_read_phy_reg_m88(hw, page_select, &temp);
ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
ret_val = -E1000_ERR_PHY;
e1000_release_phy_80003es2lan(hw);
goto out;
}
usec_delay(200);
ret_val = e1000_read_phy_reg_m88(hw,
ret_val = e1000_read_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
usec_delay(200);
e1000_release_phy_80003es2lan(hw);
out:
return ret_val;
@ -541,6 +554,10 @@ STATIC s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
DEBUGFUNC("e1000_write_phy_reg_gg82563_80003es2lan");
ret_val = e1000_acquire_phy_80003es2lan(hw);
if (ret_val)
goto out;
/* Select Configuration Page */
if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
page_select = GG82563_PHY_PAGE_SELECT;
@ -553,9 +570,11 @@ STATIC s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
}
temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT);
ret_val = e1000_write_phy_reg_m88(hw, page_select, temp);
if (ret_val)
ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp);
if (ret_val) {
e1000_release_phy_80003es2lan(hw);
goto out;
}
/*
@ -566,20 +585,22 @@ STATIC s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
usec_delay(200);
/* ...and verify the command was successful. */
ret_val = e1000_read_phy_reg_m88(hw, page_select, &temp);
ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
ret_val = -E1000_ERR_PHY;
e1000_release_phy_80003es2lan(hw);
goto out;
}
usec_delay(200);
ret_val = e1000_write_phy_reg_m88(hw,
ret_val = e1000_write_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
usec_delay(200);
e1000_release_phy_80003es2lan(hw);
out:
return ret_val;
@ -845,6 +866,8 @@ STATIC s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
icr = E1000_READ_REG(hw, E1000_ICR);
e1000_check_alt_mac_addr_generic(hw);
out:
return ret_val;
}
@ -985,10 +1008,11 @@ static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw)
**/
static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val;
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val;
u32 ctrl_ext;
u16 data;
u32 i = 0;
u16 data, data2;
DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan");
@ -1067,14 +1091,14 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
goto out;
ret_val = e1000_read_kmrn_reg(hw,
E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
&data);
E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
&data);
if (ret_val)
goto out;
data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE;
ret_val = e1000_write_kmrn_reg(hw,
E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
data);
E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
data);
if (ret_val)
goto out;
@ -1109,11 +1133,20 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
if (ret_val)
goto out;
ret_val = e1000_read_phy_reg(hw,
GG82563_PHY_KMRN_MODE_CTRL,
&data);
if (ret_val)
goto out;
do {
ret_val = e1000_read_phy_reg(hw,
GG82563_PHY_KMRN_MODE_CTRL,
&data);
if (ret_val)
goto out;
ret_val = e1000_read_phy_reg(hw,
GG82563_PHY_KMRN_MODE_CTRL,
&data2);
if (ret_val)
goto out;
i++;
} while ((data != data2) && (i < GG82563_MAX_KMRN_RETRY));
data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
ret_val = e1000_write_phy_reg(hw,
@ -1303,6 +1336,21 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
return ret_val;
}
/**
* e1000_read_mac_addr_80003es2lan - Read device MAC address
* @hw: pointer to the HW structure
**/
STATIC s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_mac_addr_80003es2lan");
if (e1000_check_alt_mac_addr_generic(hw))
ret_val = e1000_read_mac_addr_generic(hw);
return ret_val;
}
/**
* e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down
* @hw: pointer to the HW structure

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -64,7 +64,7 @@
/* PHY Specific Control Register 2 (Page 0, Register 26) */
#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000
/* 1=Reverse Auto-Negotiation */
/* 1=Reverse Auto-Negotiation */
/* MAC Specific Control Register (Page 2, Register 21) */
/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
@ -94,7 +94,7 @@
/* Power Management Control Register (Page 193, Register 20) */
#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001
/* 1=Enable SERDES Electrical Idle */
/* 1=Enable SERDES Electrical Idle */
/* In-Band Control Register (Page 194, Register 18) */
#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -32,6 +32,7 @@
*******************************************************************************/
/* $FreeBSD$ */
/* e1000_82540
* e1000_82545
* e1000_82546
@ -41,8 +42,6 @@
#include "e1000_api.h"
void e1000_init_function_pointers_82540(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_82540(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_82540(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_82540(struct e1000_hw *hw);
@ -499,7 +498,7 @@ STATIC s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw)
* e1000_adjust_serdes_amplitude_82540 - Adjust amplitude based on EEPROM
* @hw: pointer to the HW structure
*
* Adjust the SERDES ouput amplitude based on the EEPROM settings.
* Adjust the SERDES output amplitude based on the EEPROM settings.
**/
static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw)
{
@ -611,14 +610,14 @@ static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw)
if ((nvm_data != NVM_RESERVED_WORD) && (nvm_data & NVM_PHY_CLASS_A)) {
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
0x000B);
0x000B);
if (ret_val) {
ret_val = -E1000_ERR_PHY;
goto out;
}
ret_val = e1000_write_phy_reg(hw,
M88E1000_PHY_GEN_CONTROL,
0x8104);
M88E1000_PHY_GEN_CONTROL,
0x8104);
if (ret_val) {
ret_val = -E1000_ERR_PHY;
goto out;

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -42,8 +42,6 @@
#include "e1000_api.h"
#include "e1000_82541.h"
void e1000_init_function_pointers_82541(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_82541(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_82541(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_82541(struct e1000_hw *hw);
@ -514,7 +512,7 @@ STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,
* Verify the reset block is not blocking us from resetting. Acquire
* semaphore (if necessary) and read/set/write the device control reset
* bit in the PHY. Wait the appropriate delay time for the device to
* reset and relase the semaphore (if necessary).
* reset and release the semaphore (if necessary).
* This is a function pointer entry point called by the api module.
**/
STATIC s32 e1000_phy_hw_reset_82541(struct e1000_hw *hw)
@ -902,8 +900,8 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw,
*
* The automatic gain control (agc) normalizes the amplitude of the
* received signal, adjusting for the attenuation produced by the
* cable. By reading the AGC registers, which reperesent the
* cobination of course and fine gain value, the value can be put
* cable. By reading the AGC registers, which represent the
* combination of coarse and fine gain value, the value can be put
* into a lookup table to obtain the approximate cable length
* for each channel. This is a function pointer entry point called by the
* api module.

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -38,8 +38,6 @@
#include "e1000_api.h"
void e1000_init_function_pointers_82542(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_82542(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_82542(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_82542(struct e1000_hw *hw);
@ -185,7 +183,7 @@ void e1000_init_function_pointers_82542(struct e1000_hw *hw)
* @hw: pointer to the HW structure
*
* This will obtain information about the HW bus for which the
* adaper is attached and stores it in the hw structure. This is a function
* adapter is attached and stores it in the hw structure. This is a function
* pointer entry point called by the api module.
**/
STATIC s32 e1000_get_bus_info_82542(struct e1000_hw *hw)
@ -427,7 +425,7 @@ STATIC s32 e1000_led_off_82542(struct e1000_hw *hw)
}
/**
* e1000_translate_register_82542 - Translate the proper regiser offset
* e1000_translate_register_82542 - Translate the proper register offset
* @reg: e1000 register to be read
*
* Registers in 82542 are located in different offsets than other adapters

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -40,8 +40,6 @@
#include "e1000_api.h"
#include "e1000_82543.h"
void e1000_init_function_pointers_82543(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_82543(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_82543(struct e1000_hw *hw);
@ -303,7 +301,7 @@ void e1000_init_function_pointers_82543(struct e1000_hw *hw)
* e1000_tbi_compatibility_enabled_82543 - Returns TBI compat status
* @hw: pointer to the HW structure
*
* Returns the curent status of 10-bit Interface (TBI) compatibility
* Returns the current status of 10-bit Interface (TBI) compatibility
* (enabled/disabled).
**/
static bool e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw)
@ -370,7 +368,7 @@ void e1000_set_tbi_compatibility_82543(struct e1000_hw *hw, bool state)
* e1000_tbi_sbp_enabled_82543 - Returns TBI SBP status
* @hw: pointer to the HW structure
*
* Returns the curent status of 10-bit Interface (TBI) store bad packet (SBP)
* Returns the current status of 10-bit Interface (TBI) store bad packet (SBP)
* (enabled/disabled).
**/
bool e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw)
@ -660,8 +658,8 @@ static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl)
* @hw: pointer to the HW structure
* @ctrl: pointer to the control register
*
* Lower the management data input clock by clearing the MDC bit in the control
* register.
* Lower the management data input clock by clearing the MDC bit in the
* control register.
**/
static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl)
{
@ -816,7 +814,7 @@ STATIC s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw)
* @hw: pointer to the HW structure
*
* When forcing link to 10 Full or 10 Half, the PHY can reverse the polarity
* inadvertantly. To workaround the issue, we disable the transmitter on
* inadvertently. To workaround the issue, we disable the transmitter on
* the PHY until we have established the link partner's link parameters.
**/
static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw)
@ -1233,7 +1231,7 @@ STATIC s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw)
msec_delay(1);
/*
* For these adapters, the SW defineable pin 1 is cleared when the
* For these adapters, the SW definable pin 1 is cleared when the
* optics detect a signal. If we have a signal, then poll for a
* "Link-Up" indication.
*/
@ -1587,7 +1585,7 @@ STATIC s32 e1000_led_on_82543(struct e1000_hw *hw)
if (hw->mac.type == e1000_82544 &&
hw->phy.media_type == e1000_media_type_copper) {
/* Clear SW-defineable Pin 0 to turn on the LED */
/* Clear SW-definable Pin 0 to turn on the LED */
ctrl &= ~E1000_CTRL_SWDPIN0;
ctrl |= E1000_CTRL_SWDPIO0;
} else {
@ -1615,7 +1613,7 @@ STATIC s32 e1000_led_off_82543(struct e1000_hw *hw)
if (hw->mac.type == e1000_82544 &&
hw->phy.media_type == e1000_media_type_copper) {
/* Set SW-defineable Pin 0 to turn off the LED */
/* Set SW-definable Pin 0 to turn off the LED */
ctrl |= E1000_CTRL_SWDPIN0;
ctrl |= E1000_CTRL_SWDPIO0;
} else {

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -42,8 +42,6 @@
#include "e1000_api.h"
#include "e1000_82571.h"
void e1000_init_function_pointers_82571(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_82571(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_82571(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_82571(struct e1000_hw *hw);
@ -60,8 +58,8 @@ STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw);
STATIC s32 e1000_init_hw_82571(struct e1000_hw *hw);
STATIC void e1000_clear_vfta_82571(struct e1000_hw *hw);
STATIC void e1000_update_mc_addr_list_82571(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count);
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count);
STATIC s32 e1000_setup_link_82571(struct e1000_hw *hw);
STATIC s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
STATIC s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
@ -154,6 +152,25 @@ STATIC s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
goto out;
}
break;
case e1000_82574:
phy->type = e1000_phy_bm;
func->get_cfg_done = e1000_get_cfg_done_generic;
func->get_phy_info = e1000_get_phy_info_m88;
func->commit_phy = e1000_phy_sw_reset_generic;
func->force_speed_duplex = e1000_phy_force_speed_duplex_m88;
func->get_cable_length = e1000_get_cable_length_m88;
func->read_phy_reg = e1000_read_phy_reg_bm2;
func->write_phy_reg = e1000_write_phy_reg_bm2;
/* This uses above function pointers */
ret_val = e1000_get_phy_id_82571(hw);
/* Verify PHY ID */
if (phy->id != BME1000_E_PHY_ID_R2) {
ret_val = -E1000_ERR_PHY;
DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id);
goto out;
}
break;
default:
ret_val = -E1000_ERR_PHY;
goto out;
@ -198,6 +215,7 @@ STATIC s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_82573:
case e1000_82574:
if (((eecd >> 15) & 0x3) == 0x3) {
nvm->type = e1000_nvm_flash_hw;
nvm->word_size = 2048;
@ -229,9 +247,7 @@ STATIC s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
/* Function Pointers */
func->acquire_nvm = e1000_acquire_nvm_82571;
func->read_nvm = (hw->mac.type == e1000_82573)
? e1000_read_nvm_eerd
: e1000_read_nvm_spi;
func->read_nvm = e1000_read_nvm_eerd;
func->release_nvm = e1000_release_nvm_82571;
func->update_nvm = e1000_update_nvm_checksum_82571;
func->validate_nvm = e1000_validate_nvm_checksum_82571;
@ -382,6 +398,7 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS;
u16 phy_id = 0;
DEBUGFUNC("e1000_get_phy_id_82571");
@ -399,11 +416,26 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
case e1000_82573:
ret_val = e1000_get_phy_id(hw);
break;
case e1000_82574:
ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id);
if (ret_val)
goto out;
phy->id = (u32)(phy_id << 16);
usec_delay(20);
ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id);
if (ret_val)
goto out;
phy->id |= (u32)(phy_id);
phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
break;
default:
ret_val = -E1000_ERR_PHY;
break;
}
out:
return ret_val;
}
@ -413,7 +445,7 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
*
* Acquire the HW semaphore to access the PHY or NVM
**/
s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
{
u32 swsm;
s32 ret_val = E1000_SUCCESS;
@ -452,7 +484,7 @@ s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
*
* Release hardware semaphore used to access the PHY or NVM
**/
void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
{
u32 swsm;
@ -484,7 +516,7 @@ STATIC s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
if (ret_val)
goto out;
if (hw->mac.type != e1000_82573)
if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574)
ret_val = e1000_acquire_nvm_generic(hw);
if (ret_val)
@ -518,7 +550,7 @@ STATIC void e1000_release_nvm_82571(struct e1000_hw *hw)
* For non-82573 silicon, write data to EEPROM at offset using SPI interface.
*
* If e1000_update_nvm_checksum is not called after this function, the
* EEPROM will most likley contain an invalid checksum.
* EEPROM will most likely contain an invalid checksum.
**/
STATIC s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
@ -529,6 +561,7 @@ STATIC s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
switch (hw->mac.type) {
case e1000_82573:
case e1000_82574:
ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data);
break;
case e1000_82571:
@ -641,7 +674,7 @@ STATIC s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw)
* poll for completion.
*
* If e1000_update_nvm_checksum is not called after this function, the
* EEPROM will most likley contain an invalid checksum.
* EEPROM will most likely contain an invalid checksum.
**/
static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data)
@ -834,7 +867,7 @@ STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw)
* Must acquire the MDIO ownership before MAC reset.
* Ownership defaults to firmware after a reset.
*/
if (hw->mac.type == e1000_82573) {
if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
@ -875,7 +908,7 @@ STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw)
* Need to wait for Phy configuration completion before accessing
* NVM and Phy.
*/
if (hw->mac.type == e1000_82573)
if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574)
msec_delay(25);
/* Clear any pending interrupt events. */
@ -943,7 +976,7 @@ STATIC s32 e1000_init_hw_82571(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data);
/* ...for both queues. */
if (mac->type != e1000_82573) {
if (mac->type != e1000_82573 && mac->type != e1000_82574) {
reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1));
reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
E1000_TXDCTL_FULL_TX_DESC_WB |
@ -1023,14 +1056,14 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
}
/* Device Control */
if (hw->mac.type == e1000_82573) {
if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
reg = E1000_READ_REG(hw, E1000_CTRL);
reg &= ~(1 << 29);
E1000_WRITE_REG(hw, E1000_CTRL, reg);
}
/* Extended Device Control */
if (hw->mac.type == e1000_82573) {
if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
reg &= ~(1 << 23);
reg |= (1 << 22);
@ -1057,7 +1090,7 @@ STATIC void e1000_clear_vfta_82571(struct e1000_hw *hw)
DEBUGFUNC("e1000_clear_vfta_82571");
if (hw->mac.type == e1000_82573) {
if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
if (hw->mng_cookie.vlan_id != 0) {
/*
* The VFTA is a 4096b bit-field, each identifying
@ -1099,8 +1132,8 @@ STATIC void e1000_clear_vfta_82571(struct e1000_hw *hw)
* unless there are workarounds that change this.
**/
STATIC void e1000_update_mc_addr_list_82571(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count)
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count)
{
DEBUGFUNC("e1000_update_mc_addr_list_82571");
@ -1130,7 +1163,7 @@ STATIC s32 e1000_setup_link_82571(struct e1000_hw *hw)
* the default flow control setting, so we explicitly
* set it to full.
*/
if (hw->mac.type == e1000_82573)
if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574)
hw->fc.type = e1000_fc_full;
return e1000_setup_link_generic(hw);
@ -1158,6 +1191,7 @@ STATIC s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
switch (hw->phy.type) {
case e1000_phy_m88:
case e1000_phy_bm:
ret_val = e1000_copper_link_setup_m88(hw);
break;
case e1000_phy_igp_2:
@ -1200,7 +1234,7 @@ STATIC s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
* If SerDes loopback mode is entered, there is no form
* of reset to take the adapter out of that mode. So we
* have to explicitly take the adapter out of loopback
* mode. This prevents drivers from twidling their thumbs
* mode. This prevents drivers from twiddling their thumbs
* if another tool failed to take it out of loopback mode.
*/
E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
@ -1232,11 +1266,10 @@ STATIC s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
goto out;
}
if (hw->mac.type == e1000_82573 &&
if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
*data == ID_LED_RESERVED_F746)
*data = ID_LED_DEFAULT_82573;
else if (*data == ID_LED_RESERVED_0000 ||
*data == ID_LED_RESERVED_FFFF)
else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
*data = ID_LED_DEFAULT;
out:
return ret_val;
@ -1246,7 +1279,7 @@ STATIC s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
* e1000_get_laa_state_82571 - Get locally administered address state
* @hw: pointer to the HW structure
*
* Retrieve and return the current locally administed address state.
* Retrieve and return the current locally administered address state.
**/
bool e1000_get_laa_state_82571(struct e1000_hw *hw)
{
@ -1271,7 +1304,7 @@ bool e1000_get_laa_state_82571(struct e1000_hw *hw)
* @hw: pointer to the HW structure
* @state: enable/disable locally administered address
*
* Enable/Disable the current locally administed address state.
* Enable/Disable the current locally administered address state.
**/
void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state)
{

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -44,4 +44,12 @@
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
/* Intr Throttling - RW */
#define E1000_EITR_82574(_n) (0x000E8 + (0x4 * (_n)))
#define E1000_EIAC_82574 0x000DC /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAC_MASK_82574 0x01500000
#define E1000_RXCFGL 0x0B634 /* TimeSync Rx EtherType & Msg Type Reg - RW */
#endif

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -38,17 +38,6 @@
#include "e1000_nvm.h"
#include "e1000_phy.h"
#ifndef NO_82542_SUPPORT
extern void e1000_init_function_pointers_82542(struct e1000_hw *hw);
#endif
extern void e1000_init_function_pointers_82543(struct e1000_hw *hw);
extern void e1000_init_function_pointers_82540(struct e1000_hw *hw);
extern void e1000_init_function_pointers_82571(struct e1000_hw *hw);
extern void e1000_init_function_pointers_82541(struct e1000_hw *hw);
extern void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw);
extern void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw);
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
/**
* e1000_init_mac_params - Initialize MAC function pointers
* @hw: pointer to the HW structure
@ -228,6 +217,9 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82573L:
mac->type = e1000_82573;
break;
case E1000_DEV_ID_82574L:
mac->type = e1000_82574;
break;
case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
@ -246,14 +238,15 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_ICH9_IFE:
case E1000_DEV_ID_ICH9_IFE_GT:
case E1000_DEV_ID_ICH9_IFE_G:
case E1000_DEV_ID_ICH9_IGP_M:
case E1000_DEV_ID_ICH9_IGP_M_AMT:
case E1000_DEV_ID_ICH9_IGP_AMT:
case E1000_DEV_ID_ICH9_IGP_C:
mac->type = e1000_ich9lan;
break;
case E1000_DEV_ID_82575EB_COPPER:
case E1000_DEV_ID_82575EB_FIBER_SERDES:
case E1000_DEV_ID_82575GB_QUAD_COPPER:
mac->type = e1000_82575;
case E1000_DEV_ID_ICH10_D_BM_LM:
case E1000_DEV_ID_ICH10_D_BM_LF:
mac->type = e1000_ich10lan;
break;
default:
/* Should never have loaded on this device */
@ -296,7 +289,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
/*
* Init some generic function pointers that are currently all pointing
* to generic implementations. We do this first allowing a driver
* module to override it afterwards.
* module to override it afterward.
*/
hw->func.config_collision_dist = e1000_config_collision_dist_generic;
hw->func.rar_set = e1000_rar_set_generic;
@ -338,6 +331,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
case e1000_82571:
case e1000_82572:
case e1000_82573:
case e1000_82574:
e1000_init_function_pointers_82571(hw);
break;
case e1000_80003es2lan:
@ -345,11 +339,9 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
break;
case e1000_ich8lan:
case e1000_ich9lan:
case e1000_ich10lan:
e1000_init_function_pointers_ich8lan(hw);
break;
case e1000_82575:
e1000_init_function_pointers_82575(hw);
break;
default:
DEBUGOUT("Hardware not supported\n");
ret_val = -E1000_ERR_CONFIG;
@ -397,7 +389,7 @@ void e1000_remove_device(struct e1000_hw *hw)
* @hw: pointer to the HW structure
*
* This will obtain information about the HW bus for which the
* adaper is attached and stores it in the hw structure. This is a
* adapter is attached and stores it in the hw structure. This is a
* function pointer entry point called by drivers.
**/
s32 e1000_get_bus_info(struct e1000_hw *hw)
@ -825,7 +817,7 @@ s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
*
* Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
*
* This function checks whether the HOST IF is enabled for command operaton
* This function checks whether the HOST IF is enabled for command operation
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
@ -1157,7 +1149,8 @@ s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
* Writes the PHY register at offset with the value in data.
* This is a function pointer entry point called by drivers.
**/
s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset, u8 data)
s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset,
u8 data)
{
return e1000_write_8bit_ctrl_reg_generic(hw, reg, offset, data);
}
@ -1178,7 +1171,7 @@ void e1000_power_up_phy(struct e1000_hw *hw)
}
/**
* e1000_power_down_phy - Power down PHY
* e1000_power_down_phy - Power down PHY
* @hw: pointer to the HW structure
*
* The phy may be powered down to save power, to turn off link when the

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -38,6 +38,16 @@
#include "e1000_hw.h"
#ifndef NO_82542_SUPPORT
extern void e1000_init_function_pointers_82542(struct e1000_hw *hw);
#endif
extern void e1000_init_function_pointers_82543(struct e1000_hw *hw);
extern void e1000_init_function_pointers_82540(struct e1000_hw *hw);
extern void e1000_init_function_pointers_82571(struct e1000_hw *hw);
extern void e1000_init_function_pointers_82541(struct e1000_hw *hw);
extern void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw);
extern void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw);
s32 e1000_set_mac_type(struct e1000_hw *hw);
s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
s32 e1000_init_mac_params(struct e1000_hw *hw);
@ -121,6 +131,7 @@ void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
bool state);
void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw);
/*

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -46,7 +46,10 @@
#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_LSCWE 0x00000010 /* Link Status wake up enable */
#define E1000_WUC_LSCWO 0x00000020 /* Link Status wake up override */
#define E1000_WUC_SPM 0x80000000 /* Enable SPM */
#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */
/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
@ -57,14 +60,22 @@
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
#define E1000_WUFC_IGNORE_TCO_BM 0x00000800 /* Ignore WakeOn TCO packets */
#define E1000_WUFC_FLX0_BM 0x00001000 /* Flexible Filter 0 Enable */
#define E1000_WUFC_FLX1_BM 0x00002000 /* Flexible Filter 1 Enable */
#define E1000_WUFC_FLX2_BM 0x00004000 /* Flexible Filter 2 Enable */
#define E1000_WUFC_FLX3_BM 0x00008000 /* Flexible Filter 3 Enable */
#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
#define E1000_WUFC_ALL_FILTERS_BM 0x0000F0FF /* Mask for all wakeup filters */
#define E1000_WUFC_FLX_OFFSET_BM 12 /* Offset to the Flexible Filters bits */
#define E1000_WUFC_FLX_FILTERS_BM 0x0000F000 /* Mask for the 4 flexible filters */
#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
/* Wake Up Status */
#define E1000_WUS_LNKC E1000_WUFC_LNKC
@ -75,6 +86,11 @@
#define E1000_WUS_ARP E1000_WUFC_ARP
#define E1000_WUS_IPV4 E1000_WUFC_IPV4
#define E1000_WUS_IPV6 E1000_WUFC_IPV6
#define E1000_WUS_FLX0_BM E1000_WUFC_FLX0_BM
#define E1000_WUS_FLX1_BM E1000_WUFC_FLX1_BM
#define E1000_WUS_FLX2_BM E1000_WUFC_FLX2_BM
#define E1000_WUS_FLX3_BM E1000_WUFC_FLX3_BM
#define E1000_WUS_FLX_FILTERS_BM E1000_WUFC_FLX_FILTERS_BM
#define E1000_WUS_FLX0 E1000_WUFC_FLX0
#define E1000_WUS_FLX1 E1000_WUFC_FLX1
#define E1000_WUS_FLX2 E1000_WUFC_FLX2
@ -100,11 +116,13 @@
#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_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */
#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
/* Reserved (bits 4,5) in >= 82575 */
#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Definable Pin 4 */
#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Definable Pin 5 */
#define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA
#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Definable Pin 6 */
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
/* SDP 4/5 (bits 8,9) are reserved in >= 82575 */
#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
#define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */
#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */
@ -130,12 +148,14 @@
#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
#define E1000_CTRL_EXT_CANC 0x04000000 /* Interrupt delay cancellation */
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
/* IAME enable bit (27) was removed in >= 82575 */
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
#define E1000_CRTL_EXT_PB_PAREN 0x01000000 /* packet buffer parity error detection enabled */
#define E1000_CTRL_EXT_DF_PAREN 0x02000000 /* descriptor FIFO parity error detection enable */
#define E1000_CTRL_EXT_GHOST_PAREN 0x40000000
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
#define E1000_CTRL_EXT_LSECCK 0x00001000
#define E1000_I2CCMD_REG_ADDR_SHIFT 16
#define E1000_I2CCMD_REG_ADDR 0x00FF0000
#define E1000_I2CCMD_PHY_ADDR_SHIFT 24
@ -149,12 +169,12 @@
#define E1000_MAX_SGMII_PHY_REG_ADDR 255
#define E1000_I2CCMD_PHY_TIMEOUT 200
/* Receive Decriptor bit definitions */
/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
@ -184,6 +204,13 @@
#define E1000_RXDEXT_STATERR_IPE 0x40000000
#define E1000_RXDEXT_STATERR_RXE 0x80000000
#define E1000_RXDEXT_LSECH 0x01000000
#define E1000_RXDEXT_LSECE_MASK 0x60000000
#define E1000_RXDEXT_LSECE_NO_ERROR 0x00000000
#define E1000_RXDEXT_LSECE_NO_SA_MATCH 0x20000000
#define E1000_RXDEXT_LSECE_REPLAY_DETECT 0x40000000
#define E1000_RXDEXT_LSECE_BAD_SIG 0x60000000
/* mask to determine if packets should be dropped due to frame errors */
#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
E1000_RXD_ERR_CE | \
@ -323,6 +350,7 @@
#define E1000_SWFW_EEP_SM 0x1
#define E1000_SWFW_PHY0_SM 0x2
#define E1000_SWFW_PHY1_SM 0x4
#define E1000_SWFW_CSR_SM 0x8
/* FACTPS Definitions */
#define E1000_FACTPS_LFS 0x40000000 /* LAN Function Select */
@ -441,7 +469,7 @@
#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disabled on port 0 */
#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */
/* Constants used to intrepret the masked PCI-X bus speed. */
/* Constants used to interpret the masked PCI-X bus speed. */
#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */
#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */
@ -537,6 +565,8 @@
#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
/* Extended desc bits for Linksec and timesync */
#define E1000_TXD_CMD_LINKSEC 0x10000000 /* Apply LinkSec on packet */
#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */
/* Transmit Control */
#define E1000_TCTL_RST 0x00000001 /* software reset */
@ -695,7 +725,12 @@
#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */
#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DISSW bit in the FWSM */
#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generates an interrupt */
#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
#define E1000_ICR_EPRST 0x00100000 /* ME hardware reset occurs */
#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */
#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */
#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */
#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */
#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */
/* Extended Interrupt Cause Read */
#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */
@ -768,6 +803,11 @@
#define E1000_IMS_DSW E1000_ICR_DSW
#define E1000_IMS_PHYINT E1000_ICR_PHYINT
#define E1000_IMS_EPRST E1000_ICR_EPRST
#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */
#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */
#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */
#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */
#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupts */
/* Extended Interrupt Mask Set */
#define E1000_EIMS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */
@ -1019,7 +1059,7 @@
/* PHY 1000 MII Register/Bit Definitions */
/* PHY Registers defined by IEEE */
#define PHY_CONTROL 0x00 /* Control Register */
#define PHY_STATUS 0x01 /* Status Regiser */
#define PHY_STATUS 0x01 /* Status Register */
#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
@ -1123,7 +1163,7 @@
#define NVM_WRITE_OPCODE_MICROWIRE 0x5 /* NVM write opcode */
#define NVM_ERASE_OPCODE_MICROWIRE 0x7 /* NVM erase opcode */
#define NVM_EWEN_OPCODE_MICROWIRE 0x13 /* NVM erase/write enable */
#define NVM_EWDS_OPCODE_MICROWIRE 0x10 /* NVM erast/write disable */
#define NVM_EWDS_OPCODE_MICROWIRE 0x10 /* NVM erase/write disable */
/* NVM Commands - SPI */
#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
@ -1205,6 +1245,8 @@
#define IFE_E_PHY_ID 0x02A80330
#define IFE_PLUS_E_PHY_ID 0x02A80320
#define IFE_C_E_PHY_ID 0x02A80310
#define BME1000_E_PHY_ID 0x01410CB0
#define BME1000_E_PHY_ID_R2 0x01410CB1
#define M88_VENDOR 0x0141
/* M88E1000 Specific Registers */
@ -1311,6 +1353,9 @@
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X 0x0C00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X 0x0E00
/* BME1000 PHY Specific Control Register */
#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */
/*
* Bits...
* 15-5: page
@ -1402,29 +1447,5 @@
#define E1000_GEN_CTL_ADDRESS_SHIFT 8
#define E1000_GEN_POLL_TIMEOUT 640
/* LinkSec register fields */
#define E1000_LSECTXCAP_SUM_MASK 0x00FF0000
#define E1000_LSECTXCAP_SUM_SHIFT 16
#define E1000_LSECRXCAP_SUM_MASK 0x00FF0000
#define E1000_LSECRXCAP_SUM_SHIFT 16
#define E1000_LSECTXCTRL_EN_MASK 0x00000003
#define E1000_LSECTXCTRL_DISABLE 0x0
#define E1000_LSECTXCTRL_AUTH 0x1
#define E1000_LSECTXCTRL_AUTH_ENCRYPT 0x2
#define E1000_LSECTXCTRL_AISCI 0x00000020
#define E1000_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00
#define E1000_LSECTXCTRL_RSV_MASK 0x000000D8
#define E1000_LSECRXCTRL_EN_MASK 0x0000000C
#define E1000_LSECRXCTRL_EN_SHIFT 2
#define E1000_LSECRXCTRL_DISABLE 0x0
#define E1000_LSECRXCTRL_CHECK 0x1
#define E1000_LSECRXCTRL_STRICT 0x2
#define E1000_LSECRXCTRL_DROP 0x3
#define E1000_LSECRXCTRL_PLSH 0x00000040
#define E1000_LSECRXCTRL_RP 0x00000080
#define E1000_LSECRXCTRL_RSV_MASK 0xFFFFFF33
#define UNREFERENCED_PARAMETER(_p)
#endif

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -96,6 +96,7 @@ struct e1000_hw;
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82573L 0x109A
#define E1000_DEV_ID_82574L 0x10D3
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
@ -107,14 +108,15 @@ struct e1000_hw;
#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4
#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
#define E1000_DEV_ID_ICH8_IGP_M 0x104D
#define E1000_DEV_ID_ICH9_IGP_M 0x10BF
#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10BE
#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD
#define E1000_DEV_ID_ICH9_IGP_C 0x294C
#define E1000_DEV_ID_ICH9_IFE 0x10C0
#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3
#define E1000_DEV_ID_ICH9_IFE_G 0x10C2
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
#define E1000_REVISION_0 0
#define E1000_REVISION_1 1
@ -144,10 +146,11 @@ typedef enum {
e1000_82571,
e1000_82572,
e1000_82573,
e1000_82574,
e1000_80003es2lan,
e1000_ich8lan,
e1000_ich9lan,
e1000_82575,
e1000_ich10lan,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
} e1000_mac_type;
@ -185,6 +188,7 @@ typedef enum {
e1000_phy_gg82563,
e1000_phy_igp_3,
e1000_phy_ife,
e1000_phy_bm,
} e1000_phy_type;
typedef enum {

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -40,8 +40,6 @@
#include "e1000_api.h"
#include "e1000_ich8lan.h"
void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw);
@ -82,6 +80,8 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw);
static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw);
static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw);
static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
STATIC s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw,
u32 offset, u8* data);
static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
u8 size, u16* data);
STATIC s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw,
@ -180,6 +180,20 @@ STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
func->power_up_phy = e1000_power_up_phy_copper;
func->power_down_phy = e1000_power_down_phy_copper_ich8lan;
/*
* We may need to do this twice - once for IGP and if that fails,
* we'll set BM func pointers and try again
*/
ret_val = e1000_determine_phy_address(hw);
if (ret_val) {
func->write_phy_reg = e1000_write_phy_reg_bm;
func->read_phy_reg = e1000_read_phy_reg_bm;
ret_val = e1000_determine_phy_address(hw);
if (ret_val) {
DEBUGOUT("Cannot determine PHY address. Erroring out\n");
goto out;
}
}
phy->id = 0;
while ((e1000_phy_unknown == e1000_get_phy_type_from_id(phy->id)) &&
@ -202,6 +216,13 @@ STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
phy->type = e1000_phy_ife;
phy->autoneg_mask = E1000_ALL_NOT_GIG;
break;
case BME1000_E_PHY_ID:
phy->type = e1000_phy_bm;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
func->read_phy_reg = e1000_read_phy_reg_bm;
func->write_phy_reg = e1000_write_phy_reg_bm;
func->commit_phy = e1000_phy_sw_reset_generic;
break;
default:
ret_val = -E1000_ERR_PHY;
goto out;
@ -702,6 +723,7 @@ STATIC s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
ret_val = e1000_get_phy_info_ife_ich8lan(hw);
break;
case e1000_phy_igp_3:
case e1000_phy_bm:
ret_val = e1000_get_phy_info_igp(hw);
break;
default:
@ -774,7 +796,7 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw)
* e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY
* @hw: pointer to the HW structure
*
* Polarity is determined on the polarity reveral feature being enabled.
* Polarity is determined on the polarity reversal feature being enabled.
* This function is only called by other family-specific
* routines.
**/
@ -1003,10 +1025,46 @@ STATIC s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw,
STATIC s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
{
s32 ret_val = E1000_SUCCESS;
if (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL)
*bank = 1;
else
*bank = 0;
struct e1000_nvm_info *nvm = &hw->nvm;
/* flash bank size is in words */
u32 bank1_offset = nvm->flash_bank_size * sizeof(u16);
u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1;
u8 bank_high_byte = 0;
if (hw->mac.type != e1000_ich10lan) {
if (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL)
*bank = 1;
else
*bank = 0;
} else if (hw->dev_spec != NULL) {
/*
* Make sure the signature for bank 0 is valid,
* if not check for bank1
*/
e1000_read_flash_byte_ich8lan(hw, act_offset, &bank_high_byte);
if ((bank_high_byte & 0xC0) == 0x80) {
*bank = 0;
} else {
/*
* find if segment 1 is valid by verifying
* bit 15:14 = 10b in word 0x13
*/
e1000_read_flash_byte_ich8lan(hw,
act_offset + bank1_offset,
&bank_high_byte);
/* bank1 has a valid signature equivalent to SEC1V */
if ((bank_high_byte & 0xC0) == 0x80) {
*bank = 1;
} else {
DEBUGOUT("ERROR: EEPROM not present\n");
ret_val = -E1000_ERR_NVM;
}
}
} else {
DEBUGOUT("DEV SPEC is NULL\n");
ret_val = -E1000_ERR_NVM;
}
return ret_val;
}
@ -1112,7 +1170,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
* Either we should have a hardware SPI cycle in progress
* bit to check against, in order to start a new cycle or
* FDONE bit should be changed in the hardware so that it
* is 1 after harware reset, which can then be used as an
* is 1 after hardware reset, which can then be used as an
* indication whether a cycle is in progress or has been
* completed.
*/
@ -1223,6 +1281,30 @@ STATIC s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset,
return ret_val;
}
/**
* e1000_read_flash_byte_ich8lan - Read byte from flash
* @hw: pointer to the HW structure
* @offset: The offset of the byte to read.
* @data: Pointer to a byte to store the value read.
*
* Reads a single byte from the NVM using the flash access registers.
**/
STATIC s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
u8* data)
{
s32 ret_val = E1000_SUCCESS;
u16 word = 0;
ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word);
if (ret_val)
goto out;
*data = (u8)word;
out:
return ret_val;
}
/**
* e1000_read_flash_data_ich8lan - Read byte or word from NVM
* @hw: pointer to the HW structure
@ -1363,7 +1445,7 @@ STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
* which writes the checksum to the shadow ram. The changes in the shadow
* ram are then committed to the EEPROM by processing each bank at a time
* checking for the modified bit and writing only the pending changes.
* After a succesful commit, the shadow ram is cleared and is ready for
* After a successful commit, the shadow ram is cleared and is ready for
* future writes.
**/
STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
@ -1516,8 +1598,9 @@ STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
* @hw: pointer to the HW structure
*
* Check to see if checksum needs to be fixed by reading bit 6 in word 0x19.
* If the bit is 0, that the EEPROM had been modified, but the checksum was not
* calculated, in which case we need to calculate the checksum and set bit 6.
* If the bit is 0, that the EEPROM had been modified, but the checksum was
* not calculated, in which case we need to calculate the checksum and set
* bit 6.
**/
STATIC s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
{
@ -1661,8 +1744,8 @@ STATIC s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
* Writes a single byte to the NVM using the flash access registers.
* Goes through a retry algorithm before giving up.
**/
static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
u8 byte)
static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
u32 offset, u8 byte)
{
s32 ret_val;
u16 program_retries;
@ -1960,7 +2043,7 @@ STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
* - initialize LED identification
* - setup receive address registers
* - setup flow control
* - setup transmit discriptors
* - setup transmit descriptors
* - clear statistics
**/
STATIC s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
@ -2174,6 +2257,10 @@ STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
ret_val = e1000_copper_link_setup_igp(hw);
if (ret_val)
goto out;
} else if (hw->phy.type == e1000_phy_bm) {
ret_val = e1000_copper_link_setup_m88(hw);
if (ret_val)
goto out;
}
if (hw->phy.type == e1000_phy_ife) {
@ -2211,7 +2298,7 @@ STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
* @speed: pointer to store current link speed
* @duplex: pointer to store the current link duplex
*
* Calls the generic get_speed_and_duplex to retreive the current link
* Calls the generic get_speed_and_duplex to retrieve the current link
* information and then calls the Kumeran lock loss workaround for links at
* gigabit speeds.
**/
@ -2310,7 +2397,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
/*
* Call gig speed drop workaround on Giga disable before accessing
* Call gig speed drop workaround on Gig disable before accessing
* any PHY registers
*/
e1000_gig_downshift_workaround_ich8lan(hw);
@ -2323,9 +2410,9 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
}
/**
* e1000_set_kmrn_lock_loss_workaound_ich8lan - Set Kumeran workaround state
* e1000_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state
* @hw: pointer to the HW structure
* @state: boolean value used to set the current Kumaran workaround state
* @state: boolean value used to set the current Kumeran workaround state
*
* If ICH8, set the current Kumeran workaround state (enabled - TRUE
* /disabled - FALSE).
@ -2385,7 +2472,7 @@ void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_PHY_CTRL, reg);
/*
* Call gig speed drop workaround on Giga disable before
* Call gig speed drop workaround on Gig disable before
* accessing any PHY registers
*/
if (hw->mac.type == e1000_ich8lan)
@ -2419,7 +2506,7 @@ void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
* @hw: pointer to the HW structure
*
* Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC),
* LPLU, Giga disable, MDIC PHY reset):
* LPLU, Gig disable, MDIC PHY reset):
* 1) Set Kumeran Near-end loopback
* 2) Clear Kumeran Near-end loopback
* Should only be called for ICH8[m] devices with IGP_3 Phy.
@ -2436,7 +2523,7 @@ void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
goto out;
ret_val = e1000_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
&reg_data);
&reg_data);
if (ret_val)
goto out;
reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK;
@ -2446,11 +2533,39 @@ void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
goto out;
reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK;
ret_val = e1000_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
reg_data);
reg_data);
out:
return;
}
/**
* e1000_disable_gig_wol_ich8lan - disable gig during WoL
* @hw: pointer to the HW structure
*
* During S0 to Sx transition, it is possible the link remains at gig
* instead of negotiating to a lower speed. Before going to Sx, set
* 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
* to a lower speed.
*
* Should only be called for ICH9m and ICH10 devices.
**/
void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw)
{
u32 phy_ctrl;
if ((hw->mac.type == e1000_ich10lan) ||
((hw->mac.type == e1000_ich9lan) &&
((hw->device_id == E1000_DEV_ID_ICH9_IGP_M) ||
(hw->device_id == E1000_DEV_ID_ICH9_IGP_M_AMT)))) {
phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL);
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
E1000_PHY_CTRL_GBE_DISABLE;
E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
}
return;
}
/**
* e1000_cleanup_led_ich8lan - Restore the default LED operation
* @hw: pointer to the HW structure
@ -2465,8 +2580,8 @@ STATIC s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw)
if (hw->phy.type == e1000_phy_ife)
ret_val = e1000_write_phy_reg(hw,
IFE_PHY_SPECIAL_CONTROL_LED,
0);
IFE_PHY_SPECIAL_CONTROL_LED,
0);
else
E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default);
@ -2474,10 +2589,10 @@ STATIC s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw)
}
/**
* e1000_led_on_ich8lan - Turn LED's on
* e1000_led_on_ich8lan - Turn LEDs on
* @hw: pointer to the HW structure
*
* Turn on the LED's.
* Turn on the LEDs.
**/
STATIC s32 e1000_led_on_ich8lan(struct e1000_hw *hw)
{
@ -2496,10 +2611,10 @@ STATIC s32 e1000_led_on_ich8lan(struct e1000_hw *hw)
}
/**
* e1000_led_off_ich8lan - Turn LED's off
* e1000_led_off_ich8lan - Turn LEDs off
* @hw: pointer to the HW structure
*
* Turn off the LED's.
* Turn off the LEDs.
**/
STATIC s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
{
@ -2530,13 +2645,22 @@ STATIC s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
STATIC s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u32 bank = 0;
e1000_get_cfg_done_generic(hw);
/* If EEPROM is not marked present, init the IGP 3 PHY manually */
if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) &&
(hw->phy.type == e1000_phy_igp_3)) {
e1000_phy_init_script_igp3(hw);
if (hw->mac.type != e1000_ich10lan) {
if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) &&
(hw->phy.type == e1000_phy_igp_3)) {
e1000_phy_init_script_igp3(hw);
}
} else {
if (e1000_valid_nvm_bank_detect_ich8lan(hw, &bank)) {
/* Maybe we should do a basic Boazman config */
DEBUGOUT("EEPROM not present\n");
ret_val = -E1000_ERR_CONFIG;
}
}
return ret_val;

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -83,7 +83,7 @@
#define E1000_ICH8_LAN_INIT_TIMEOUT 1500
#define E1000_FEXTNVM_SW_CONFIG 1
#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */
#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M */
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
@ -113,5 +113,9 @@
E1000_IMS_PHYINT | \
E1000_IMS_EPRST)
/* Additional interrupt register bit definitions */
#define E1000_ICR_LSECPNC 0x00004000 /* PN threshold - client */
#define E1000_IMS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */
#define E1000_ICS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */
#endif

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -239,7 +239,8 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_alt_mac_addr_generic");
ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, &nvm_alt_mac_addr_offset);
ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
&nvm_alt_mac_addr_offset);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
@ -300,8 +301,8 @@ void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
* from network order (big endian) to little endian
*/
rar_low = ((u32) addr[0] |
((u32) addr[1] << 8) |
((u32) addr[2] << 16) | ((u32) addr[3] << 24));
((u32) addr[1] << 8) |
((u32) addr[2] << 16) | ((u32) addr[3] << 24));
rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
@ -311,8 +312,8 @@ void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
rar_high |= E1000_RAH_AV;
}
E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
E1000_WRITE_REG(hw, E1000_RAL(index), rar_low);
E1000_WRITE_REG(hw, E1000_RAH(index), rar_high);
}
/**
@ -486,8 +487,8 @@ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr)
*
* In certain situations, a system BIOS may report that the PCIx maximum
* memory read byte count (MMRBC) value is higher than than the actual
* value. We check the PCIx command regsiter with the current PCIx status
* regsiter.
* value. We check the PCIx command register with the current PCIx status
* register.
**/
void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw)
{
@ -505,9 +506,9 @@ void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw)
e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd);
e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word);
cmd_mmrbc = (pcix_cmd & PCIX_COMMAND_MMRBC_MASK) >>
PCIX_COMMAND_MMRBC_SHIFT;
PCIX_COMMAND_MMRBC_SHIFT;
stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
PCIX_STATUS_HI_MMRBC_SHIFT;
PCIX_STATUS_HI_MMRBC_SHIFT;
if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
if (cmd_mmrbc > stat_mmrbc) {
@ -914,7 +915,7 @@ s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw)
msec_delay(1);
/*
* For these adapters, the SW defineable pin 1 is set when the optics
* For these adapters, the SW definable pin 1 is set when the optics
* detect a signal. If we have a signal, then poll for a "Link-Up"
* indication.
*/
@ -1086,7 +1087,7 @@ s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
*
* Sets the flow control high/low threshold (watermark) registers. If
* flow control XON frame transmission is enabled, then set XON frame
* tansmission as well.
* transmission as well.
**/
s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw)
{
@ -1299,11 +1300,11 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
* flow control was negotiated.
*/
ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
&mii_nway_adv_reg);
&mii_nway_adv_reg);
if (ret_val)
goto out;
ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
&mii_nway_lp_ability_reg);
&mii_nway_lp_ability_reg);
if (ret_val)
goto out;
@ -1427,7 +1428,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
}
/**
* e1000_get_speed_and_duplex_copper_generic - Retreive current speed/duplex
* e1000_get_speed_and_duplex_copper_generic - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
@ -1466,7 +1467,7 @@ s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
}
/**
* e1000_get_speed_and_duplex_fiber_generic - Retreive current speed/duplex
* e1000_get_speed_and_duplex_fiber_generic - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
@ -1749,7 +1750,7 @@ s32 e1000_cleanup_led_generic(struct e1000_hw *hw)
* e1000_blink_led_generic - Blink LED
* @hw: pointer to the HW structure
*
* Blink the led's which are set to be on.
* Blink the LEDs which are set to be on.
**/
s32 e1000_blink_led_generic(struct e1000_hw *hw)
{
@ -1869,7 +1870,7 @@ void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop)
* @hw: pointer to the HW structure
*
* Returns 0 (E1000_SUCCESS) if successful, else returns -10
* (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not casued
* (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
* the master requests to be disabled.
*
* Disables PCI-Express master access and verifies there are no pending
@ -1985,7 +1986,7 @@ void e1000_update_adaptive_generic(struct e1000_hw *hw)
* e1000_validate_mdi_setting_generic - Verify MDI/MDIx settings
* @hw: pointer to the HW structure
*
* Verify that when not using auto-negotitation that MDI/MDIx is correctly
* Verify that when not using auto-negotiation that MDI/MDIx is correctly
* set, which is forced to MDI mode only.
**/
s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw)

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -68,7 +68,7 @@ static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
*
* Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
*
* This function checks whether the HOST IF is enabled for command operaton
* This function checks whether the HOST IF is enabled for command operation
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
@ -106,7 +106,7 @@ s32 e1000_mng_enable_host_if_generic(struct e1000_hw * hw)
}
/**
* e1000_check_mng_mode_generic - Generic check managament mode
* e1000_check_mng_mode_generic - Generic check management mode
* @hw: pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
@ -163,8 +163,8 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
for (i = 0; i < len; i++) {
*(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
E1000_HOST_IF,
offset + i);
E1000_HOST_IF,
offset + i);
}
hdr_csum = hdr->checksum;
hdr->checksum = 0;
@ -244,7 +244,7 @@ s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw * hw, u8 *buffer,
* Writes the command header after does the checksum calculation.
**/
s32 e1000_mng_write_cmd_header_generic(struct e1000_hw * hw,
struct e1000_host_mng_command_header * hdr)
struct e1000_host_mng_command_header * hdr)
{
u16 i, length = sizeof(struct e1000_host_mng_command_header);
@ -266,7 +266,7 @@ s32 e1000_mng_write_cmd_header_generic(struct e1000_hw * hw,
}
/**
* e1000_mng_host_if_write_generic - Writes to the manageability host interface
* e1000_mng_host_if_write_generic - Write to the manageability host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface buffer
* @length: size of the buffer

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -71,8 +71,8 @@ typedef enum {
#define E1000_VFTA_ENTRY_MASK 0x7F
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Number of bytes in range */
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Number of dwords in range */
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */
#define E1000_HICR_EN 0x01 /* Enable bit - RO */

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -32,7 +32,6 @@
*******************************************************************************/
/* $FreeBSD$ */
#include "e1000_api.h"
#include "e1000_nvm.h"
@ -280,7 +279,7 @@ void e1000_stop_nvm(struct e1000_hw *hw)
eecd |= E1000_EECD_CS;
e1000_lower_eec_clk(hw, &eecd);
} else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
/* CS on Microcwire is active-high */
/* CS on Microwire is active-high */
eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
e1000_raise_eec_clk(hw, &eecd);
@ -544,7 +543,7 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
* EEPROM will most likley contain an invalid checksum.
* EEPROM will most likely contain an invalid checksum.
**/
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
@ -630,7 +629,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
* Writes data to EEPROM at offset using microwire interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
* EEPROM will most likley contain an invalid checksum.
* EEPROM will most likely contain an invalid checksum.
**/
s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
@ -890,7 +889,7 @@ s32 e1000_acquire_nvm(struct e1000_hw *hw)
* @hw: pointer to the HW structure
*
* For those silicon families which have implemented a NVM release function,
* run the defined fucntion else return success.
* run the defined function else return success.
**/
void e1000_release_nvm(struct e1000_hw *hw)
{

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -44,14 +44,16 @@ s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num);
s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data);
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw);
s32 e1000_write_nvm_eewr(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw);
void e1000_stop_nvm(struct e1000_hw *hw);
void e1000_release_nvm_generic(struct e1000_hw *hw);

View File

@ -1,6 +1,6 @@
/**************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -39,6 +39,7 @@
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
STATIC void e1000_release_phy(struct e1000_hw *hw);
STATIC s32 e1000_acquire_phy(struct e1000_hw *hw);
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
/* Cable length tables */
static const u16 e1000_m88_cable_length_table[] =
@ -140,10 +141,10 @@ s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw)
* @offset: register offset to be read
* @data: pointer to the read data
*
* Reads the MDI control regsiter in the PHY at offset and stores the
* Reads the MDI control register in the PHY at offset and stores the
* information read to data.
**/
STATIC s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
{
struct e1000_phy_info *phy = &hw->phy;
u32 i, mdic = 0;
@ -203,7 +204,7 @@ STATIC s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
*
* Writes data to MDI control register in the PHY at offset.
**/
STATIC s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
{
struct e1000_phy_info *phy = &hw->phy;
u32 i, mdic = 0;
@ -336,8 +337,8 @@ s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
if (offset > MAX_PHY_MULTI_PAGE_REG) {
ret_val = e1000_write_phy_reg_mdic(hw,
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
if (ret_val) {
e1000_release_phy(hw);
goto out;
@ -345,8 +346,8 @@ s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
}
ret_val = e1000_read_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
MAX_PHY_REG_ADDRESS & offset,
data);
e1000_release_phy(hw);
@ -375,8 +376,8 @@ s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
if (offset > MAX_PHY_MULTI_PAGE_REG) {
ret_val = e1000_write_phy_reg_mdic(hw,
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
if (ret_val) {
e1000_release_phy(hw);
goto out;
@ -384,8 +385,8 @@ s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
}
ret_val = e1000_write_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
MAX_PHY_REG_ADDRESS & offset,
data);
e1000_release_phy(hw);
@ -486,7 +487,9 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
if (ret_val)
goto out;
phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
/* For newer PHYs this bit is downshift enable */
if (phy->type == e1000_phy_m88)
phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
/*
* Options:
@ -525,11 +528,17 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
if (phy->disable_polarity_correction == 1)
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
/* Enable downshift on BM (disabled by default) */
if (phy->type == e1000_phy_bm)
phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
if (phy->revision < E1000_REVISION_4) {
if ((phy->type == e1000_phy_m88) &&
(phy->revision < E1000_REVISION_4) &&
(phy->id != BME1000_E_PHY_ID_R2)) {
/*
* Force TX_CLK in the Extended PHY Specific Control Register
* to 25MHz clock.
@ -550,9 +559,9 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
} else {
/* Configure Master and Slave downshift values */
phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
}
ret_val = e1000_write_phy_reg(hw,
M88E1000_EXT_PHY_SPEC_CTRL,
@ -1348,7 +1357,7 @@ s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
}
/**
* e1000_check_downshift_generic - Checks whether a downshift in speed occured
* e1000_check_downshift_generic - Checks whether a downshift in speed occurred
* @hw: pointer to the HW structure
*
* Success returns 0, Failure returns 1
@ -1366,6 +1375,7 @@ s32 e1000_check_downshift_generic(struct e1000_hw *hw)
switch (phy->type) {
case e1000_phy_m88:
case e1000_phy_gg82563:
case e1000_phy_bm:
offset = M88E1000_PHY_SPEC_STATUS;
mask = M88E1000_PSSR_DOWNSHIFT;
break;
@ -1467,7 +1477,7 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw)
}
/**
* e1000_wait_autoneg_generic - Wait for auto-neg compeletion
* e1000_wait_autoneg_generic - Wait for auto-neg completion
* @hw: pointer to the HW structure
*
* Waits for auto-negotiation to complete or for the auto-negotiation time
@ -1586,8 +1596,8 @@ s32 e1000_get_cable_length_m88(struct e1000_hw *hw)
*
* The automatic gain control (agc) normalizes the amplitude of the
* received signal, adjusting for the attenuation produced by the
* cable. By reading the AGC registers, which reperesent the
* cobination of course and fine gain value, the value can be put
* cable. By reading the AGC registers, which represent the
* combination of coarse and fine gain value, the value can be put
* into a lookup table to obtain the approximate cable length
* for each channel.
**/
@ -1614,7 +1624,7 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
/*
* Getting bits 15:9, which represent the combination of
* course and fine gain values. The result is a number
* coarse and fine gain values. The result is a number
* that can be put into the lookup table to obtain the
* approximate cable length.
*/
@ -1837,7 +1847,7 @@ s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw)
* Verify the reset block is not blocking us from resetting. Acquire
* semaphore (if necessary) and read/set/write the device control reset
* bit in the PHY. Wait the appropriate delay time for the device to
* reset and relase the semaphore (if necessary).
* reset and release the semaphore (if necessary).
**/
s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
{
@ -1902,7 +1912,7 @@ s32 e1000_get_cfg_done_generic(struct e1000_hw *hw)
* Return success if silicon family did not implement a family specific
* get_cfg_done function.
**/
s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
{
if (hw->func.get_cfg_done)
return hw->func.get_cfg_done(hw);
@ -1917,7 +1927,7 @@ s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
* Return if silicon family does not require a semaphore when accessing the
* PHY.
**/
void e1000_release_phy(struct e1000_hw *hw)
STATIC void e1000_release_phy(struct e1000_hw *hw)
{
if (hw->func.release_phy)
hw->func.release_phy(hw);
@ -1930,7 +1940,7 @@ void e1000_release_phy(struct e1000_hw *hw)
* Return success if silicon family does not require a semaphore when
* accessing the PHY.
**/
s32 e1000_acquire_phy(struct e1000_hw *hw)
STATIC s32 e1000_acquire_phy(struct e1000_hw *hw)
{
if (hw->func.acquire_phy)
return hw->func.acquire_phy(hw);
@ -1972,7 +1982,7 @@ s32 e1000_phy_init_script_igp3(struct e1000_hw *hw)
e1000_write_phy_reg(hw, 0x2FB1, 0x8B24);
/* Increase Hybrid poly bias */
e1000_write_phy_reg(hw, 0x2FB2, 0xF8F0);
/* Add 4% to Tx amplitude in Giga mode */
/* Add 4% to Tx amplitude in Gig mode */
e1000_write_phy_reg(hw, 0x2010, 0x10B0);
/* Disable trimming (TTT) */
e1000_write_phy_reg(hw, 0x2011, 0x0000);
@ -2069,6 +2079,10 @@ e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
case IFE_C_E_PHY_ID:
phy_type = e1000_phy_ife;
break;
case BME1000_E_PHY_ID:
case BME1000_E_PHY_ID_R2:
phy_type = e1000_phy_bm;
break;
default:
phy_type = e1000_phy_unknown;
break;
@ -2076,6 +2090,395 @@ e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
return phy_type;
}
/**
* e1000_determine_phy_address - Determines PHY address.
* @hw: pointer to the HW structure
*
* This uses a trial and error method to loop through possible PHY
* addresses. It tests each by reading the PHY ID registers and
* checking for a match.
**/
s32 e1000_determine_phy_address(struct e1000_hw* hw)
{
s32 ret_val = -E1000_ERR_PHY_TYPE;
u32 phy_addr= 0;
u32 i = 0;
e1000_phy_type phy_type = e1000_phy_unknown;
do {
for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
hw->phy.addr = phy_addr;
e1000_get_phy_id(hw);
phy_type = e1000_get_phy_type_from_id(hw->phy.id);
/*
* If phy_type is valid, break - we found our
* PHY address
*/
if (phy_type != e1000_phy_unknown) {
ret_val = E1000_SUCCESS;
break;
}
}
i++;
} while ((ret_val != E1000_SUCCESS) && (i < 100));
return ret_val;
}
/**
* e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
* @page: page to access
*
* Returns the phy address for the page requested.
**/
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
{
u32 phy_addr = 2;
if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
phy_addr = 1;
return phy_addr;
}
/**
* e1000_write_phy_reg_bm - Write BM PHY register
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write at register offset
*
* Acquires semaphore, if necessary, then writes the data to PHY register
* at the offset. Release any acquired semaphores before exiting.
**/
s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
{
s32 ret_val;
u32 page_select = 0;
u32 page = offset >> IGP_PAGE_SHIFT;
u32 page_shift = 0;
DEBUGFUNC("e1000_write_phy_reg_bm");
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
ret_val = e1000_access_phy_wakeup_reg_bm(hw,
offset, &data, FALSE);
goto out;
}
ret_val = e1000_acquire_phy(hw);
if (ret_val)
goto out;
hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
if (offset > MAX_PHY_MULTI_PAGE_REG) {
/*
* Page select is register 31 for phy address 1 and 22 for
* phy address 2 and 3. Page select is shifted only for
* phy address 1.
*/
if (hw->phy.addr == 1) {
page_shift = IGP_PAGE_SHIFT;
page_select = IGP01E1000_PHY_PAGE_SELECT;
} else {
page_shift = 0;
page_select = BM_PHY_PAGE_SELECT;
}
/* Page is shifted left, PHY expects (page x 32) */
ret_val = e1000_write_phy_reg_mdic(hw, page_select,
(page << page_shift));
if (ret_val) {
e1000_release_phy(hw);
goto out;
}
}
ret_val = e1000_write_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
e1000_release_phy(hw);
out:
return ret_val;
}
/**
* e1000_read_phy_reg_bm - Read BM PHY register
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
*
* Acquires semaphore, if necessary, then reads the PHY register at offset
* and storing the retrieved information in data. Release any acquired
* semaphores before exiting.
**/
s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
{
s32 ret_val;
u32 page_select = 0;
u32 page = offset >> IGP_PAGE_SHIFT;
u32 page_shift = 0;
DEBUGFUNC("e1000_write_phy_reg_bm");
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
ret_val = e1000_access_phy_wakeup_reg_bm(hw,
offset, data, TRUE);
goto out;
}
ret_val = e1000_acquire_phy(hw);
if (ret_val)
goto out;
hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
if (offset > MAX_PHY_MULTI_PAGE_REG) {
/*
* Page select is register 31 for phy address 1 and 22 for
* phy address 2 and 3. Page select is shifted only for
* phy address 1.
*/
if (hw->phy.addr == 1) {
page_shift = IGP_PAGE_SHIFT;
page_select = IGP01E1000_PHY_PAGE_SELECT;
} else {
page_shift = 0;
page_select = BM_PHY_PAGE_SELECT;
}
/* Page is shifted left, PHY expects (page x 32) */
ret_val = e1000_write_phy_reg_mdic(hw, page_select,
(page << page_shift));
if (ret_val) {
e1000_release_phy(hw);
goto out;
}
}
ret_val = e1000_read_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset,
data);
e1000_release_phy(hw);
out:
return ret_val;
}
/**
* e1000_read_phy_reg_bm2 - Read BM PHY register
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
*
* Acquires semaphore, if necessary, then reads the PHY register at offset
* and storing the retrieved information in data. Release any acquired
* semaphores before exiting.
**/
s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
{
s32 ret_val;
u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
DEBUGFUNC("e1000_write_phy_reg_bm2");
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
TRUE);
goto out;
}
ret_val = e1000_acquire_phy(hw);
if (ret_val)
goto out;
hw->phy.addr = 1;
if (offset > MAX_PHY_MULTI_PAGE_REG) {
/* Page is shifted left, PHY expects (page x 32) */
ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
page);
if (ret_val) {
e1000_release_phy(hw);
goto out;
}
}
ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
data);
e1000_release_phy(hw);
out:
return ret_val;
}
/**
* e1000_write_phy_reg_bm2 - Write BM PHY register
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write at register offset
*
* Acquires semaphore, if necessary, then writes the data to PHY register
* at the offset. Release any acquired semaphores before exiting.
**/
s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
{
s32 ret_val;
u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
DEBUGFUNC("e1000_write_phy_reg_bm2");
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
FALSE);
goto out;
}
ret_val = e1000_acquire_phy(hw);
if (ret_val)
goto out;
hw->phy.addr = 1;
if (offset > MAX_PHY_MULTI_PAGE_REG) {
/* Page is shifted left, PHY expects (page x 32) */
ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
page);
if (ret_val) {
e1000_release_phy(hw);
goto out;
}
}
ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
data);
e1000_release_phy(hw);
out:
return ret_val;
}
/**
* e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register
* @hw: pointer to the HW structure
* @offset: register offset to be read or written
* @data: pointer to the data to read or write
* @read: determines if operation is read or write
*
* Acquires semaphore, if necessary, then reads the PHY register at offset
* and storing the retrieved information in data. Release any acquired
* semaphores before exiting. Note that procedure to read the wakeup
* registers are different. It works as such:
* 1) Set page 769, register 17, bit 2 = 1
* 2) Set page to 800 for host (801 if we were manageability)
* 3) Write the address using the address opcode (0x11)
* 4) Read or write the data using the data opcode (0x12)
* 5) Restore 769_17.2 to its original value
**/
s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw,
u32 offset, u16 *data, bool read)
{
s32 ret_val;
u16 reg = ((u16)offset) & PHY_REG_MASK;
u16 phy_reg = 0;
u8 phy_acquired = 1;
DEBUGFUNC("e1000_read_phy_wakeup_reg_bm");
ret_val = e1000_acquire_phy(hw);
if (ret_val) {
DEBUGOUT("Could not acquire PHY\n");
phy_acquired = 0;
goto out;
}
/* All operations in this function are phy address 1 */
hw->phy.addr = 1;
/* Set page 769 */
e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
(BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
if (ret_val) {
DEBUGOUT("Could not read PHY page 769\n");
goto out;
}
/* First clear bit 4 to avoid a power state change */
phy_reg &= ~(BM_WUC_HOST_WU_BIT);
ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
if (ret_val) {
DEBUGOUT("Could not clear PHY page 769 bit 4\n");
goto out;
}
/* Write bit 2 = 1, and clear bit 4 to 769_17 */
ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
phy_reg | BM_WUC_ENABLE_BIT);
if (ret_val) {
DEBUGOUT("Could not write PHY page 769 bit 2\n");
goto out;
}
/* Select page 800 */
ret_val = e1000_write_phy_reg_mdic(hw,
IGP01E1000_PHY_PAGE_SELECT,
(BM_WUC_PAGE << IGP_PAGE_SHIFT));
/* Write the page 800 offset value using opcode 0x11 */
ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
if (ret_val) {
DEBUGOUT("Could not write address opcode to page 800\n");
goto out;
}
if (read) {
/* Read the page 800 value using opcode 0x12 */
ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
data);
} else {
/* Read the page 800 value using opcode 0x12 */
ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
*data);
}
if (ret_val) {
DEBUGOUT("Could not read data value from page 800\n");
goto out;
}
/*
* Restore 769_17.2 to its original value
* Set page 769
*/
e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
(BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
/* Clear 769_17.2 */
ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
if (ret_val) {
DEBUGOUT("Could not clear PHY page 769 bit 2\n");
goto out;
}
out:
if (phy_acquired == 1)
e1000_release_phy(hw);
return ret_val;
}
/**
* e1000_power_up_phy_copper - Restore copper link in case of PHY power down
* @hw: pointer to the HW structure

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -84,8 +84,17 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
s32 e1000_determine_phy_address(struct e1000_hw* hw);
s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data,
bool read);
s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
void e1000_power_up_phy_copper(struct e1000_hw *hw);
void e1000_power_down_phy_copper(struct e1000_hw *hw);
s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
#define E1000_MAX_PHY_ADDR 4
@ -102,6 +111,17 @@ void e1000_power_down_phy_copper(struct e1000_hw *hw);
#define IGP_PAGE_SHIFT 5
#define PHY_REG_MASK 0x1F
#define BM_WUC_PAGE 800
#define BM_WUC_ADDRESS_OPCODE 0x11
#define BM_WUC_DATA_OPCODE 0x12
#define BM_WUC_ENABLE_PAGE 769
#define BM_WUC_ENABLE_REG 17
#define BM_WUC_ENABLE_BIT (1 << 2)
#define BM_WUC_HOST_WU_BIT (1 << 4)
/* BM PHY Copper Specific Control 1 */
#define BM_CS_CTRL1 16
#define BM_CR_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -57,6 +57,7 @@
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
#define E1000_RCTL 0x00100 /* Rx Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
@ -138,9 +139,9 @@
#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
#define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */
#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
#define E1000_PSRTYPE_REG(_i) (0x05480 + ((_i) * 4))
#define E1000_RAL(_i) (0x05400 + ((_i) * 8))
#define E1000_RAH(_i) (0x05404 + ((_i) * 8))
#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x054E0 + ((_i - 16) * 8)))
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x054E4 + ((_i - 16) * 8)))
#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
@ -229,46 +230,6 @@
#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_LSECTXUT 0x04300 /* LinkSec Tx Untagged Packet Count - OutPktsUntagged */
#define E1000_LSECTXPKTE 0x04304 /* LinkSec Encrypted Tx Packets Count - OutPktsEncrypted */
#define E1000_LSECTXPKTP 0x04308 /* LinkSec Protected Tx Packet Count - OutPktsProtected */
#define E1000_LSECTXOCTE 0x0430C /* LinkSec Encrypted Tx Octets Count - OutOctetsEncrypted */
#define E1000_LSECTXOCTP 0x04310 /* LinkSec Protected Tx Octets Count - OutOctetsProtected */
#define E1000_LSECRXUT 0x04314 /* LinkSec Untagged non-Strict Rx Packet Count - InPktsUntagged/InPktsNoTag */
#define E1000_LSECRXOCTD 0x0431C /* LinkSec Rx Octets Decrypted Count - InOctetsDecrypted */
#define E1000_LSECRXOCTV 0x04320 /* LinkSec Rx Octets Validated - InOctetsValidated */
#define E1000_LSECRXBAD 0x04324 /* LinkSec Rx Bad Tag - InPktsBadTag */
#define E1000_LSECRXNOSCI 0x04328 /* LinkSec Rx Packet No SCI Count - InPktsNoSci */
#define E1000_LSECRXUNSCI 0x0432C /* LinkSec Rx Packet Unknown SCI Count - InPktsUnknownSci */
#define E1000_LSECRXUNCH 0x04330 /* LinkSec Rx Unchecked Packets Count - InPktsUnchecked */
#define E1000_LSECRXDELAY 0x04340 /* LinkSec Rx Delayed Packet Count - InPktsDelayed */
#define E1000_LSECRXLATE 0x04350 /* LinkSec Rx Late Packets Count - InPktsLate */
#define E1000_LSECRXOK(_n) (0x04360 + (0x04 * (_n))) /* LinkSec Rx Packet OK Count - InPktsOk */
#define E1000_LSECRXINV(_n) (0x04380 + (0x04 * (_n))) /* LinkSec Rx Invalid Count - InPktsInvalid */
#define E1000_LSECRXNV(_n) (0x043A0 + (0x04 * (_n))) /* LinkSec Rx Not Valid Count - InPktsNotValid */
#define E1000_LSECRXUNSA 0x043C0 /* LinkSec Rx Unused SA Count - InPktsUnusedSa */
#define E1000_LSECRXNUSA 0x043D0 /* LinkSec Rx Not Using SA Count - InPktsNotUsingSa */
#define E1000_LSECTXCAP 0x0B000 /* LinkSec Tx Capabilities Register - RO */
#define E1000_LSECRXCAP 0x0B300 /* LinkSec Rx Capabilities Register - RO */
#define E1000_LSECTXCTRL 0x0B004 /* LinkSec Tx Control - RW */
#define E1000_LSECRXCTRL 0x0B304 /* LinkSec Rx Control - RW */
#define E1000_LSECTXSCIL 0x0B008 /* LinkSec Tx SCI Low - RW */
#define E1000_LSECTXSCIH 0x0B00C /* LinkSec Tx SCI High - RW */
#define E1000_LSECTXSA 0x0B010 /* LinkSec Tx SA0 - RW */
#define E1000_LSECTXPN0 0x0B018 /* LinkSec Tx SA PN 0 - RW */
#define E1000_LSECTXPN1 0x0B01C /* LinkSec Tx SA PN 1 - RW */
#define E1000_LSECRXSCL 0x0B3D0 /* LinkSec Rx SCI Low - RW */
#define E1000_LSECRXSCH 0x0B3E0 /* LinkSec Rx SCI High - RW */
#define E1000_LSECTXKEY0(_n) (0x0B020 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 0 - WO */
#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 1 - WO */
#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */
#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */
/*
* LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
* key - RW.
*/
#define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m)))
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
@ -296,7 +257,6 @@
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_PSRTYPE 0x05480 /* Packet Split Receive Type - RW */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */
#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */
@ -334,7 +294,7 @@
#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Inteface Control */
#define E1000_HICR 0x08F00 /* Host Interface Control */
/* RSS registers */
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
@ -352,5 +312,19 @@
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
/* Time Sync */
#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */
#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */
#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
#define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Message Type - RW */
#define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/**************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -30,18 +30,13 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
/*$FreeBSD$ */
/* $FreeBSD$ */
#ifndef _EM_H_DEFINED_
#define _EM_H_DEFINED_
/* Tunables */
/* Set FAST handling on by default */
#if __FreeBSD_version > 700000
#define EM_FAST_IRQ
#endif
/*
* EM_TXD: Maximum number of Transmit Descriptors
* Valid Range: 80-256 for 82542 and 82543-based adapters
@ -241,6 +236,14 @@ POSSIBILITY OF SUCH DAMAGE.
#define ETH_ADDR_LEN 6
#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */
/* Used in for 82547 10Mb Half workaround */
#define EM_PBA_BYTES_SHIFT 0xA
#define EM_TX_HEAD_ADDR_SHIFT 7
#define EM_PBA_TX_MASK 0xFFFF0000
#define EM_FIFO_HDR 0x10
#define EM_82547_PKT_THRESH 0x3e0
struct adapter;
struct em_int_delay_info {
@ -270,17 +273,23 @@ struct adapter {
/* FreeBSD operating-system-specific structures. */
struct e1000_osdep osdep;
struct device *dev;
struct resource *res_memory;
struct resource *flash_mem;
struct resource *msix_mem;
struct resource *res_ioport;
struct resource *res_interrupt;
void *int_handler_tag;
struct resource *memory;
struct resource *flash;
struct resource *msix;
struct resource *ioport;
int io_rid;
/* 82574 uses 3 int vectors */
struct resource *res[3];
void *tag[3];
int rid[3];
struct ifmedia media;
struct callout timer;
struct callout tx_fifo_timer;
int watchdog_timer;
int io_rid;
int msi;
int if_flags;
int max_frame_size;
@ -288,9 +297,14 @@ struct adapter {
struct mtx core_mtx;
struct mtx tx_mtx;
int em_insert_vlan_header;
/* Task for FAST handling */
struct task link_task;
struct task rxtx_task;
struct task rx_task;
struct task tx_task;
struct taskqueue *tq; /* private task queue */
/* Management and WOL features */
int wol;
int has_manage;
@ -325,12 +339,6 @@ struct adapter {
bus_dma_tag_t txtag; /* dma tag for tx */
uint32_t tx_tso; /* last tx was tso */
/*
* Transmit function pointer:
* legacy or advanced (82575 and later)
*/
int (*em_xmit) (struct adapter *adapter, struct mbuf **m_headp);
/*
* Receive definitions
*
@ -366,15 +374,10 @@ struct adapter {
unsigned long no_tx_dma_setup;
unsigned long watchdog_events;
unsigned long rx_overruns;
unsigned long rx_irq;
unsigned long tx_irq;
/* Used in for 82547 10Mb Half workaround */
#define EM_PBA_BYTES_SHIFT 0xA
#define EM_TX_HEAD_ADDR_SHIFT 7
#define EM_PBA_TX_MASK 0xFFFF0000
#define EM_FIFO_HDR 0x10
#define EM_82547_PKT_THRESH 0x3e0
/* 82547 workaround */
uint32_t tx_fifo_size;
uint32_t tx_fifo_head;
uint32_t tx_fifo_head_addr;
@ -386,6 +389,7 @@ struct adapter {
boolean_t pcix_82544;
boolean_t in_detach;
struct e1000_hw_stats stats;
};

View File

@ -1,6 +1,6 @@
/*******************************************************************************
/******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -29,9 +29,8 @@
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/* $FreeBSD$ */
******************************************************************************/
/*$FreeBSD$*/
/* e1000_82575
* e1000_82576
@ -40,32 +39,29 @@
#include "e1000_api.h"
#include "e1000_82575.h"
void e1000_init_function_pointers_82575(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_82575(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_82575(struct e1000_hw *hw);
STATIC s32 e1000_acquire_phy_82575(struct e1000_hw *hw);
STATIC void e1000_release_phy_82575(struct e1000_hw *hw);
STATIC s32 e1000_acquire_nvm_82575(struct e1000_hw *hw);
STATIC void e1000_release_nvm_82575(struct e1000_hw *hw);
STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw);
STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw);
STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
static s32 e1000_init_phy_params_82575(struct e1000_hw *hw);
static s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
static s32 e1000_init_mac_params_82575(struct e1000_hw *hw);
static s32 e1000_acquire_phy_82575(struct e1000_hw *hw);
static void e1000_release_phy_82575(struct e1000_hw *hw);
static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw);
static void e1000_release_nvm_82575(struct e1000_hw *hw);
static s32 e1000_check_for_link_82575(struct e1000_hw *hw);
static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw);
static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw);
STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
STATIC s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
static s32 e1000_init_hw_82575(struct e1000_hw *hw);
static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 *data);
STATIC void e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index);
STATIC s32 e1000_reset_hw_82575(struct e1000_hw *hw);
STATIC s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
static s32 e1000_reset_hw_82575(struct e1000_hw *hw);
static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
bool active);
STATIC s32 e1000_setup_copper_link_82575(struct e1000_hw *hw);
STATIC s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw);
STATIC s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw);
static s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw);
static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
u32 offset, u16 data);
STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
static s32 e1000_configure_pcs_link_82575(struct e1000_hw *hw);
static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
@ -73,9 +69,9 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
static s32 e1000_get_phy_id_82575(struct e1000_hw *hw);
static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
static bool e1000_sgmii_active_82575(struct e1000_hw *hw);
STATIC s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
STATIC s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
STATIC void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
static s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
struct e1000_dev_spec_82575 {
@ -88,10 +84,9 @@ struct e1000_dev_spec_82575 {
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_phy_params_82575");
@ -100,27 +95,27 @@ STATIC s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
phy->type = e1000_phy_none;
goto out;
} else {
func->power_up_phy = e1000_power_up_phy_copper;
func->power_down_phy = e1000_power_down_phy_copper_82575;
phy->ops.power_up = e1000_power_up_phy_copper;
phy->ops.power_down = e1000_power_down_phy_copper_82575;
}
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
phy->reset_delay_us = 100;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
phy->reset_delay_us = 100;
func->acquire_phy = e1000_acquire_phy_82575;
func->check_reset_block = e1000_check_reset_block_generic;
func->commit_phy = e1000_phy_sw_reset_generic;
func->get_cfg_done = e1000_get_cfg_done_82575;
func->release_phy = e1000_release_phy_82575;
phy->ops.acquire = e1000_acquire_phy_82575;
phy->ops.check_reset_block = e1000_check_reset_block_generic;
phy->ops.commit = e1000_phy_sw_reset_generic;
phy->ops.get_cfg_done = e1000_get_cfg_done_82575;
phy->ops.release = e1000_release_phy_82575;
if (e1000_sgmii_active_82575(hw)) {
func->reset_phy = e1000_phy_hw_reset_sgmii_82575;
func->read_phy_reg = e1000_read_phy_reg_sgmii_82575;
func->write_phy_reg = e1000_write_phy_reg_sgmii_82575;
phy->ops.reset = e1000_phy_hw_reset_sgmii_82575;
phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
} else {
func->reset_phy = e1000_phy_hw_reset_generic;
func->read_phy_reg = e1000_read_phy_reg_igp;
func->write_phy_reg = e1000_write_phy_reg_igp;
phy->ops.reset = e1000_phy_hw_reset_generic;
phy->ops.read_reg = e1000_read_phy_reg_igp;
phy->ops.write_reg = e1000_write_phy_reg_igp;
}
/* Set phy->phy_addr and phy->id. */
@ -129,20 +124,20 @@ STATIC s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
/* Verify phy id and set remaining function pointers */
switch (phy->id) {
case M88E1111_I_PHY_ID:
phy->type = e1000_phy_m88;
func->check_polarity = e1000_check_polarity_m88;
func->get_phy_info = e1000_get_phy_info_m88;
func->get_cable_length = e1000_get_cable_length_m88;
func->force_speed_duplex = e1000_phy_force_speed_duplex_m88;
phy->type = e1000_phy_m88;
phy->ops.check_polarity = e1000_check_polarity_m88;
phy->ops.get_info = e1000_get_phy_info_m88;
phy->ops.get_cable_length = e1000_get_cable_length_m88;
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
break;
case IGP03E1000_E_PHY_ID:
phy->type = e1000_phy_igp_3;
func->check_polarity = e1000_check_polarity_igp;
func->get_phy_info = e1000_get_phy_info_igp;
func->get_cable_length = e1000_get_cable_length_igp_2;
func->force_speed_duplex = e1000_phy_force_speed_duplex_igp;
func->set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
func->set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
phy->type = e1000_phy_igp_3;
phy->ops.check_polarity = e1000_check_polarity_igp;
phy->ops.get_info = e1000_get_phy_info_igp;
phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
break;
default:
ret_val = -E1000_ERR_PHY;
@ -159,10 +154,9 @@ STATIC s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
static s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
struct e1000_functions *func = &hw->func;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
u16 size;
@ -185,7 +179,7 @@ STATIC s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
break;
}
nvm->type = e1000_nvm_eeprom_spi;
nvm->type = e1000_nvm_eeprom_spi;
size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
E1000_EECD_SIZE_EX_SHIFT);
@ -202,13 +196,13 @@ STATIC s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
nvm->word_size = 1 << size;
/* Function Pointers */
func->acquire_nvm = e1000_acquire_nvm_82575;
func->read_nvm = e1000_read_nvm_eerd;
func->release_nvm = e1000_release_nvm_82575;
func->update_nvm = e1000_update_nvm_checksum_generic;
func->valid_led_default = e1000_valid_led_default_generic;
func->validate_nvm = e1000_validate_nvm_checksum_generic;
func->write_nvm = e1000_write_nvm_spi;
nvm->ops.acquire = e1000_acquire_nvm_82575;
nvm->ops.read = e1000_read_nvm_eerd;
nvm->ops.release = e1000_release_nvm_82575;
nvm->ops.update = e1000_update_nvm_checksum_generic;
nvm->ops.valid_led_default = e1000_valid_led_default_generic;
nvm->ops.validate = e1000_validate_nvm_checksum_generic;
nvm->ops.write = e1000_write_nvm_spi;
return E1000_SUCCESS;
}
@ -219,10 +213,9 @@ STATIC s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
struct e1000_functions *func = &hw->func;
struct e1000_dev_spec_82575 *dev_spec;
u32 ctrl_ext = 0;
s32 ret_val = E1000_SUCCESS;
@ -276,47 +269,47 @@ STATIC s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
/* Function pointers */
/* bus type/speed/width */
func->get_bus_info = e1000_get_bus_info_pcie_generic;
mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
/* reset */
func->reset_hw = e1000_reset_hw_82575;
mac->ops.reset_hw = e1000_reset_hw_82575;
/* hw initialization */
func->init_hw = e1000_init_hw_82575;
mac->ops.init_hw = e1000_init_hw_82575;
/* link setup */
func->setup_link = e1000_setup_link_generic;
mac->ops.setup_link = e1000_setup_link_generic;
/* physical interface link setup */
func->setup_physical_interface =
mac->ops.setup_physical_interface =
(hw->phy.media_type == e1000_media_type_copper)
? e1000_setup_copper_link_82575
: e1000_setup_fiber_serdes_link_82575;
/* check for link */
func->check_for_link = e1000_check_for_link_82575;
mac->ops.check_for_link = e1000_check_for_link_82575;
/* receive address register setting */
func->rar_set = e1000_rar_set_82575;
mac->ops.rar_set = e1000_rar_set_generic;
/* read mac address */
func->read_mac_addr = e1000_read_mac_addr_82575;
mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
/* multicast address update */
func->update_mc_addr_list = e1000_update_mc_addr_list_generic;
mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
/* writing VFTA */
func->write_vfta = e1000_write_vfta_generic;
mac->ops.write_vfta = e1000_write_vfta_generic;
/* clearing VFTA */
func->clear_vfta = e1000_clear_vfta_generic;
mac->ops.clear_vfta = e1000_clear_vfta_generic;
/* setting MTA */
func->mta_set = e1000_mta_set_generic;
mac->ops.mta_set = e1000_mta_set_generic;
/* blink LED */
func->blink_led = e1000_blink_led_generic;
mac->ops.blink_led = e1000_blink_led_generic;
/* setup LED */
func->setup_led = e1000_setup_led_generic;
mac->ops.setup_led = e1000_setup_led_generic;
/* cleanup LED */
func->cleanup_led = e1000_cleanup_led_generic;
mac->ops.cleanup_led = e1000_cleanup_led_generic;
/* turn on/off LED */
func->led_on = e1000_led_on_generic;
func->led_off = e1000_led_off_generic;
mac->ops.led_on = e1000_led_on_generic;
mac->ops.led_off = e1000_led_off_generic;
/* remove device */
func->remove_device = e1000_remove_device_generic;
mac->ops.remove_device = e1000_remove_device_generic;
/* clear hardware counters */
func->clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
/* link info */
func->get_link_up_info = e1000_get_link_up_info_82575;
mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
out:
return ret_val;
@ -333,9 +326,9 @@ void e1000_init_function_pointers_82575(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_init_function_pointers_82575");
hw->func.init_mac_params = e1000_init_mac_params_82575;
hw->func.init_nvm_params = e1000_init_nvm_params_82575;
hw->func.init_phy_params = e1000_init_phy_params_82575;
hw->mac.ops.init_params = e1000_init_mac_params_82575;
hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
hw->phy.ops.init_params = e1000_init_phy_params_82575;
}
/**
@ -345,7 +338,7 @@ void e1000_init_function_pointers_82575(struct e1000_hw *hw)
* Acquire access rights to the correct PHY. This is a
* function pointer entry point called by the api module.
**/
STATIC s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
{
u16 mask;
@ -363,7 +356,7 @@ STATIC s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
* A wrapper to release access rights to the correct PHY. This is a
* function pointer entry point called by the api module.
**/
STATIC void e1000_release_phy_82575(struct e1000_hw *hw)
static void e1000_release_phy_82575(struct e1000_hw *hw)
{
u16 mask;
@ -382,7 +375,7 @@ STATIC void e1000_release_phy_82575(struct e1000_hw *hw)
* Reads the PHY register at offset using the serial gigabit media independent
* interface and stores the retrieved information in data.
**/
STATIC s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 *data)
{
struct e1000_phy_info *phy = &hw->phy;
@ -437,7 +430,7 @@ STATIC s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
* Writes the data to PHY register at the offset using the serial gigabit
* media independent interface.
**/
STATIC s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 data)
{
struct e1000_phy_info *phy = &hw->phy;
@ -486,10 +479,10 @@ STATIC s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
}
/**
* e1000_get_phy_id_82575 - Retreive PHY addr and id
* e1000_get_phy_id_82575 - Retrieve PHY addr and id
* @hw: pointer to the HW structure
*
* Retreives the PHY address and ID for both PHY's which do and do not use
* Retrieves the PHY address and ID for both PHY's which do and do not use
* sgmi interface.
**/
static s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
@ -554,9 +547,9 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
*
* Resets the PHY using the serial gigabit media independent interface.
**/
STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
{
s32 ret_val;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
@ -567,15 +560,18 @@ STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
DEBUGOUT("Soft resetting SGMII attached PHY...\n");
if (!(hw->phy.ops.write_reg))
goto out;
/*
* SFP documentation requires the following to configure the SPF module
* to work on SGMII. No further documentation is given.
*/
ret_val = e1000_write_phy_reg(hw, 0x1B, 0x8084);
ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
if (ret_val)
goto out;
ret_val = e1000_phy_commit(hw);
ret_val = hw->phy.ops.commit(hw);
out:
return ret_val;
@ -594,41 +590,40 @@ STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
* This is a function pointer entry point only called by
* PHY setup routines.
**/
STATIC s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val;
s32 ret_val = E1000_SUCCESS;
u16 data;
DEBUGFUNC("e1000_set_d0_lplu_state_82575");
ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (!(hw->phy.ops.read_reg))
goto out;
ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
if (active) {
data |= IGP02E1000_PM_D0_LPLU;
ret_val = e1000_write_phy_reg(hw,
IGP02E1000_PHY_POWER_MGMT,
data);
ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
goto out;
/* When LPLU is enabled, we should disable SmartSpeed */
ret_val = e1000_read_phy_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&data);
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1000_write_phy_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
} else {
data &= ~IGP02E1000_PM_D0_LPLU;
ret_val = e1000_write_phy_reg(hw,
IGP02E1000_PHY_POWER_MGMT,
data);
ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
/*
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
* during Dx states where the power conservation is most
@ -636,27 +631,27 @@ STATIC s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
* SmartSpeed, so performance is maintained.
*/
if (phy->smart_speed == e1000_smart_speed_on) {
ret_val = e1000_read_phy_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data |= IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1000_write_phy_reg(hw,
ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
} else if (phy->smart_speed == e1000_smart_speed_off) {
ret_val = e1000_read_phy_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1000_write_phy_reg(hw,
ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
@ -672,12 +667,12 @@ STATIC s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
* e1000_acquire_nvm_82575 - Request for access to EEPROM
* @hw: pointer to the HW structure
*
* Acquire the necessary semaphores for exclussive access to the EEPROM.
* Acquire the necessary semaphores for exclusive access to the EEPROM.
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
STATIC s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
{
s32 ret_val;
@ -703,7 +698,7 @@ STATIC s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
* Stop any current commands to the EEPROM and clear the EEPROM request bit,
* then release the semaphores acquired.
**/
STATIC void e1000_release_nvm_82575(struct e1000_hw *hw)
static void e1000_release_nvm_82575(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_release_nvm_82575");
@ -797,7 +792,7 @@ static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
* E1000_SUCCESS. If we were to return with error, EEPROM-less silicon
* would not be able to be reset or change link.
**/
STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
{
s32 timeout = PHY_CFG_TIMEOUT;
s32 ret_val = E1000_SUCCESS;
@ -834,10 +829,10 @@ STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
* @duplex: stores the current duplex
*
* This is a wrapper function, if using the serial gigabit media independent
* interface, use pcs to retreive the link speed and duplex information.
* interface, use PCS to retrieve the link speed and duplex information.
* Otherwise, use the generic function to get the link speed and duplex info.
**/
STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
u16 *duplex)
{
s32 ret_val;
@ -863,7 +858,7 @@ STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
* If sgmii is enabled, then use the pcs register to determine link, otherwise
* use the generic interface for determining link.
**/
STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw)
static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
{
s32 ret_val;
u16 speed, duplex;
@ -887,11 +882,11 @@ STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw)
* @speed: stores the current speed
* @duplex: stores the current duplex
*
* Using the physical coding sub-layer (PCS), retreive the current speed and
* Using the physical coding sub-layer (PCS), retrieve the current speed and
* duplex, then store the values in the pointers provided.
**/
static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
u16 *duplex)
static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
u16 *speed, u16 *duplex)
{
struct e1000_mac_info *mac = &hw->mac;
u32 pcs;
@ -938,26 +933,6 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
return E1000_SUCCESS;
}
/**
* e1000_rar_set_82575 - Set receive address register
* @hw: pointer to the HW structure
* @addr: pointer to the receive address
* @index: receive address array register
*
* Sets the receive address array register at index to the address passed
* in by addr.
**/
void e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index)
{
DEBUGFUNC("e1000_rar_set_82575");
if (index < E1000_RAR_ENTRIES_82575) {
e1000_rar_set_generic(hw, addr, index);
}
return;
}
/**
* e1000_reset_hw_82575 - Reset hardware
* @hw: pointer to the HW structure
@ -965,7 +940,7 @@ void e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index)
* This resets the hardware into a known state. This is a
* function pointer entry point called by the api module.
**/
STATIC s32 e1000_reset_hw_82575(struct e1000_hw *hw)
static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
{
u32 ctrl, icr;
s32 ret_val;
@ -1024,7 +999,7 @@ STATIC s32 e1000_reset_hw_82575(struct e1000_hw *hw)
*
* This inits the hardware readying it for operation.
**/
STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw)
static s32 e1000_init_hw_82575(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
s32 ret_val;
@ -1041,7 +1016,7 @@ STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw)
/* Disabling VLAN filtering */
DEBUGOUT("Initializing the IEEE VLAN\n");
e1000_clear_vfta(hw);
mac->ops.clear_vfta(hw);
/* Setup the receive address */
e1000_init_rx_addrs_generic(hw, rar_count);
@ -1051,7 +1026,7 @@ STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw)
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
/* Setup link and flow control */
ret_val = e1000_setup_link(hw);
ret_val = mac->ops.setup_link(hw);
/*
* Clear all of the statistics registers (clear on read). It is
@ -1072,7 +1047,7 @@ STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw)
* for link, once link is established calls to configure collision distance
* and flow control are called.
**/
STATIC s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
{
u32 ctrl, led_ctrl;
s32 ret_val;
@ -1119,7 +1094,7 @@ STATIC s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
* depending on user settings.
*/
DEBUGOUT("Forcing Speed and Duplex\n");
ret_val = e1000_phy_force_speed_duplex(hw);
ret_val = hw->phy.ops.force_speed_duplex(hw);
if (ret_val) {
DEBUGOUT("Error Forcing Speed and Duplex\n");
goto out;
@ -1160,7 +1135,7 @@ STATIC s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
*
* Configures speed and duplex for fiber and serdes links.
**/
STATIC s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
static s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
{
u32 reg;
@ -1256,7 +1231,7 @@ static s32 e1000_configure_pcs_link_82575(struct e1000_hw *hw)
*/
reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE;
} else {
/* Set PCS regiseter for forced speed */
/* Set PCS register for forced speed */
/* Turn off bits for full duplex, speed, and autoneg */
reg &= ~(E1000_PCS_LCTL_FSV_1000 |
@ -1321,7 +1296,7 @@ static bool e1000_sgmii_active_82575(struct e1000_hw *hw)
* Inits recommended HW defaults after a reset when there is no EEPROM
* detected. This is only for the 82575.
**/
STATIC s32 e1000_reset_init_script_82575(struct e1000_hw* hw)
static s32 e1000_reset_init_script_82575(struct e1000_hw* hw)
{
DEBUGFUNC("e1000_reset_init_script_82575");
@ -1356,7 +1331,7 @@ STATIC s32 e1000_reset_init_script_82575(struct e1000_hw* hw)
* e1000_read_mac_addr_82575 - Read device MAC address
* @hw: pointer to the HW structure
**/
STATIC s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
@ -1374,10 +1349,16 @@ STATIC s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
* In the case of a PHY power down to save power, or to turn off link during a
* driver unload, or wake on lan is not enabled, remove the link.
**/
STATIC void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
struct e1000_mac_info *mac = &hw->mac;
if (!(phy->ops.check_reset_block))
return;
/* If the management interface is not enabled, then power down */
if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw)))
if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw)))
e1000_power_down_phy_copper(hw);
return;
@ -1389,7 +1370,7 @@ STATIC void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
*
* Clears the hardware counters by reading the counter registers.
**/
STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
{
volatile u32 temp;

View File

@ -1,6 +1,6 @@
/*******************************************************************************
/******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -29,9 +29,8 @@
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/* $FreeBSD$ */
******************************************************************************/
/*$FreeBSD$*/
#ifndef _E1000_82575_H_
#define _E1000_82575_H_
@ -80,6 +79,8 @@ struct e1000_adv_data_desc {
#define E1000_ADV_DCMD_RS 0x8 /* Report Status */
#define E1000_ADV_DCMD_VLE 0x40 /* Add VLAN tag */
#define E1000_ADV_DCMD_TSE 0x80 /* TCP Seg enable */
/* Extended Device Control */
#define E1000_CTRL_EXT_NSICR 0x00000001 /* Disable Intr Clear all on read */
struct e1000_adv_context_desc {
union {
@ -161,7 +162,7 @@ struct e1000_adv_context_desc {
#define E1000_IMIREXT_CTRL_RST 0x00010000 /* Check RST bit in header */
#define E1000_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */
#define E1000_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */
#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of control bits */
#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of ctrl bits */
/* Receive Descriptor - Advanced */
union e1000_adv_rx_desc {
@ -171,10 +172,13 @@ union e1000_adv_rx_desc {
} read;
struct {
struct {
struct {
u16 pkt_info; /* RSS type, Packet type */
u16 hdr_info; /* Split Header,
* header buffer length */
union {
u32 data;
struct {
u16 pkt_info; /* RSS type, Packet type */
u16 hdr_info; /* Split Header,
* header buffer length */
} hs_rss;
} lo_dword;
union {
u32 rss; /* RSS Hash */
@ -242,17 +246,14 @@ union e1000_adv_tx_desc {
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_ADVTXD_DCMD_RDMA 0x04000000 /* RDMA */
#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
#define E1000_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
#define E1000_ADVTXD_MAC_LINKSEC 0x00040000 /* Apply LinkSec on packet */
#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
#define E1000_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED present in WB */
#define E1000_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
#define E1000_ADVTXD_POPTS_EOM 0x00000400 /* Enable L bit in RDMA DDP hdr */
#define E1000_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */

1063
sys/dev/igb/e1000_api.c Normal file

File diff suppressed because it is too large Load Diff

153
sys/dev/igb/e1000_api.h Normal file
View File

@ -0,0 +1,153 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _E1000_API_H_
#define _E1000_API_H_
#include "e1000_hw.h"
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
s32 e1000_set_mac_type(struct e1000_hw *hw);
s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
s32 e1000_init_mac_params(struct e1000_hw *hw);
s32 e1000_init_nvm_params(struct e1000_hw *hw);
s32 e1000_init_phy_params(struct e1000_hw *hw);
void e1000_remove_device(struct e1000_hw *hw);
s32 e1000_get_bus_info(struct e1000_hw *hw);
void e1000_clear_vfta(struct e1000_hw *hw);
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
s32 e1000_force_mac_fc(struct e1000_hw *hw);
s32 e1000_check_for_link(struct e1000_hw *hw);
s32 e1000_reset_hw(struct e1000_hw *hw);
s32 e1000_init_hw(struct e1000_hw *hw);
s32 e1000_setup_link(struct e1000_hw *hw);
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 e1000_disable_pcie_master(struct e1000_hw *hw);
void e1000_config_collision_dist(struct e1000_hw *hw);
void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
void e1000_mta_set(struct e1000_hw *hw, u32 hash_value);
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
void e1000_update_mc_addr_list(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count);
s32 e1000_setup_led(struct e1000_hw *hw);
s32 e1000_cleanup_led(struct e1000_hw *hw);
s32 e1000_check_reset_block(struct e1000_hw *hw);
s32 e1000_blink_led(struct e1000_hw *hw);
s32 e1000_led_on(struct e1000_hw *hw);
s32 e1000_led_off(struct e1000_hw *hw);
void e1000_reset_adaptive(struct e1000_hw *hw);
void e1000_update_adaptive(struct e1000_hw *hw);
s32 e1000_get_cable_length(struct e1000_hw *hw);
s32 e1000_validate_mdi_setting(struct e1000_hw *hw);
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
s32 e1000_get_phy_info(struct e1000_hw *hw);
void e1000_release_phy(struct e1000_hw *hw);
s32 e1000_acquire_phy(struct e1000_hw *hw);
s32 e1000_phy_hw_reset(struct e1000_hw *hw);
s32 e1000_phy_commit(struct e1000_hw *hw);
void e1000_power_up_phy(struct e1000_hw *hw);
void e1000_power_down_phy(struct e1000_hw *hw);
s32 e1000_read_mac_addr(struct e1000_hw *hw);
s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *part_num);
void e1000_reload_nvm(struct e1000_hw *hw);
s32 e1000_update_nvm_checksum(struct e1000_hw *hw);
s32 e1000_validate_nvm_checksum(struct e1000_hw *hw);
s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_wait_autoneg(struct e1000_hw *hw);
s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
bool e1000_check_mng_mode(struct e1000_hw *hw);
bool e1000_enable_mng_pass_thru(struct e1000_hw *hw);
bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
s32 e1000_mng_enable_host_if(struct e1000_hw *hw);
s32 e1000_mng_host_if_write(struct e1000_hw *hw,
u8 *buffer, u16 length, u16 offset, u8 *sum);
s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr);
s32 e1000_mng_write_dhcp_info(struct e1000_hw * hw,
u8 *buffer, u16 length);
/*
* TBI_ACCEPT macro definition:
*
* This macro requires:
* adapter = a pointer to struct e1000_hw
* status = the 8 bit status field of the Rx descriptor with EOP set
* error = the 8 bit error field of the Rx descriptor with EOP set
* length = the sum of all the length fields of the Rx descriptors that
* make up the current frame
* last_byte = the last byte of the frame DMAed by the hardware
* max_frame_length = the maximum frame length we want to accept.
* min_frame_length = the minimum frame length we want to accept.
*
* This macro is a conditional that should be used in the interrupt
* handler's Rx processing routine when RxErrors have been detected.
*
* Typical use:
* ...
* if (TBI_ACCEPT) {
* accept_frame = TRUE;
* e1000_tbi_adjust_stats(adapter, MacAddress);
* frame_length--;
* } else {
* accept_frame = FALSE;
* }
* ...
*/
/* The carrier extension symbol, as received by the NIC. */
#define CARRIER_EXTENSION 0x0F
#define TBI_ACCEPT(a, status, errors, length, last_byte, min_frame_size, max_frame_size) \
(e1000_tbi_sbp_enabled_82543(a) && \
(((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
((last_byte) == CARRIER_EXTENSION) && \
(((status) & E1000_RXD_STAT_VP) ? \
(((length) > (min_frame_size - VLAN_TAG_SIZE)) && \
((length) <= (max_frame_size + 1))) : \
(((length) > min_frame_size) && \
((length) <= (max_frame_size + VLAN_TAG_SIZE + 1)))))
#endif

1402
sys/dev/igb/e1000_defines.h Normal file

File diff suppressed because it is too large Load Diff

627
sys/dev/igb/e1000_hw.h Normal file
View File

@ -0,0 +1,627 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _E1000_HW_H_
#define _E1000_HW_H_
#include "e1000_osdep.h"
#include "e1000_regs.h"
#include "e1000_defines.h"
struct e1000_hw;
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
#define E1000_REVISION_0 0
#define E1000_REVISION_1 1
#define E1000_REVISION_2 2
#define E1000_REVISION_3 3
#define E1000_REVISION_4 4
#define E1000_FUNC_0 0
#define E1000_FUNC_1 1
typedef enum {
e1000_undefined = 0,
e1000_82575,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
} e1000_mac_type;
typedef enum {
e1000_media_type_unknown = 0,
e1000_media_type_copper = 1,
e1000_media_type_fiber = 2,
e1000_media_type_internal_serdes = 3,
e1000_num_media_types
} e1000_media_type;
typedef enum {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
e1000_nvm_eeprom_microwire,
e1000_nvm_flash_hw,
e1000_nvm_flash_sw
} e1000_nvm_type;
typedef enum {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large,
e1000_nvm_override_microwire_small,
e1000_nvm_override_microwire_large
} e1000_nvm_override;
typedef enum {
e1000_phy_unknown = 0,
e1000_phy_none,
e1000_phy_m88,
e1000_phy_igp,
e1000_phy_igp_2,
e1000_phy_gg82563,
e1000_phy_igp_3,
e1000_phy_ife,
} e1000_phy_type;
typedef enum {
e1000_bus_type_unknown = 0,
e1000_bus_type_pci,
e1000_bus_type_pcix,
e1000_bus_type_pci_express,
e1000_bus_type_reserved
} e1000_bus_type;
typedef enum {
e1000_bus_speed_unknown = 0,
e1000_bus_speed_33,
e1000_bus_speed_66,
e1000_bus_speed_100,
e1000_bus_speed_120,
e1000_bus_speed_133,
e1000_bus_speed_2500,
e1000_bus_speed_5000,
e1000_bus_speed_reserved
} e1000_bus_speed;
typedef enum {
e1000_bus_width_unknown = 0,
e1000_bus_width_pcie_x1,
e1000_bus_width_pcie_x2,
e1000_bus_width_pcie_x4 = 4,
e1000_bus_width_pcie_x8 = 8,
e1000_bus_width_32,
e1000_bus_width_64,
e1000_bus_width_reserved
} e1000_bus_width;
typedef enum {
e1000_1000t_rx_status_not_ok = 0,
e1000_1000t_rx_status_ok,
e1000_1000t_rx_status_undefined = 0xFF
} e1000_1000t_rx_status;
typedef enum {
e1000_rev_polarity_normal = 0,
e1000_rev_polarity_reversed,
e1000_rev_polarity_undefined = 0xFF
} e1000_rev_polarity;
typedef enum {
e1000_fc_none = 0,
e1000_fc_rx_pause,
e1000_fc_tx_pause,
e1000_fc_full,
e1000_fc_default = 0xFF
} e1000_fc_type;
/* Receive Descriptor */
struct e1000_rx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
u16 length; /* Length of data DMAed into data buffer */
u16 csum; /* Packet checksum */
u8 status; /* Descriptor status */
u8 errors; /* Descriptor Errors */
u16 special;
};
/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
struct {
u64 buffer_addr;
u64 reserved;
} read;
struct {
struct {
u32 mrq; /* Multiple Rx Queues */
union {
u32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length;
u16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define MAX_PS_BUFFERS 4
/* Receive Descriptor - Packet Split */
union e1000_rx_desc_packet_split {
struct {
/* one buffer for protocol header(s), three data buffers */
u64 buffer_addr[MAX_PS_BUFFERS];
} read;
struct {
struct {
u32 mrq; /* Multiple Rx Queues */
union {
u32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length0; /* length of buffer 0 */
u16 vlan; /* VLAN tag */
} middle;
struct {
u16 header_status;
u16 length[3]; /* length of buffers 1-3 */
} upper;
u64 reserved;
} wb; /* writeback */
};
/* Transmit Descriptor */
struct e1000_tx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
union {
u32 data;
struct {
u16 length; /* Data buffer length */
u8 cso; /* Checksum offset */
u8 cmd; /* Descriptor control */
} flags;
} lower;
union {
u32 data;
struct {
u8 status; /* Descriptor status */
u8 css; /* Checksum start */
u16 special;
} fields;
} upper;
};
/* Offload Context Descriptor */
struct e1000_context_desc {
union {
u32 ip_config;
struct {
u8 ipcss; /* IP checksum start */
u8 ipcso; /* IP checksum offset */
u16 ipcse; /* IP checksum end */
} ip_fields;
} lower_setup;
union {
u32 tcp_config;
struct {
u8 tucss; /* TCP checksum start */
u8 tucso; /* TCP checksum offset */
u16 tucse; /* TCP checksum end */
} tcp_fields;
} upper_setup;
u32 cmd_and_length;
union {
u32 data;
struct {
u8 status; /* Descriptor status */
u8 hdr_len; /* Header length */
u16 mss; /* Maximum segment size */
} fields;
} tcp_seg_setup;
};
/* Offload data descriptor */
struct e1000_data_desc {
u64 buffer_addr; /* Address of the descriptor's buffer address */
union {
u32 data;
struct {
u16 length; /* Data buffer length */
u8 typ_len_ext;
u8 cmd;
} flags;
} lower;
union {
u32 data;
struct {
u8 status; /* Descriptor status */
u8 popts; /* Packet Options */
u16 special;
} fields;
} upper;
};
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
u64 crcerrs;
u64 algnerrc;
u64 symerrs;
u64 rxerrc;
u64 mpc;
u64 scc;
u64 ecol;
u64 mcc;
u64 latecol;
u64 colc;
u64 dc;
u64 tncrs;
u64 sec;
u64 cexterr;
u64 rlec;
u64 xonrxc;
u64 xontxc;
u64 xoffrxc;
u64 xofftxc;
u64 fcruc;
u64 prc64;
u64 prc127;
u64 prc255;
u64 prc511;
u64 prc1023;
u64 prc1522;
u64 gprc;
u64 bprc;
u64 mprc;
u64 gptc;
u64 gorc;
u64 gotc;
u64 rnbc;
u64 ruc;
u64 rfc;
u64 roc;
u64 rjc;
u64 mgprc;
u64 mgpdc;
u64 mgptc;
u64 tor;
u64 tot;
u64 tpr;
u64 tpt;
u64 ptc64;
u64 ptc127;
u64 ptc255;
u64 ptc511;
u64 ptc1023;
u64 ptc1522;
u64 mptc;
u64 bptc;
u64 tsctc;
u64 tsctfc;
u64 iac;
u64 icrxptc;
u64 icrxatc;
u64 ictxptc;
u64 ictxatc;
u64 ictxqec;
u64 ictxqmtc;
u64 icrxdmtc;
u64 icrxoc;
u64 cbtmpc;
u64 htdpmc;
u64 cbrdpc;
u64 cbrmpc;
u64 rpthc;
u64 hgptc;
u64 htcbdpc;
u64 hgorc;
u64 hgotc;
u64 lenerrs;
u64 scvpc;
u64 hrmpc;
};
struct e1000_phy_stats {
u32 idle_errors;
u32 receive_errors;
};
struct e1000_host_mng_dhcp_cookie {
u32 signature;
u8 status;
u8 reserved0;
u16 vlan_id;
u32 reserved1;
u16 reserved2;
u8 reserved3;
u8 checksum;
};
/* Host Interface "Rev 1" */
struct e1000_host_command_header {
u8 command_id;
u8 command_length;
u8 command_options;
u8 checksum;
};
#define E1000_HI_MAX_DATA_LENGTH 252
struct e1000_host_command_info {
struct e1000_host_command_header command_header;
u8 command_data[E1000_HI_MAX_DATA_LENGTH];
};
/* Host Interface "Rev 2" */
struct e1000_host_mng_command_header {
u8 command_id;
u8 checksum;
u16 reserved1;
u16 reserved2;
u16 command_length;
};
#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
struct e1000_host_mng_command_info {
struct e1000_host_mng_command_header command_header;
u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
};
#include "e1000_mac.h"
#include "e1000_phy.h"
#include "e1000_nvm.h"
#include "e1000_manage.h"
struct e1000_mac_operations {
/* Function pointers for the MAC. */
s32 (*init_params)(struct e1000_hw *);
s32 (*blink_led)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *hw);
s32 (*cleanup_led)(struct e1000_hw *);
void (*clear_hw_cntrs)(struct e1000_hw *);
void (*clear_vfta)(struct e1000_hw *);
s32 (*get_bus_info)(struct e1000_hw *);
s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
s32 (*led_on)(struct e1000_hw *);
s32 (*led_off)(struct e1000_hw *);
void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32,
u32);
void (*remove_device)(struct e1000_hw *);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
s32 (*setup_link)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
s32 (*setup_led)(struct e1000_hw *);
void (*write_vfta)(struct e1000_hw *, u32, u32);
void (*mta_set)(struct e1000_hw *, u32);
void (*config_collision_dist)(struct e1000_hw*);
void (*rar_set)(struct e1000_hw*, u8*, u32);
s32 (*read_mac_addr)(struct e1000_hw*);
s32 (*validate_mdi_setting)(struct e1000_hw*);
s32 (*mng_host_if_write)(struct e1000_hw*, u8*, u16, u16, u8*);
s32 (*mng_write_cmd_header)(struct e1000_hw *hw,
struct e1000_host_mng_command_header*);
s32 (*mng_enable_host_if)(struct e1000_hw*);
s32 (*wait_autoneg)(struct e1000_hw*);
};
struct e1000_phy_operations {
s32 (*init_params)(struct e1000_hw *);
s32 (*acquire)(struct e1000_hw *);
s32 (*check_polarity)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*commit)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_info)(struct e1000_hw *);
s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
void (*release)(struct e1000_hw *);
s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
s32 (*write_reg)(struct e1000_hw *, u32, u16);
void (*power_up)(struct e1000_hw *);
void (*power_down)(struct e1000_hw *);
};
struct e1000_nvm_operations {
s32 (*init_params)(struct e1000_hw *);
s32 (*acquire)(struct e1000_hw *);
s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
void (*release)(struct e1000_hw *);
void (*reload)(struct e1000_hw *);
s32 (*update)(struct e1000_hw *);
s32 (*valid_led_default)(struct e1000_hw *, u16 *);
s32 (*validate)(struct e1000_hw *);
s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
};
struct e1000_mac_info {
struct e1000_mac_operations ops;
u8 addr[6];
u8 perm_addr[6];
e1000_mac_type type;
u32 collision_delta;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 mc_filter_type;
u32 tx_packet_delta;
u32 txcw;
u16 current_ifs_val;
u16 ifs_max_val;
u16 ifs_min_val;
u16 ifs_ratio;
u16 ifs_step_size;
u16 mta_reg_count;
u16 rar_entry_count;
u8 forced_speed_duplex;
bool adaptive_ifs;
bool arc_subsystem_valid;
bool asf_firmware_present;
bool autoneg;
bool autoneg_failed;
bool disable_av;
bool disable_hw_init_bits;
bool get_link_status;
bool ifs_params_forced;
bool in_ifs_mode;
bool report_tx_early;
bool serdes_has_link;
bool tx_pkt_filtering;
};
struct e1000_phy_info {
struct e1000_phy_operations ops;
e1000_phy_type type;
e1000_1000t_rx_status local_rx;
e1000_1000t_rx_status remote_rx;
e1000_ms_type ms_type;
e1000_ms_type original_ms_type;
e1000_rev_polarity cable_polarity;
e1000_smart_speed smart_speed;
u32 addr;
u32 id;
u32 reset_delay_us; /* in usec */
u32 revision;
e1000_media_type media_type;
u16 autoneg_advertised;
u16 autoneg_mask;
u16 cable_length;
u16 max_cable_length;
u16 min_cable_length;
u8 mdix;
bool disable_polarity_correction;
bool is_mdix;
bool polarity_correction;
bool reset_disable;
bool speed_downgraded;
bool autoneg_wait_to_complete;
};
struct e1000_nvm_info {
struct e1000_nvm_operations ops;
e1000_nvm_type type;
e1000_nvm_override override;
u32 flash_bank_size;
u32 flash_base_addr;
u16 word_size;
u16 delay_usec;
u16 address_bits;
u16 opcode_bits;
u16 page_size;
};
struct e1000_bus_info {
e1000_bus_type type;
e1000_bus_speed speed;
e1000_bus_width width;
u32 snoop;
u16 func;
u16 pci_cmd_word;
};
struct e1000_fc_info {
u32 high_water; /* Flow control high-water mark */
u32 low_water; /* Flow control low-water mark */
u16 pause_time; /* Flow control pause timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
e1000_fc_type type; /* Type of flow control */
e1000_fc_type original_type;
};
struct e1000_hw {
void *back;
void *dev_spec;
u8 *hw_addr;
u8 *flash_address;
unsigned long io_base;
struct e1000_mac_info mac;
struct e1000_fc_info fc;
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
struct e1000_host_mng_dhcp_cookie mng_cookie;
u32 dev_spec_size;
u16 device_id;
u16 subsystem_vendor_id;
u16 subsystem_device_id;
u16 vendor_id;
u8 revision_id;
};
/* These functions must be implemented by drivers */
void e1000_pci_clear_mwi(struct e1000_hw *hw);
void e1000_pci_set_mwi(struct e1000_hw *hw);
s32 e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, u32 size);
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
void e1000_free_dev_spec_struct(struct e1000_hw *hw);
void e1000_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
void e1000_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
#endif

2172
sys/dev/igb/e1000_mac.c Normal file

File diff suppressed because it is too large Load Diff

101
sys/dev/igb/e1000_mac.h Normal file
View File

@ -0,0 +1,101 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _E1000_MAC_H_
#define _E1000_MAC_H_
/*
* Functions that should not be called directly from drivers but can be used
* by other files in this 'shared code'
*/
void e1000_init_mac_ops_generic(struct e1000_hw *hw);
void e1000_null_mac_generic(struct e1000_hw *hw);
s32 e1000_null_ops_generic(struct e1000_hw *hw);
s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
bool e1000_null_mng_mode(struct e1000_hw *hw);
void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a, u32 b, u32 c);
void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
void e1000_null_mta_set(struct e1000_hw *hw, u32 a);
void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a);
s32 e1000_blink_led_generic(struct e1000_hw *hw);
s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw);
s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw);
s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw);
s32 e1000_cleanup_led_generic(struct e1000_hw *hw);
s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw);
s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw);
s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw);
s32 e1000_force_mac_fc_generic(struct e1000_hw *hw);
s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw);
s32 e1000_get_bus_info_pci_generic(struct e1000_hw *hw);
s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw);
s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
u16 *speed, u16 *duplex);
s32 e1000_id_led_init_generic(struct e1000_hw *hw);
s32 e1000_led_on_generic(struct e1000_hw *hw);
s32 e1000_led_off_generic(struct e1000_hw *hw);
void e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count);
s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw);
s32 e1000_set_default_fc_generic(struct e1000_hw *hw);
s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw);
s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw);
s32 e1000_setup_led_generic(struct e1000_hw *hw);
s32 e1000_setup_link_generic(struct e1000_hw *hw);
s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw);
s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr);
void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw);
void e1000_clear_vfta_generic(struct e1000_hw *hw);
void e1000_config_collision_dist_generic(struct e1000_hw *hw);
void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count);
void e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value);
void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw);
void e1000_put_hw_semaphore_generic(struct e1000_hw *hw);
void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
void e1000_remove_device_generic(struct e1000_hw *hw);
void e1000_reset_adaptive_generic(struct e1000_hw *hw);
void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop);
void e1000_update_adaptive_generic(struct e1000_hw *hw);
void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
#endif

390
sys/dev/igb/e1000_manage.c Normal file
View File

@ -0,0 +1,390 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#include "e1000_api.h"
#include "e1000_manage.h"
static u8 e1000_calculate_checksum(u8 *buffer, u32 length);
/**
* e1000_calculate_checksum - Calculate checksum for buffer
* @buffer: pointer to EEPROM
* @length: size of EEPROM to calculate a checksum for
*
* Calculates the checksum for some buffer on a specified length. The
* checksum calculated is returned.
**/
static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
{
u32 i;
u8 sum = 0;
DEBUGFUNC("e1000_calculate_checksum");
if (!buffer)
return 0;
for (i = 0; i < length; i++)
sum += buffer[i];
return (u8) (0 - sum);
}
/**
* e1000_mng_enable_host_if_generic - Checks host interface is enabled
* @hw: pointer to the HW structure
*
* Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
*
* This function checks whether the HOST IF is enabled for command operation
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
s32 e1000_mng_enable_host_if_generic(struct e1000_hw * hw)
{
u32 hicr;
s32 ret_val = E1000_SUCCESS;
u8 i;
DEBUGFUNC("e1000_mng_enable_host_if_generic");
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, E1000_HICR);
if ((hicr & E1000_HICR_EN) == 0) {
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
}
/* check the previous command is completed */
for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
hicr = E1000_READ_REG(hw, E1000_HICR);
if (!(hicr & E1000_HICR_C))
break;
msec_delay_irq(1);
}
if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
DEBUGOUT("Previous command timeout failed .\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
}
out:
return ret_val;
}
/**
* e1000_check_mng_mode_generic - Generic check management mode
* @hw: pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
* manageability is enabled, else false (0).
**/
bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
{
u32 fwsm;
DEBUGFUNC("e1000_check_mng_mode_generic");
fwsm = E1000_READ_REG(hw, E1000_FWSM);
return ((fwsm & E1000_FWSM_MODE_MASK) ==
(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT));
}
/**
* e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on TX
* @hw: pointer to the HW structure
*
* Enables packet filtering on transmit packets if manageability is enabled
* and host interface is enabled.
**/
bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
{
struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
u32 *buffer = (u32 *)&hw->mng_cookie;
u32 offset;
s32 ret_val, hdr_csum, csum;
u8 i, len;
bool tx_filter = TRUE;
DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
/* No manageability, no filtering */
if (!hw->mac.ops.check_mng_mode(hw)) {
tx_filter = FALSE;
goto out;
}
/*
* If we can't read from the host interface for whatever
* reason, disable filtering.
*/
ret_val = hw->mac.ops.mng_enable_host_if(hw);
if (ret_val != E1000_SUCCESS) {
tx_filter = FALSE;
goto out;
}
/* Read in the header. Length and offset are in dwords. */
len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
for (i = 0; i < len; i++) {
*(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
E1000_HOST_IF,
offset + i);
}
hdr_csum = hdr->checksum;
hdr->checksum = 0;
csum = e1000_calculate_checksum((u8 *)hdr,
E1000_MNG_DHCP_COOKIE_LENGTH);
/*
* If either the checksums or signature don't match, then
* the cookie area isn't considered valid, in which case we
* take the safe route of assuming Tx filtering is enabled.
*/
if (hdr_csum != csum)
goto out;
if (hdr->signature != E1000_IAMT_SIGNATURE)
goto out;
/* Cookie area is valid, make the final check for filtering. */
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
tx_filter = FALSE;
out:
hw->mac.tx_pkt_filtering = tx_filter;
return tx_filter;
}
/**
* e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface
* @length: size of the buffer
*
* Writes the DHCP information to the host interface.
**/
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw * hw, u8 *buffer,
u16 length)
{
struct e1000_host_mng_command_header hdr;
s32 ret_val;
u32 hicr;
DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
hdr.command_length = length;
hdr.reserved1 = 0;
hdr.reserved2 = 0;
hdr.checksum = 0;
/* Enable the host interface */
ret_val = hw->mac.ops.mng_enable_host_if(hw);
if (ret_val)
goto out;
/* Populate the host interface with the contents of "buffer". */
ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
sizeof(hdr), &(hdr.checksum));
if (ret_val)
goto out;
/* Write the manageability command header */
ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
if (ret_val)
goto out;
/* Tell the ARC a new command is pending. */
hicr = E1000_READ_REG(hw, E1000_HICR);
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
out:
return ret_val;
}
/**
* e1000_mng_write_cmd_header_generic - Writes manageability command header
* @hw: pointer to the HW structure
* @hdr: pointer to the host interface command header
*
* Writes the command header after does the checksum calculation.
**/
s32 e1000_mng_write_cmd_header_generic(struct e1000_hw * hw,
struct e1000_host_mng_command_header * hdr)
{
u16 i, length = sizeof(struct e1000_host_mng_command_header);
DEBUGFUNC("e1000_mng_write_cmd_header_generic");
/* Write the whole command header structure with new checksum. */
hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
length >>= 2;
/* Write the relevant command block into the ram area. */
for (i = 0; i < length; i++) {
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
*((u32 *) hdr + i));
E1000_WRITE_FLUSH(hw);
}
return E1000_SUCCESS;
}
/**
* e1000_mng_host_if_write_generic - Write to the manageability host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface buffer
* @length: size of the buffer
* @offset: location in the buffer to write to
* @sum: sum of the data (not checksum)
*
* This function writes the buffer content at the offset given on the host if.
* It also does alignment considerations to do the writes in most efficient
* way. Also fills up the sum of the buffer in *buffer parameter.
**/
s32 e1000_mng_host_if_write_generic(struct e1000_hw * hw, u8 *buffer,
u16 length, u16 offset, u8 *sum)
{
u8 *tmp;
u8 *bufptr = buffer;
u32 data = 0;
s32 ret_val = E1000_SUCCESS;
u16 remaining, i, j, prev_bytes;
DEBUGFUNC("e1000_mng_host_if_write_generic");
/* sum = only sum of the data and it is not checksum */
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
ret_val = -E1000_ERR_PARAM;
goto out;
}
tmp = (u8 *)&data;
prev_bytes = offset & 0x3;
offset >>= 2;
if (prev_bytes) {
data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
for (j = prev_bytes; j < sizeof(u32); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
length -= j - prev_bytes;
offset++;
}
remaining = length & 0x3;
length -= remaining;
/* Calculate length in DWORDs */
length >>= 2;
/*
* The device driver writes the relevant command block into the
* ram area.
*/
for (i = 0; i < length; i++) {
for (j = 0; j < sizeof(u32); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
}
if (remaining) {
for (j = 0; j < sizeof(u32); j++) {
if (j < remaining)
*(tmp + j) = *bufptr++;
else
*(tmp + j) = 0;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
}
out:
return ret_val;
}
/**
* e1000_enable_mng_pass_thru - Enable processing of ARP's
* @hw: pointer to the HW structure
*
* Verifies the hardware needs to allow ARPs to be processed by the host.
**/
bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
{
u32 manc;
u32 fwsm, factps;
bool ret_val = FALSE;
DEBUGFUNC("e1000_enable_mng_pass_thru");
if (!hw->mac.asf_firmware_present)
goto out;
manc = E1000_READ_REG(hw, E1000_MANC);
if (!(manc & E1000_MANC_RCV_TCO_EN) ||
!(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
goto out;
if (hw->mac.arc_subsystem_valid) {
fwsm = E1000_READ_REG(hw, E1000_FWSM);
factps = E1000_READ_REG(hw, E1000_FACTPS);
if (!(factps & E1000_FACTPS_MNGCG) &&
((fwsm & E1000_FWSM_MODE_MASK) ==
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
ret_val = TRUE;
goto out;
}
} else {
if ((manc & E1000_MANC_SMBUS_EN) &&
!(manc & E1000_MANC_ASF_EN)) {
ret_val = TRUE;
goto out;
}
}
out:
return ret_val;
}

View File

@ -0,0 +1,87 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _E1000_MANAGE_H_
#define _E1000_MANAGE_H_
bool e1000_check_mng_mode_generic(struct e1000_hw *hw);
bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw);
s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw);
s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
u16 length, u16 offset, u8 *sum);
s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr);
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw,
u8 *buffer, u16 length);
typedef enum {
e1000_mng_mode_none = 0,
e1000_mng_mode_asf,
e1000_mng_mode_pt,
e1000_mng_mode_ipmi,
e1000_mng_mode_host_if_only
} e1000_mng_mode;
#define E1000_FACTPS_MNGCG 0x20000000
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_MNG_IAMT_MODE 0x3
#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0
#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
#define E1000_VFTA_ENTRY_SHIFT 5
#define E1000_VFTA_ENTRY_MASK 0x7F
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
/* Driver sets this bit when done to put command in RAM */
#define E1000_HICR_C 0x02
#define E1000_HICR_SV 0x04 /* Status Validity */
#define E1000_HICR_FW_RESET_ENABLE 0x40
#define E1000_HICR_FW_RESET 0x80
/* Intel(R) Active Management Technology signature */
#define E1000_IAMT_SIGNATURE 0x544D4149
#endif

932
sys/dev/igb/e1000_nvm.c Normal file
View File

@ -0,0 +1,932 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#include "e1000_api.h"
#include "e1000_nvm.h"
/**
* e1000_init_nvm_ops_generic - Initialize NVM function pointers
* @hw: pointer to the HW structure
*
* Setups up the function pointers to no-op functions
**/
void e1000_init_nvm_ops_generic(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
DEBUGFUNC("e1000_init_nvm_ops_generic");
/* Initialize function pointers */
nvm->ops.init_params = e1000_null_ops_generic;
nvm->ops.acquire = e1000_null_ops_generic;
nvm->ops.read = e1000_null_read_nvm;
nvm->ops.release = e1000_null_nvm_generic;
nvm->ops.reload = e1000_reload_nvm_generic;
nvm->ops.update = e1000_null_ops_generic;
nvm->ops.valid_led_default = e1000_null_led_default;
nvm->ops.validate = e1000_null_ops_generic;
nvm->ops.write = e1000_null_write_nvm;
}
/**
* e1000_null_nvm_read - No-op function, return 0
* @hw: pointer to the HW structure
**/
s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
{
DEBUGFUNC("e1000_null_read_nvm");
return E1000_SUCCESS;
}
/**
* e1000_null_nvm_generic - No-op function, return void
* @hw: pointer to the HW structure
**/
void e1000_null_nvm_generic(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_null_nvm_generic");
return;
}
/**
* e1000_null_led_default - No-op function, return 0
* @hw: pointer to the HW structure
**/
s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data)
{
DEBUGFUNC("e1000_null_led_default");
return E1000_SUCCESS;
}
/**
* e1000_null_write_nvm - No-op function, return 0
* @hw: pointer to the HW structure
**/
s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
{
DEBUGFUNC("e1000_null_write_nvm");
return E1000_SUCCESS;
}
/**
* e1000_raise_eec_clk - Raise EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Enable/Raise the EEPROM clock bit.
**/
static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd | E1000_EECD_SK;
E1000_WRITE_REG(hw, E1000_EECD, *eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(hw->nvm.delay_usec);
}
/**
* e1000_lower_eec_clk - Lower EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Clear/Lower the EEPROM clock bit.
**/
static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd & ~E1000_EECD_SK;
E1000_WRITE_REG(hw, E1000_EECD, *eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(hw->nvm.delay_usec);
}
/**
* e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
* @hw: pointer to the HW structure
* @data: data to send to the EEPROM
* @count: number of bits to shift out
*
* We need to shift 'count' bits out to the EEPROM. So, the value in the
* "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.
**/
static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
u32 mask;
DEBUGFUNC("e1000_shift_out_eec_bits");
mask = 0x01 << (count - 1);
if (nvm->type == e1000_nvm_eeprom_microwire)
eecd &= ~E1000_EECD_DO;
else if (nvm->type == e1000_nvm_eeprom_spi)
eecd |= E1000_EECD_DO;
do {
eecd &= ~E1000_EECD_DI;
if (data & mask)
eecd |= E1000_EECD_DI;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
e1000_raise_eec_clk(hw, &eecd);
e1000_lower_eec_clk(hw, &eecd);
mask >>= 1;
} while (mask);
eecd &= ~E1000_EECD_DI;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
}
/**
* e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
* @hw: pointer to the HW structure
* @count: number of bits to shift in
*
* In order to read a register from the EEPROM, we need to shift 'count' bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the data out
* "DO" bit. During this "shifting in" process the data in "DI" bit should
* always be clear.
**/
static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
{
u32 eecd;
u32 i;
u16 data;
DEBUGFUNC("e1000_shift_in_eec_bits");
eecd = E1000_READ_REG(hw, E1000_EECD);
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
data = 0;
for (i = 0; i < count; i++) {
data <<= 1;
e1000_raise_eec_clk(hw, &eecd);
eecd = E1000_READ_REG(hw, E1000_EECD);
eecd &= ~E1000_EECD_DI;
if (eecd & E1000_EECD_DO)
data |= 1;
e1000_lower_eec_clk(hw, &eecd);
}
return data;
}
/**
* e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion
* @hw: pointer to the HW structure
* @ee_reg: EEPROM flag for polling
*
* Polls the EEPROM status bit for either read or write completion based
* upon the value of 'ee_reg'.
**/
s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
{
u32 attempts = 100000;
u32 i, reg = 0;
s32 ret_val = -E1000_ERR_NVM;
DEBUGFUNC("e1000_poll_eerd_eewr_done");
for (i = 0; i < attempts; i++) {
if (ee_reg == E1000_NVM_POLL_READ)
reg = E1000_READ_REG(hw, E1000_EERD);
else
reg = E1000_READ_REG(hw, E1000_EEWR);
if (reg & E1000_NVM_RW_REG_DONE) {
ret_val = E1000_SUCCESS;
break;
}
usec_delay(5);
}
return ret_val;
}
/**
* e1000_acquire_nvm_generic - Generic request for access to EEPROM
* @hw: pointer to the HW structure
*
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
{
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_acquire_nvm_generic");
E1000_WRITE_REG(hw, E1000_EECD, eecd | E1000_EECD_REQ);
eecd = E1000_READ_REG(hw, E1000_EECD);
while (timeout) {
if (eecd & E1000_EECD_GNT)
break;
usec_delay(5);
eecd = E1000_READ_REG(hw, E1000_EECD);
timeout--;
}
if (!timeout) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
DEBUGOUT("Could not acquire NVM grant\n");
ret_val = -E1000_ERR_NVM;
}
return ret_val;
}
/**
* e1000_standby_nvm - Return EEPROM to standby state
* @hw: pointer to the HW structure
*
* Return the EEPROM to a standby state.
**/
static void e1000_standby_nvm(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
DEBUGFUNC("e1000_standby_nvm");
if (nvm->type == e1000_nvm_eeprom_microwire) {
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
e1000_raise_eec_clk(hw, &eecd);
/* Select EEPROM */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
e1000_lower_eec_clk(hw, &eecd);
} else if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
eecd &= ~E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
}
}
/**
* e1000_stop_nvm - Terminate EEPROM command
* @hw: pointer to the HW structure
*
* Terminates the current command by inverting the EEPROM's chip select pin.
**/
void e1000_stop_nvm(struct e1000_hw *hw)
{
u32 eecd;
DEBUGFUNC("e1000_stop_nvm");
eecd = E1000_READ_REG(hw, E1000_EECD);
if (hw->nvm.type == e1000_nvm_eeprom_spi) {
/* Pull CS high */
eecd |= E1000_EECD_CS;
e1000_lower_eec_clk(hw, &eecd);
} else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
/* CS on Microwire is active-high */
eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
e1000_raise_eec_clk(hw, &eecd);
e1000_lower_eec_clk(hw, &eecd);
}
}
/**
* e1000_release_nvm_generic - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
**/
void e1000_release_nvm_generic(struct e1000_hw *hw)
{
u32 eecd;
DEBUGFUNC("e1000_release_nvm_generic");
e1000_stop_nvm(hw);
eecd = E1000_READ_REG(hw, E1000_EECD);
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
}
/**
* e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
* @hw: pointer to the HW structure
*
* Setups the EEPROM for reading and writing.
**/
static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
s32 ret_val = E1000_SUCCESS;
u16 timeout = 0;
u8 spi_stat_reg;
DEBUGFUNC("e1000_ready_nvm_eeprom");
if (nvm->type == e1000_nvm_eeprom_microwire) {
/* Clear SK and DI */
eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
/* Set CS */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
} else if (nvm->type == e1000_nvm_eeprom_spi) {
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
usec_delay(1);
timeout = NVM_MAX_RETRY_SPI;
/*
* 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 'timeout', then error out.
*/
while (timeout) {
e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
hw->nvm.opcode_bits);
spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
break;
usec_delay(5);
e1000_standby_nvm(hw);
timeout--;
}
if (!timeout) {
DEBUGOUT("SPI NVM Status error\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
}
out:
return ret_val;
}
/**
* e1000_read_nvm_spi - Read EEPROM's using SPI
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM.
**/
s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i = 0;
s32 ret_val;
u16 word_in;
u8 read_opcode = NVM_READ_OPCODE_SPI;
DEBUGFUNC("e1000_read_nvm_spi");
/*
* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
e1000_standby_nvm(hw);
if ((nvm->address_bits == 8) && (offset >= 128))
read_opcode |= NVM_A8_OPCODE_SPI;
/* Send the READ command (opcode + addr) */
e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
/*
* Read the data. SPI NVMs increment the address with each byte
* read and will roll over if reading beyond the end. This allows
* us to read the whole NVM from any offset
*/
for (i = 0; i < words; i++) {
word_in = e1000_shift_in_eec_bits(hw, 16);
data[i] = (word_in >> 8) | (word_in << 8);
}
release:
nvm->ops.release(hw);
out:
return ret_val;
}
/**
* e1000_read_nvm_microwire - Reads EEPROM's using microwire
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM.
**/
s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i = 0;
s32 ret_val;
u8 read_opcode = NVM_READ_OPCODE_MICROWIRE;
DEBUGFUNC("e1000_read_nvm_microwire");
/*
* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
for (i = 0; i < words; i++) {
/* Send the READ command (opcode + addr) */
e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)(offset + i),
nvm->address_bits);
/*
* Read the data. For microwire, each word requires the
* overhead of setup and tear-down.
*/
data[i] = e1000_shift_in_eec_bits(hw, 16);
e1000_standby_nvm(hw);
}
release:
nvm->ops.release(hw);
out:
return ret_val;
}
/**
* e1000_read_nvm_eerd - Reads EEPROM using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM using the EERD register.
**/
s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, eerd = 0;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_nvm_eerd");
/*
* A check for invalid values: offset too large, too many words,
* too many words for the offset, and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
for (i = 0; i < words; i++) {
eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
E1000_NVM_RW_REG_START;
E1000_WRITE_REG(hw, E1000_EERD, eerd);
ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
if (ret_val)
break;
data[i] = (E1000_READ_REG(hw, E1000_EERD) >>
E1000_NVM_RW_REG_DATA);
}
out:
return ret_val;
}
/**
* e1000_write_nvm_spi - Write to EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the EEPROM
*
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
* EEPROM will most likely contain an invalid checksum.
**/
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val;
u16 widx = 0;
DEBUGFUNC("e1000_write_nvm_spi");
/*
* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
msec_delay(10);
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
e1000_standby_nvm(hw);
/* Send the WRITE ENABLE command (8 bit opcode) */
e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
nvm->opcode_bits);
e1000_standby_nvm(hw);
/*
* Some SPI eeproms use the 8th address bit embedded in the
* opcode
*/
if ((nvm->address_bits == 8) && (offset >= 128))
write_opcode |= NVM_A8_OPCODE_SPI;
/* Send the Write command (8-bit opcode + addr) */
e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
nvm->address_bits);
/* Loop to allow for up to whole page write of eeprom */
while (widx < words) {
u16 word_out = data[widx];
word_out = (word_out >> 8) | (word_out << 8);
e1000_shift_out_eec_bits(hw, word_out, 16);
widx++;
if ((((offset + widx) * 2) % nvm->page_size) == 0) {
e1000_standby_nvm(hw);
break;
}
}
}
msec_delay(10);
release:
nvm->ops.release(hw);
out:
return ret_val;
}
/**
* e1000_write_nvm_microwire - Writes EEPROM using microwire
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the EEPROM
*
* Writes data to EEPROM at offset using microwire interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
* EEPROM will most likely contain an invalid checksum.
**/
s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val;
u32 eecd;
u16 words_written = 0;
u16 widx = 0;
DEBUGFUNC("e1000_write_nvm_microwire");
/*
* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE,
(u16)(nvm->opcode_bits + 2));
e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
e1000_standby_nvm(hw);
while (words_written < words) {
e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE,
nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)(offset + words_written),
nvm->address_bits);
e1000_shift_out_eec_bits(hw, data[words_written], 16);
e1000_standby_nvm(hw);
for (widx = 0; widx < 200; widx++) {
eecd = E1000_READ_REG(hw, E1000_EECD);
if (eecd & E1000_EECD_DO)
break;
usec_delay(50);
}
if (widx == 200) {
DEBUGOUT("NVM Write did not complete\n");
ret_val = -E1000_ERR_NVM;
goto release;
}
e1000_standby_nvm(hw);
words_written++;
}
e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE,
(u16)(nvm->opcode_bits + 2));
e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
release:
nvm->ops.release(hw);
out:
return ret_val;
}
/**
* e1000_read_pba_num_generic - Read device part number
* @hw: pointer to the HW structure
* @pba_num: pointer to device part number
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in pba_num.
**/
s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num)
{
s32 ret_val;
u16 nvm_data;
DEBUGFUNC("e1000_read_pba_num_generic");
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
*pba_num = (u32)(nvm_data << 16);
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
*pba_num |= nvm_data;
out:
return ret_val;
}
/**
* e1000_read_mac_addr_generic - Read device MAC address
* @hw: pointer to the HW structure
*
* Reads the device MAC address from the EEPROM and stores the value.
* Since devices with two ports use the same EEPROM, we increment the
* last bit in the MAC address for the second port.
**/
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 offset, nvm_data, i;
DEBUGFUNC("e1000_read_mac_addr");
for (i = 0; i < ETH_ADDR_LEN; i += 2) {
offset = i >> 1;
ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
}
/* Flip last bit of mac address if we're on second port */
if (hw->bus.func == E1000_FUNC_1)
hw->mac.perm_addr[5] ^= 1;
for (i = 0; i < ETH_ADDR_LEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
out:
return ret_val;
}
/**
* e1000_validate_nvm_checksum_generic - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 checksum = 0;
u16 i, nvm_data;
DEBUGFUNC("e1000_validate_nvm_checksum_generic");
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
checksum += nvm_data;
}
if (checksum != (u16) NVM_SUM) {
DEBUGOUT("NVM Checksum Invalid\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
out:
return ret_val;
}
/**
* e1000_update_nvm_checksum_generic - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM.
**/
s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
DEBUGFUNC("e1000_update_nvm_checksum");
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val) {
DEBUGOUT("NVM Write Error while updating checksum.\n");
}
out:
return ret_val;
}
/**
* e1000_reload_nvm_generic - Reloads EEPROM
* @hw: pointer to the HW structure
*
* Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
* extended control register.
**/
void e1000_reload_nvm_generic(struct e1000_hw *hw)
{
u32 ctrl_ext;
DEBUGFUNC("e1000_reload_nvm_generic");
usec_delay(10);
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
ctrl_ext |= E1000_CTRL_EXT_EE_RST;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
}

68
sys/dev/igb/e1000_nvm.h Normal file
View File

@ -0,0 +1,68 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _E1000_NVM_H_
#define _E1000_NVM_H_
void e1000_init_nvm_ops_generic(struct e1000_hw *hw);
s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c);
void e1000_null_nvm_generic(struct e1000_hw *hw);
s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data);
s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c);
s32 e1000_acquire_nvm_generic(struct e1000_hw *hw);
s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num);
s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data);
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw);
s32 e1000_write_nvm_eewr(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw);
void e1000_stop_nvm(struct e1000_hw *hw);
void e1000_release_nvm_generic(struct e1000_hw *hw);
void e1000_reload_nvm_generic(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#endif

184
sys/dev/igb/e1000_osdep.h Normal file
View File

@ -0,0 +1,184 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _FREEBSD_OS_H_
#define _FREEBSD_OS_H_
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/clock.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#define ASSERT(x) if(!(x)) panic("EM: x")
/* The happy-fun DELAY macro is defined in /usr/src/sys/i386/include/clock.h */
#define usec_delay(x) DELAY(x)
#define msec_delay(x) DELAY(1000*(x))
/* TODO: Should we be paranoid about delaying in interrupt context? */
#define msec_delay_irq(x) DELAY(1000*(x))
#define MSGOUT(S, A, B) printf(S "\n", A, B)
#define DEBUGFUNC(F) DEBUGOUT(F);
#define DEBUGOUT(S)
#define DEBUGOUT1(S,A)
#define DEBUGOUT2(S,A,B)
#define DEBUGOUT3(S,A,B,C)
#define DEBUGOUT7(S,A,B,C,D,E,F,G)
#define STATIC static
#define FALSE 0
#define TRUE 1
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
/*
** These typedefs are necessary due to the new
** shared code, they are native to Linux.
*/
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
typedef boolean_t bool;
struct e1000_osdep
{
bus_space_tag_t mem_bus_space_tag;
bus_space_handle_t mem_bus_space_handle;
bus_space_tag_t io_bus_space_tag;
bus_space_handle_t io_bus_space_handle;
bus_space_tag_t flash_bus_space_tag;
bus_space_handle_t flash_bus_space_handle;
struct device *dev;
};
#define E1000_REGISTER(hw, reg) reg
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, E1000_STATUS)
/* Read from an absolute offset in the adapter's memory space */
#define E1000_READ_OFFSET(hw, offset) \
bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, offset)
/* Write to an absolute offset in the adapter's memory space */
#define E1000_WRITE_OFFSET(hw, offset, value) \
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, offset, value)
/* Register READ/WRITE macros */
#define E1000_READ_REG(hw, reg) \
bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg))
#define E1000_WRITE_REG(hw, reg, value) \
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg), value)
#define E1000_READ_REG_ARRAY(hw, reg, index) \
bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + ((index)<< 2))
#define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + ((index)<< 2), value)
#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
#define E1000_READ_REG_ARRAY_BYTE(hw, reg, index) \
bus_space_read_1(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + index)
#define E1000_WRITE_REG_ARRAY_BYTE(hw, reg, index, value) \
bus_space_write_1(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + index, value)
#define E1000_WRITE_REG_ARRAY_WORD(hw, reg, index, value) \
bus_space_write_2(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + (index << 1), value)
#define E1000_WRITE_REG_IO(hw, reg, value) do {\
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->io_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->io_bus_space_handle, \
(hw)->io_base, reg); \
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->io_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->io_bus_space_handle, \
(hw)->io_base + 4, value); } while (0)
#define E1000_READ_FLASH_REG(hw, reg) \
bus_space_read_4(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg)
#define E1000_READ_FLASH_REG16(hw, reg) \
bus_space_read_2(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg)
#define E1000_WRITE_FLASH_REG(hw, reg, value) \
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
#define E1000_WRITE_FLASH_REG16(hw, reg, value) \
bus_space_write_2(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
#endif /* _FREEBSD_OS_H_ */

2146
sys/dev/igb/e1000_phy.c Normal file

File diff suppressed because it is too large Load Diff

177
sys/dev/igb/e1000_phy.h Normal file
View File

@ -0,0 +1,177 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _E1000_PHY_H_
#define _E1000_PHY_H_
typedef enum {
e1000_ms_hw_default = 0,
e1000_ms_force_master,
e1000_ms_force_slave,
e1000_ms_auto
} e1000_ms_type;
typedef enum {
e1000_smart_speed_default = 0,
e1000_smart_speed_on,
e1000_smart_speed_off
} e1000_smart_speed;
void e1000_init_phy_ops_generic(struct e1000_hw *hw);
s32 e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data);
void e1000_null_phy_generic(struct e1000_hw *hw);
s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active);
s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_check_downshift_generic(struct e1000_hw *hw);
s32 e1000_check_polarity_m88(struct e1000_hw *hw);
s32 e1000_check_polarity_igp(struct e1000_hw *hw);
s32 e1000_check_reset_block_generic(struct e1000_hw *hw);
s32 e1000_copper_link_autoneg(struct e1000_hw *hw);
s32 e1000_copper_link_setup_igp(struct e1000_hw *hw);
s32 e1000_copper_link_setup_m88(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw);
s32 e1000_get_cable_length_m88(struct e1000_hw *hw);
s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw);
s32 e1000_get_cfg_done_generic(struct e1000_hw *hw);
s32 e1000_get_phy_id(struct e1000_hw *hw);
s32 e1000_get_phy_info_igp(struct e1000_hw *hw);
s32 e1000_get_phy_info_m88(struct e1000_hw *hw);
s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw);
void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw);
s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw);
s32 e1000_phy_setup_autoneg(struct e1000_hw *hw);
s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active);
s32 e1000_setup_copper_link_generic(struct e1000_hw *hw);
s32 e1000_wait_autoneg_generic(struct e1000_hw *hw);
s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
void e1000_power_up_phy_copper(struct e1000_hw *hw);
void e1000_power_down_phy_copper(struct e1000_hw *hw);
s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
#define E1000_MAX_PHY_ADDR 4
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO */
#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality */
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
#define IGP_PAGE_SHIFT 5
#define PHY_REG_MASK 0x1F
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
/* Enable flexible speed on link-up */
#define IGP01E1000_GMII_FLEX_SPD 0x0010
#define IGP01E1000_GMII_SPD 0x0020 /* Enable SPD */
#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
#define IGP01E1000_PSSR_MDIX 0x0008
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP02E1000_PHY_CHANNEL_NUM 4
#define IGP02E1000_PHY_AGC_A 0x11B1
#define IGP02E1000_PHY_AGC_B 0x12B1
#define IGP02E1000_PHY_AGC_C 0x14B1
#define IGP02E1000_PHY_AGC_D 0x18B1
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */
#define IGP02E1000_AGC_LENGTH_MASK 0x7F
#define IGP02E1000_AGC_RANGE 15
#define IGP03E1000_PHY_MISC_CTRL 0x1B
#define IGP03E1000_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Manually Set Duplex */
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16
#define E1000_KMRNCTRLSTA_REN 0x00200000
#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */
#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */
#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */
/* IFE PHY Extended Status Control */
#define IFE_PESC_POLARITY_REVERSED 0x0100
/* IFE PHY Special Control */
#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010
#define IFE_PSC_FORCE_POLARITY 0x0020
#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100
/* IFE PHY Special Control and LED Control */
#define IFE_PSCL_PROBE_MODE 0x0020
#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
/* IFE PHY MDIX Control */
#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */
#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto MDI/MDI-X, 0=disable */
#endif

326
sys/dev/igb/e1000_regs.h Normal file
View File

@ -0,0 +1,326 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _E1000_REGS_H_
#define _E1000_REGS_H_
#define E1000_CTRL 0x00000 /* Device Control - RW */
#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
#define E1000_STATUS 0x00008 /* Device Status - RO */
#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 - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_RCTL 0x00100 /* Rx Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
#define E1000_RXCW 0x00180 /* Rx Configuration Word - RO */
#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
#define E1000_EITR(_n) (0x01680 + (0x4 * (_n)))
#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
#define E1000_TCTL 0x00400 /* Tx Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */
#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */
#define E1000_TBT 0x00448 /* Tx Burst Timer - RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_FLSWCTL 0x01030 /* FLASH control register */
#define E1000_FLSWDATA 0x01034 /* FLASH data register */
#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */
#define E1000_WDSTP 0x01040 /* Watchdog Setup - RW */
#define E1000_SWDSTS 0x01044 /* SW Device Status - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n)))
#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
/* Split and Replication Rx Control - RW */
#define E1000_RDPUMB 0x025CC /* DMA Rx Descriptor uC Mailbox - RW */
#define E1000_RDPUAD 0x025D0 /* DMA Rx Descriptor uC Addr Command - RW */
#define E1000_RDPUWD 0x025D4 /* DMA Rx Descriptor uC Data Write - RW */
#define E1000_RDPURD 0x025D8 /* DMA Rx Descriptor uC Data Read - RW */
#define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */
#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
/*
* Convenience macros
*
* Note: "_n" is the queue number of the register to be written to.
*
* Example usage:
* E1000_RDBAL_REG(current_rx_queue)
*/
#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : (0x0C000 + ((_n) * 0x40)))
#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : (0x0C004 + ((_n) * 0x40)))
#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : (0x0C008 + ((_n) * 0x40)))
#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : (0x0C00C + ((_n) * 0x40)))
#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : (0x0C010 + ((_n) * 0x40)))
#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : (0x0C018 + ((_n) * 0x40)))
#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : (0x0C028 + ((_n) * 0x40)))
#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : (0x0E000 + ((_n) * 0x40)))
#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : (0x0E004 + ((_n) * 0x40)))
#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : (0x0E008 + ((_n) * 0x40)))
#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : (0x0E010 + ((_n) * 0x40)))
#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : (0x0E018 + ((_n) * 0x40)))
#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : (0x0E028 + ((_n) * 0x40)))
#define E1000_TARC(_n) (0x03840 + (_n << 8))
#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) : (0x0E038 + ((_n) * 0x40)))
#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) : (0x0E03C + ((_n) * 0x40)))
#define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */
#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
#define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */
#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x054E0 + ((_i - 16) * 8)))
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x054E4 + ((_i - 16) * 8)))
#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8))
#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8))
#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8))
#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_TDPUMB 0x0357C /* DMA Tx Descriptor uC Mail Box - RW */
#define E1000_TDPUAD 0x03580 /* DMA Tx Descriptor uC Addr Command - RW */
#define E1000_TDPUWD 0x03584 /* DMA Tx Descriptor uC Data Write - RW */
#define E1000_TDPURD 0x03588 /* DMA Tx Descriptor uC Data Read - RW */
#define E1000_TDPUCTL 0x0358C /* DMA Tx Descriptor uC Control - RW */
#define E1000_DTXCTL 0x03590 /* DMA Tx Control - RW */
#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
#define E1000_DC 0x04030 /* Defer Count - R/clr */
#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */
#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */
#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */
#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */
#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */
#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */
#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */
#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */
#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */
#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */
#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */
#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */
#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */
#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */
#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */
#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */
#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */
#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */
#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */
#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */
#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */
#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */
#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */
#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */
#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */
#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */
#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */
#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */
#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */
#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */
#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */
#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */
#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */
#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */
#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */
#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */
#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */
#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */
#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */
#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */
#define E1000_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */
#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */
#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */
#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
#define E1000_CBTMPC 0x0402C /* Circuit Breaker Tx Packet Count */
#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */
#define E1000_CBRDPC 0x04044 /* Circuit Breaker Rx Dropped Count */
#define E1000_CBRMPC 0x040FC /* Circuit Breaker Rx Packet Count */
#define E1000_RPTHC 0x04104 /* Rx Packets To Host */
#define E1000_HGPTC 0x04118 /* Host Good Packets Tx Count */
#define E1000_HTCBDPC 0x04124 /* Host Tx Circuit Breaker Dropped Count */
#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */
#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */
#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
#define E1000_LENERRS 0x04138 /* Length Errors Count */
#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */
#define E1000_HRMPC 0x0A018 /* Header Redirection Missed Packet Count */
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Packet Count - RW */
#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */
#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */
#define E1000_VFQA1 0x0B200 /* VLAN Filter Queue Array 1 - RW Array */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
#define E1000_WUS 0x05810 /* Wakeup Status - RO */
#define E1000_MANC 0x05820 /* Management Control - RW */
#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
#define E1000_PBACL 0x05B68 /* MSIx PBA Clear - Read/Write 1's to clear */
#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
#define E1000_HOST_IF 0x08800 /* Host Interface */
#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
#define E1000_GCR 0x05B00 /* PCI-Ex Control */
#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Interface Control */
/* RSS registers */
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt Rx VLAN Priority - RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Allocation Register (_i) - RW */
#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10)) /* MSI-X Table entry addr low reg 0 - RW */
#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10)) /* MSI-X Table entry addr upper reg 0 - RW */
#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10)) /* MSI-X Table entry message reg 0 - RW */
#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10)) /* MSI-X Table entry vector ctrl reg 0 - RW */
#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW Array */
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
/* Time Sync */
#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */
#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */
#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
#endif

4439
sys/dev/igb/if_igb.c Normal file

File diff suppressed because it is too large Load Diff

419
sys/dev/igb/if_igb.h Normal file
View File

@ -0,0 +1,419 @@
/******************************************************************************
Copyright (c) 2001-2008, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _IGB_H_DEFINED_
#define _IGB_H_DEFINED_
/* Tunables */
/*
* IGB_TXD: Maximum number of Transmit Descriptors
*
* This value is the number of transmit descriptors allocated by the driver.
* Increasing this value allows the driver to queue more transmits. Each
* descriptor is 16 bytes.
* Since TDLEN should be multiple of 128bytes, the number of transmit
* desscriptors should meet the following condition.
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
#define IGB_MIN_TXD 80
#define IGB_DEFAULT_TXD 256
#define IGB_MAX_TXD 4096
/*
* IGB_RXD: Maximum number of Transmit Descriptors
*
* This value is the number of receive descriptors allocated by the driver.
* Increasing this value allows the driver to buffer more incoming packets.
* Each descriptor is 16 bytes. A receive buffer is also allocated for each
* descriptor. The maximum MTU size is 16110.
* Since TDLEN should be multiple of 128bytes, the number of transmit
* desscriptors should meet the following condition.
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
#define IGB_MIN_RXD 80
#define IGB_DEFAULT_RXD 256
#define IGB_MAX_RXD 4096
/*
* IGB_TIDV - Transmit Interrupt Delay Value
* Valid Range: 0-65535 (0=off)
* Default Value: 64
* This value delays the generation of transmit interrupts in units of
* 1.024 microseconds. Transmit interrupt reduction can improve CPU
* efficiency if properly tuned for specific network traffic. If the
* system is reporting dropped transmits, this value may be set too high
* causing the driver to run out of available transmit descriptors.
*/
#define IGB_TIDV 64
/*
* IGB_TADV - Transmit Absolute Interrupt Delay Value
* Valid Range: 0-65535 (0=off)
* Default Value: 64
* This value, in units of 1.024 microseconds, limits the delay in which a
* transmit interrupt is generated. Useful only if IGB_TIDV is non-zero,
* this value ensures that an interrupt is generated after the initial
* packet is sent on the wire within the set amount of time. Proper tuning,
* along with IGB_TIDV, may improve traffic throughput in specific
* network conditions.
*/
#define IGB_TADV 64
/*
* IGB_RDTR - Receive Interrupt Delay Timer (Packet Timer)
* Valid Range: 0-65535 (0=off)
* Default Value: 0
* This value delays the generation of receive interrupts in units of 1.024
* microseconds. Receive interrupt reduction can improve CPU efficiency if
* properly tuned for specific network traffic. Increasing this value adds
* extra latency to frame reception and can end up decreasing the throughput
* of TCP traffic. If the system is reporting dropped receives, this value
* may be set too high, causing the driver to run out of available receive
* descriptors.
*
* CAUTION: When setting IGB_RDTR to a value other than 0, adapters
* may hang (stop transmitting) under certain network conditions.
* If this occurs a WATCHDOG message is logged in the system
* event log. In addition, the controller is automatically reset,
* restoring the network connection. To eliminate the potential
* for the hang ensure that IGB_RDTR is set to 0.
*/
#define IGB_RDTR 0
/*
* Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544)
* Valid Range: 0-65535 (0=off)
* Default Value: 64
* This value, in units of 1.024 microseconds, limits the delay in which a
* receive interrupt is generated. Useful only if IGB_RDTR is non-zero,
* this value ensures that an interrupt is generated after the initial
* packet is received within the set amount of time. Proper tuning,
* along with IGB_RDTR, may improve traffic throughput in specific network
* conditions.
*/
#define IGB_RADV 64
/*
* This parameter controls the duration of transmit watchdog timer.
*/
#define IGB_TX_TIMEOUT 5 /* set to 5 seconds */
/*
* This parameter controls when the driver calls the routine to reclaim
* transmit descriptors.
*/
#define IGB_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
#define IGB_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
/*
* This parameter controls whether or not autonegotation is enabled.
* 0 - Disable autonegotiation
* 1 - Enable autonegotiation
*/
#define DO_AUTO_NEG 1
/*
* This parameter control whether or not the driver will wait for
* autonegotiation to complete.
* 1 - Wait for autonegotiation to complete
* 0 - Don't wait for autonegotiation to complete
*/
#define WAIT_FOR_AUTO_NEG_DEFAULT 0
/* Tunables -- End */
#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
ADVERTISE_1000_FULL)
#define AUTO_ALL_MODES 0
/* PHY master/slave setting */
#define IGB_MASTER_SLAVE e1000_ms_hw_default
/*
* Micellaneous constants
*/
#define IGB_VENDOR_ID 0x8086
#define IGB_JUMBO_PBA 0x00000028
#define IGB_DEFAULT_PBA 0x00000030
#define IGB_SMARTSPEED_DOWNSHIFT 3
#define IGB_SMARTSPEED_MAX 15
#define IGB_MAX_INTR 10
#define IGB_RX_PTHRESH 16
#define IGB_RX_HTHRESH 8
#define IGB_RX_WTHRESH 1
#define MAX_NUM_MULTICAST_ADDRESSES 128
#define PCI_ANY_ID (~0U)
#define ETHER_ALIGN 2
#define IGB_TX_BUFFER_SIZE ((uint32_t) 1514)
#define IGB_FC_PAUSE_TIME 0x0680
#define IGB_EEPROM_APME 0x400;
#define MAX_INTS_PER_SEC 8000
#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256)
/* Code compatilbility between 6 and 7 */
#ifndef ETHER_BPF_MTAP
#define ETHER_BPF_MTAP BPF_MTAP
#endif
/*
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
* also optimize cache line size effect. H/W supports up to cache line size 128.
*/
#define IGB_DBA_ALIGN 128
#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */
/* PCI Config defines */
#define IGB_MSIX_BAR 3
#define IGB_MSIX_VEC 10 /* Max vectors supported */
/* Defines for printing debug information */
#define DEBUG_INIT 0
#define DEBUG_IOCTL 0
#define DEBUG_HW 0
#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n")
#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A)
#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B)
#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n")
#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A)
#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B)
#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n")
#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
#define IGB_MAX_SCATTER 64
#define IGB_TSO_SIZE (65535 + sizeof(struct ether_vlan_header))
#define IGB_TSO_SEG_SIZE 4096 /* Max dma segment size */
#define ETH_ZLEN 60
#define ETH_ADDR_LEN 6
#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */
struct adapter; /* forward reference */
struct igb_int_delay_info {
struct adapter *adapter; /* Back-pointer to the adapter struct */
int offset; /* Register offset to read/write */
int value; /* Current value in usecs */
};
/*
* Bus dma allocation structure used by
* e1000_dma_malloc and e1000_dma_free.
*/
struct igb_dma_alloc {
bus_addr_t dma_paddr;
caddr_t dma_vaddr;
bus_dma_tag_t dma_tag;
bus_dmamap_t dma_map;
bus_dma_segment_t dma_seg;
int dma_nseg;
};
/*
* Transmit ring: one per tx queue
*/
struct tx_ring {
struct adapter *adapter;
u32 me;
u32 msix; /* This ring's MSIX vector */
u32 eims; /* This ring's EIMS bit */
struct mtx tx_mtx;
struct igb_dma_alloc txdma; /* bus_dma glue for tx desc */
struct e1000_tx_desc *tx_base;
struct task tx_task; /* cleanup tasklet */
u32 next_avail_desc;
u32 next_to_clean;
volatile u16 tx_avail;
struct igb_buffer *tx_buffers;
bus_dma_tag_t txtag; /* dma tag for tx */
u32 watchdog_timer;
u64 no_desc_avail;
u64 tx_irq;
u64 tx_packets;
};
/*
* Receive ring: one per rx queue
*/
struct rx_ring {
struct adapter *adapter;
u32 me;
u32 msix; /* This ring's MSIX vector */
u32 eims; /* This ring's EIMS bit */
struct igb_dma_alloc rxdma; /* bus_dma glue for tx desc */
union e1000_adv_rx_desc *rx_base;
struct task rx_task; /* cleanup tasklet */
struct mtx rx_mtx;
u32 last_cleaned;
u32 next_to_check;
struct igb_buffer *rx_buffers;
bus_dma_tag_t rxtag; /* dma tag for tx */
bus_dmamap_t rx_spare_map;
/*
* First/last mbuf pointers, for
* collecting multisegment RX packets.
*/
struct mbuf *fmp;
struct mbuf *lmp;
/* Soft stats */
u64 rx_irq;
u64 rx_packets;
u64 rx_bytes;
};
struct adapter {
struct ifnet *ifp;
struct e1000_hw hw;
/* FreeBSD operating-system-specific structures. */
struct e1000_osdep osdep;
struct device *dev;
struct resource *pci_mem;
struct resource *msix_mem;
struct resource *res[IGB_MSIX_VEC];
void *tag[IGB_MSIX_VEC];
int rid[IGB_MSIX_VEC];
u32 eims_mask;
int linkvec;
int link_irq;
struct ifmedia media;
struct callout timer;
int msix; /* total vectors allocated */
int if_flags;
int max_frame_size;
int min_frame_size;
struct mtx core_mtx;
int igb_insert_vlan_header;
struct task link_task;
struct task rxtx_task;
struct taskqueue *tq; /* private task queue */
/* Management and WOL features */
int wol;
int has_manage;
/* Info about the board itself */
u8 link_active;
u16 link_speed;
u16 link_duplex;
u32 smartspeed;
struct igb_int_delay_info tx_int_delay;
struct igb_int_delay_info tx_abs_int_delay;
struct igb_int_delay_info rx_int_delay;
struct igb_int_delay_info rx_abs_int_delay;
/*
* Transmit rings
*/
struct tx_ring *tx_rings;
u16 num_tx_desc;
u16 num_tx_queues;
u32 txd_cmd;
/*
* Receive rings
*/
struct rx_ring *rx_rings;
u16 num_rx_desc;
u16 num_rx_queues;
int rx_process_limit;
u32 rx_buffer_len;
/* Misc stats maintained by the driver */
unsigned long dropped_pkts;
unsigned long mbuf_alloc_failed;
unsigned long mbuf_cluster_failed;
unsigned long no_tx_map_avail;
unsigned long no_tx_dma_setup;
unsigned long watchdog_events;
unsigned long rx_overruns;
boolean_t in_detach;
struct e1000_hw_stats stats;
};
/* ******************************************************************************
* vendor_info_array
*
* This array contains the list of Subvendor/Subdevice IDs on which the driver
* should load.
*
* ******************************************************************************/
typedef struct _igb_vendor_info_t {
unsigned int vendor_id;
unsigned int device_id;
unsigned int subvendor_id;
unsigned int subdevice_id;
unsigned int index;
} igb_vendor_info_t;
struct igb_buffer {
int next_eop; /* Index of the desc to watch */
struct mbuf *m_head;
bus_dmamap_t map; /* bus_dma map for packet */
};
#define IGB_CORE_LOCK_INIT(_sc, _name) \
mtx_init(&(_sc)->core_mtx, _name, "IGB Core Lock", MTX_DEF)
#define IGB_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx)
#define IGB_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx)
#define IGB_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx)
#define IGB_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx)
#define IGB_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx)
#define IGB_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx)
#define IGB_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx)
#define IGB_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx)
#define IGB_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx)
#define IGB_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED)
#define IGB_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
#endif /* _IGB_H_DEFINED_ */

View File

@ -5,7 +5,7 @@ SRCS = device_if.h bus_if.h pci_if.h opt_bdg.h
SRCS += if_em.c $(SHARED_SRCS)
SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c
SHARED_SRCS += e1000_80003es2lan.c e1000_82542.c e1000_82541.c e1000_82543.c
SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c e1000_82575.c
SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c
CFLAGS+= -I${.CURDIR}/../../dev/em

25
sys/modules/igb/Makefile Normal file
View File

@ -0,0 +1,25 @@
#$FreeBSD$
.PATH: ${.CURDIR}/../../dev/igb
KMOD = if_igb
SRCS = device_if.h bus_if.h pci_if.h opt_bdg.h
SRCS += if_igb.c $(SHARED_SRCS)
SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c
SHARED_SRCS += e1000_82575.c
CFLAGS += -I${.CURDIR}/../../dev/igb
# DEVICE_POLLING gives you non-interrupt handling
# not advisable since MSIX gives better results
#CFLAGS += -DDEVICE_POLLING
clean:
rm -f opt_bdg.h device_if.h bus_if.h pci_if.h setdef*
rm -f *.o *.kld *.ko
rm -f @ machine
rm -f ${CLEANFILES}
man:
mv /usr/share/man/man4/igb.4.gz /usr/share/man/man4/igbSAVE.4.gz
cp igb.4 /usr/share/man/man4/
.include <bsd.kmod.mk>