1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-16 10:20:30 +00:00

Merge in the new driver (6.5.0) of Intel. This has a new

shared code infrastructure that is family specific and
modular. There is also support for our latest gigabit
nic, the 82575 that is MSI/X and multiqueue capable.

The new shared code changes some interfaces to the core
code but testing at Intel has been going on for months,
it is fairly stable.

I have attempted to be careful in retaining any fixes that
CURRENT had and we did not, I apologize in advance if any
thing gets clobbered, I'm sure I'll hear about it :)

Approved by pdeuskar
This commit is contained in:
Jack F Vogel 2007-05-04 00:00:12 +00:00
parent 832eef31d1
commit 89290aa383
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169240
38 changed files with 23333 additions and 13662 deletions

View File

@ -600,8 +600,32 @@ dev/ed/if_ed_pccard.c optional ed pccard
dev/ed/if_ed_pci.c optional ed pci
dev/eisa/eisa_if.m standard
dev/eisa/eisaconf.c optional eisa
dev/em/if_em.c optional em
dev/em/if_em_hw.c optional em
dev/em/if_e1000.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_80003es2lan.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_82540.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_82541.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_82542.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_82543.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_82571.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_api.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_ich8lan.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_mac.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_manage.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_nvm.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/em/e1000_phy.c optional em \
compile-with "${NORMAL_C} -I$S/dev/em"
dev/en/if_en_pci.c optional en pci
dev/en/midway.c optional en
dev/ep/if_ep.c optional ep

View File

@ -76,6 +76,9 @@ INCLUDES+= -I$S/contrib/ngatm
# .. and the same for twa
INCLUDES+= -I$S/dev/twa
# .. and the same for em
INCLUDES+= -I$S/dev/em
# ... and XFS
INCLUDES+= -I$S/gnu/fs/xfs/FreeBSD -I$S/gnu/fs/xfs/FreeBSD/support -I$S/gnu/fs/xfs

View File

@ -1,31 +1,31 @@
$FreeBSD$
/*-
Copyright (c) 2001-2005, 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:
Copyright (c) 2001-2007, 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.
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.
*/

View File

@ -1,8 +1,8 @@
$FreeBSD$
FreeBSD* Driver for the Intel(R) PRO/1000 Family of Adapters
FreeBSD Driver for the Gigabit Family of Adapters
============================================================
May 2, 2006
April 18, 2007
Contents
@ -21,11 +21,11 @@ Contents
Overview
========
This file describes the FreeBSD* driver for the Intel(R) PRO/1000 Family of
This file describes the FreeBSD* driver for the Gigabit Family of
Adapters. This driver has been developed for use with FreeBSD, Release 6.x.
For questions related to hardware requirements, refer to the documentation
supplied with your Intel PRO/1000 adapter. All hardware requirements listed
supplied with your Gigabit adapter. All hardware requirements listed
apply to use with FreeBSD.
@ -62,7 +62,7 @@ name of the driver tar file.
2. Untar/unzip the archive:
tar xvfz em-x.x.x.tar.gz
tar xzvf em-x.x.x.tar.gz
This will create an em-x.x.x directory.
@ -74,7 +74,7 @@ name of the driver tar file.
cd em-x.x.x
make
b. To install the compiled module in system directory:
b. To install the compiled module to the system directory:
make install
@ -84,35 +84,26 @@ name of the driver tar file.
if_em_load="YES"
4. To compile the driver into the kernel:
4. To compile the driver into the kernel, enter:
cd em-x.x.x/src
cp if_em* /usr/src/sys/dev/em
cp *.[ch] /usr/src/sys/dev/em
cp Makefile.kernel /usr/src/sys/modules/em/Makefile
Edit the /usr/src/sys/conf/files file, and add the following lines only if
they don't already exist:
NOTE: At this point you MUST install a patch, kernbuild.patch, which is
located in the patches directory. This is applied as shown below where
"$PATH_TO_KERNBUILD_PATCH" is the location of the kernbuild.patch:
dev/em/if_em.c optional em
cd /usr/src/sys; patch -p1 < $PATH_TO_KERNBUILD_PATCH
dev/em/if_em_hw.c optional em
Remove the following lines from the /usr/src/sys/conf/files file,
if they exist:
dev/em/if_em_fxhw.c optional em
dev/em/if_em_phy.c optional em
Edit the kernel configuration file (i.e., GENERIC or MYKERNEL) in
/usr/src/sys/i386/conf, and ensure the following line is present:
Edit the kernel configuration file (i.e., GENERIC or MYKERNEL) in
/usr/src/sys/i386/conf, and ensure the following line is present:
device em
Compile and install the kernel. The system must be rebooted for the kernel
updates to take effect. For additional information on compiling the
kernel, consult the FreeBSD operating system documentation.
Compile and install the kernel. The system must be rebooted for the
kernel updates to take effect. For additional information on compiling
the kernel, consult the FreeBSD operating system documentation.
5. To assign an IP address to the interface, enter the following:
@ -150,6 +141,12 @@ configure the speed and duplex settings on the adapter. Example usage:
not specified and you are not running at gigabit speed, the driver
defaults to half-duplex.
If the interface is currently forced to 100 full duplex, in order to change
to half duplex you must use this command:
ifconfig em<interface_num> <IP_address> media 100baseTX -mediaopt
full-duplex
This driver supports the following media type options:
@ -207,8 +204,8 @@ Identifying Your Adapter section.
- Some Intel gigabit adapters that support Jumbo Frames have a frame size
limit of 9238 bytes, with a corresponding MTU size limit of 9216 bytes.
The adapters with this limitation are based on the Intel(R) 82571EB,
82572EI, 82573L and 80003ES2LAN controller. These correspond to the
following product names:
82572EI, 82573L, 82566, 82562, and 80003ES2LAN controller. These
correspond to the following product names:
Intel(R) PRO/1000 PT Server Adapter
Intel(R) PRO/1000 PT Desktop Adapter
Intel(R) PRO/1000 PT Network Connection
@ -221,6 +218,7 @@ Identifying Your Adapter section.
Intel(R) PRO/1000 PL Network Connection
Intel(R) PRO/1000 EB Network Connection with I/O Acceleration
Intel(R) PRO/1000 EB Backplane Connection with I/O Acceleration
Intel(R) 82566DM-2 Gigabit Network Connection
- Adapters based on the Intel(R) 82542 and 82573V/E controller do not
support Jumbo Frames. These correspond to the following product names:
@ -236,7 +234,12 @@ Identifying Your Adapter section.
Intel(R) 82566DC Gigabit Network Connection
Intel(R) 82566MM Gigabit Network Connection
Intel(R) 82566MC Gigabit Network Connection
Intel(R) 82562GT 10/100 Network Connection
Intel(R) 82562G 10/100 Network Connection
Intel(R) 82566DC-2 Gigabit Network Connection
Intel(R) 82562V-2 10/100 Network Connection
Intel(R) 82562G-2 10/100 Network Connection
Intel(R) 82562GT-2 10/100 Network Connection
VLANs
-----
@ -252,9 +255,9 @@ Identifying Your Adapter section.
Example:
ifconfig vlan10 10.0.0.1 netmask 255.255.255.0 vlan10 vlandev em0
ifconfig vlan10 10.0.0.1 netmask 255.255.255.0 vlan 10 vlandev em0
In this example, all packets will be marked on egress with 802.1Q VLAN
In this example, all packets will be marked on egress with 802.1Q VLAN
tags, specifying a VLAN ID of 10.
To remove a VLAN interface:
@ -264,6 +267,12 @@ Identifying Your Adapter section.
Polling
-------
NOTES: Device Polling is only valid for non-SMP (Symmetric MultiProcessing)
kernels.
The driver has to be compiled into the kernel for Device Polling to be
enabled in the driver.
To enable polling in the driver, add the following options to the kernel
configuration, and then recompile the kernel:
@ -271,9 +280,9 @@ Identifying Your Adapter section.
options HZ=1000
At runtime use:
ifconfig em0 polling to turn polling on
sysctl kern.polling.enable=1 to turn polling on
Use:
ifconfig em0 -polling to turn polling off
sysctl kern.polling.enable=0 to turn polling off
Checksum Offload
@ -306,16 +315,51 @@ Identifying Your Adapter section.
See the ifconfig man page for further information.
TSO
---
The FreeBSD driver now offers support for TSO (TCP Segmentation Offload).
To enable this support perform the following:
Patch the kernel with the patch supplied in the tarball.
Rebuild and install the kernel.
Recompile the driver. You must alter the Makefile to build the driver with
E1000_TSO defined.
Enable or disable TSO:
sysctl net.inet.tcp.tso=1 or 0
0=disabled, 1=enabled (TSO is enabled by default).
NOTE: TSO is not supported on 82547 and 82544-based adapters, as well as
older adapters.
Known Limitations
=================
Detected Tx Unit Hang in Quad Port Adapters
-------------------------------------------
In some cases ports 3 and 4 wont pass traffic. Ports 1 and 2 don't show
any errors and will pass traffic.
This issue MAY be resolved by updating to the latest BIOS. You can
check your system's BIOS by downloading the Linux Firmware Developer Kit
that can be obtained at http://www.linuxfirmwarekit.org/
FreeBSD version 4.x with Symmetric MultiProcessing (SMP)
--------------------------------------------------------
In FreeBSD version 4.x with Symmetric MultiProcessing (SMP), there is a known
issue on some newer hardware. The problem is generic kernel and only in SMP
issue on some newer hardware. The problem is kernel generic and only in SMP
mode. The workaround is to either use FreeBSD version 4.x in single processor
mode, or use FreeBSD 5.4 or later.
There are known performance issues with this driver when running UDP traffic
with Jumbo Frames.
----------------------------------------------------------------------------
82541/82547 can't link or is slow to link with some link partners
-----------------------------------------------------------------
There is a known compatibility issue where time to link is slow or link is not
established between 82541/82547 controllers and some switches. Known switches
@ -325,12 +369,12 @@ Known Limitations
The driver can be compiled with the following changes:
Edit ./em.x.x.x/src/if_em.h to uncomment the #define EM_MASTER_SLAVE
Edit ./em.x.x.x/src/if_em.h to uncomment the #define E1000_MASTER_SLAVE
from within the comments. For example, change from:
/* #define EM_MASTER_SLAVE 2 */
/* #define E1000_MASTER_SLAVE 2 */
to:
#define EM_MASTER_SLAVE 2
#define E1000_MASTER_SLAVE 2
Use one of the following options:
1 = Master mode

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_80003ES2LAN_H_
#define _E1000_80003ES2LAN_H_
#include "e1000_api.h"
#define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00
#define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02
#define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10
#define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008
#define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800
#define E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING 0x0010
#define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004
#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000
#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000
#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8
#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9
/* GG82563 PHY Specific Status Register (Page 0, Register 16 */
#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Disabled */
#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060
#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI */
#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX */
#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */
/* PHY Specific Control Register 2 (Page 0, Register 26) */
#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000
/* 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 */
#define GG82563_MSCR_TX_CLK_MASK 0x0007
#define GG82563_MSCR_TX_CLK_10MBPS_2_5 0x0004
#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005
#define GG82563_MSCR_TX_CLK_1000MBPS_2_5 0x0006
#define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007
#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */
/* DSP Distance Register (Page 5, Register 26) */
#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* 0 = <50M;
1 = 50-80M;
2 = 80-110M;
3 = 110-140M;
4 = >140M */
/* Kumeran Mode Control Register (Page 193, Register 16) */
#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800
/* Power Management Control Register (Page 193, Register 20) */
#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001
/* 1=Enable SERDES Electrical Idle */
/* In-Band Control Register (Page 194, Register 18) */
#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */
#endif

677
sys/dev/em/e1000_82540.c Normal file
View File

@ -0,0 +1,677 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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$
/* e1000_82540
* e1000_82545
* e1000_82546
* e1000_82545_rev_3
* e1000_82546_rev_3
*/
#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);
static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw);
STATIC void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw);
STATIC s32 e1000_init_hw_82540(struct e1000_hw *hw);
STATIC s32 e1000_reset_hw_82540(struct e1000_hw *hw);
static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw);
static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw);
STATIC s32 e1000_setup_copper_link_82540(struct e1000_hw *hw);
STATIC s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw);
/**
* e1000_init_phy_params_82540 - Init PHY func ptrs.
* @hw - pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_phy_params_82540(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
phy->addr = 1;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
phy->reset_delay_us = 10000;
phy->type = e1000_phy_m88;
/* Function Pointers */
func->check_polarity = e1000_check_polarity_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->get_cfg_done = e1000_get_cfg_done_generic;
func->read_phy_reg = e1000_read_phy_reg_m88;
func->reset_phy = e1000_phy_hw_reset_generic;
func->write_phy_reg = e1000_write_phy_reg_m88;
func->get_phy_info = e1000_get_phy_info_m88;
ret_val = e1000_get_phy_id(hw);
if (ret_val)
goto out;
/* Verify phy id */
switch (hw->mac.type) {
case e1000_82540:
case e1000_82545:
case e1000_82545_rev_3:
case e1000_82546:
case e1000_82546_rev_3:
if (phy->id == M88E1011_I_PHY_ID)
break;
/* Fall Through */
default:
ret_val = -E1000_ERR_PHY;
goto out;
break;
}
out:
return ret_val;
}
/**
* e1000_init_nvm_params_82540 - Init NVM func ptrs.
* @hw - pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_nvm_params_82540(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);
DEBUGFUNC("e1000_init_nvm_params_82540");
nvm->type = e1000_nvm_eeprom_microwire;
nvm->delay_usec = 50;
nvm->opcode_bits = 3;
switch (nvm->override) {
case e1000_nvm_override_microwire_large:
nvm->address_bits = 8;
nvm->word_size = 256;
break;
case e1000_nvm_override_microwire_small:
nvm->address_bits = 6;
nvm->word_size = 64;
break;
default:
nvm->address_bits = eecd & E1000_EECD_SIZE ? 8 : 6;
nvm->word_size = eecd & E1000_EECD_SIZE ? 256 : 64;
break;
}
/* Function Pointers */
func->acquire_nvm = e1000_acquire_nvm_generic;
func->read_nvm = e1000_read_nvm_microwire;
func->release_nvm = e1000_release_nvm_generic;
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_microwire;
return E1000_SUCCESS;
}
/**
* e1000_init_mac_params_82540 - Init MAC func ptrs.
* @hw - pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_mac_params_82540(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_mac_params_82540");
/* Set media type */
switch (hw->device_id) {
case E1000_DEV_ID_82545EM_FIBER:
case E1000_DEV_ID_82545GM_FIBER:
case E1000_DEV_ID_82546EB_FIBER:
case E1000_DEV_ID_82546GB_FIBER:
hw->media_type = e1000_media_type_fiber;
break;
case E1000_DEV_ID_82545GM_SERDES:
case E1000_DEV_ID_82546GB_SERDES:
hw->media_type = e1000_media_type_internal_serdes;
break;
default:
hw->media_type = e1000_media_type_copper;
break;
}
/* Set mta register count */
mac->mta_reg_count = 128;
/* Set rar entry count */
mac->rar_entry_count = E1000_RAR_ENTRIES;
/* Function pointers */
/* bus type/speed/width */
func->get_bus_info = e1000_get_bus_info_pci_generic;
/* reset */
func->reset_hw = e1000_reset_hw_82540;
/* hw initialization */
func->init_hw = e1000_init_hw_82540;
/* link setup */
func->setup_link = e1000_setup_link_generic;
/* physical interface setup */
func->setup_physical_interface =
(hw->media_type == e1000_media_type_copper)
? e1000_setup_copper_link_82540
: e1000_setup_fiber_serdes_link_82540;
/* check for link */
switch (hw->media_type) {
case e1000_media_type_copper:
func->check_for_link = e1000_check_for_copper_link_generic;
break;
case e1000_media_type_fiber:
func->check_for_link = e1000_check_for_fiber_link_generic;
break;
case e1000_media_type_internal_serdes:
func->check_for_link = e1000_check_for_serdes_link_generic;
break;
default:
ret_val = -E1000_ERR_CONFIG;
goto out;
break;
}
/* link info */
func->get_link_up_info =
(hw->media_type == e1000_media_type_copper)
? e1000_get_speed_and_duplex_copper_generic
: e1000_get_speed_and_duplex_fiber_serdes_generic;
/* multicast address update */
func->mc_addr_list_update = e1000_mc_addr_list_update_generic;
/* writing VFTA */
func->write_vfta = e1000_write_vfta_generic;
/* clearing VFTA */
func->clear_vfta = e1000_clear_vfta_generic;
/* setting MTA */
func->mta_set = e1000_mta_set_generic;
/* setup LED */
func->setup_led = e1000_setup_led_generic;
/* cleanup LED */
func->cleanup_led = e1000_cleanup_led_generic;
/* turn on/off LED */
func->led_on = e1000_led_on_generic;
func->led_off = e1000_led_off_generic;
/* clear hardware counters */
func->clear_hw_cntrs = e1000_clear_hw_cntrs_82540;
out:
return ret_val;
}
/**
* e1000_init_function_pointers_82540 - Init func ptrs.
* @hw - pointer to the HW structure
*
* The only function explicitly called by the api module to initialize
* all function pointers and parameters.
**/
void
e1000_init_function_pointers_82540(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_init_function_pointers_82540");
hw->func.init_mac_params = e1000_init_mac_params_82540;
hw->func.init_nvm_params = e1000_init_nvm_params_82540;
hw->func.init_phy_params = e1000_init_phy_params_82540;
}
/**
* e1000_reset_hw_82540 - Reset hardware
* @hw - pointer to the HW structure
*
* 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_82540(struct e1000_hw *hw)
{
u32 ctrl, icr, manc;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_reset_hw_82540");
DEBUGOUT("Masking off all interrupts\n");
E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
E1000_WRITE_REG(hw, E1000_RCTL, 0);
E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
E1000_WRITE_FLUSH(hw);
/* Delay to allow any outstanding PCI transactions to complete
* before resetting the device.
*/
msec_delay(10);
ctrl = E1000_READ_REG(hw, E1000_CTRL);
DEBUGOUT("Issuing a global reset to 82540/82545/82546 MAC\n");
switch (hw->mac.type) {
case e1000_82545_rev_3:
case e1000_82546_rev_3:
E1000_WRITE_REG(hw, E1000_CTRL_DUP, ctrl | E1000_CTRL_RST);
break;
default:
/* These controllers can't ack the 64-bit write when
* issuing the reset, so we use IO-mapping as a
* workaround to issue the reset.
*/
E1000_WRITE_REG_IO(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
break;
}
/* Wait for EEPROM reload */
msec_delay(5);
/* Disable HW ARPs on ASF enabled adapters */
manc = E1000_READ_REG(hw, E1000_MANC);
manc &= ~E1000_MANC_ARP_EN;
E1000_WRITE_REG(hw, E1000_MANC, manc);
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
icr = E1000_READ_REG(hw, E1000_ICR);
return ret_val;
}
/**
* e1000_init_hw_82540 - Initialize hardware
* @hw - pointer to the HW structure
*
* This inits the hardware readying it for operation. This is a
* function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_hw_82540(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
u32 txdctl, ctrl_ext;
s32 ret_val = E1000_SUCCESS;
u16 i;
DEBUGFUNC("e1000_init_hw_82540");
/* Initialize identification LED */
ret_val = e1000_id_led_init_generic(hw);
if (ret_val) {
DEBUGOUT("Error initializing identification LED\n");
goto out;
}
/* Disabling VLAN filtering */
DEBUGOUT("Initializing the IEEE VLAN\n");
if (mac->type < e1000_82545_rev_3) {
E1000_WRITE_REG(hw, E1000_VET, 0);
}
e1000_clear_vfta(hw);
/* Setup the receive address. */
e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
/* Zero out the Multicast HASH table */
DEBUGOUT("Zeroing the MTA\n");
for (i = 0; i < mac->mta_reg_count; i++) {
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
/* Avoid back to back register writes by adding the register
* read (flush). This is to protect against some strange
* bridge configurations that may issue Memory Write Block
* (MWB) to our register space. The *_rev_3 hardware at
* least doesn't respond correctly to every other dword in an
* MWB to our register space.
*/
E1000_WRITE_FLUSH(hw);
}
if (mac->type < e1000_82545_rev_3)
e1000_pcix_mmrbc_workaround_generic(hw);
/* Setup link and flow control */
ret_val = e1000_setup_link(hw);
txdctl = E1000_READ_REG(hw, E1000_TXDCTL);
txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
E1000_TXDCTL_FULL_TX_DESC_WB;
E1000_WRITE_REG(hw, E1000_TXDCTL, txdctl);
/* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there
* is no link.
*/
e1000_clear_hw_cntrs_82540(hw);
if ((hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER) ||
(hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3)) {
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
/* Relaxed ordering must be disabled to avoid a parity
* error crash in a PCI slot. */
ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
}
out:
return ret_val;
}
/**
* e1000_setup_copper_link_82540 - Configure copper link settings
* @hw - pointer to the HW structure
*
* Calls the appropriate function to configure the link for auto-neg or forced
* speed and duplex. Then we check for link, once link is established calls
* to configure collision distance and flow control are called. If link is
* not established, we return -E1000_ERR_PHY (-2). This is a function
* pointer entry point called by the api module.
**/
STATIC s32
e1000_setup_copper_link_82540(struct e1000_hw *hw)
{
u32 ctrl;
s32 ret_val = E1000_SUCCESS;
u16 data;
DEBUGFUNC("e1000_setup_copper_link_82540");
ctrl = E1000_READ_REG(hw, E1000_CTRL);
ctrl |= E1000_CTRL_SLU;
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
ret_val = e1000_set_phy_mode_82540(hw);
if (ret_val)
goto out;
if (hw->mac.type == e1000_82545_rev_3 ||
hw->mac.type == e1000_82546_rev_3) {
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &data);
if (ret_val)
goto out;
data |= 0x00000008;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, data);
if (ret_val)
goto out;
}
ret_val = e1000_copper_link_setup_m88(hw);
if (ret_val)
goto out;
ret_val = e1000_setup_copper_link_generic(hw);
out:
return ret_val;
}
/**
* e1000_setup_fiber_serdes_link_82540 - Setup link for fiber/serdes
* @hw - pointer to the HW structure
*
* Set the output amplitude to the value in the EEPROM and adjust the VCO
* speed to improve Bit Error Rate (BER) performance. Configures collision
* distance and flow control for fiber and serdes links. Upon successful
* setup, poll for link. This is a function pointer entry point called by
* the api module.
**/
STATIC s32
e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_setup_fiber_serdes_link_82540");
switch (mac->type) {
case e1000_82545_rev_3:
case e1000_82546_rev_3:
if (hw->media_type == e1000_media_type_internal_serdes) {
/* If we're on serdes media, adjust the output
* amplitude to value set in the EEPROM.
*/
ret_val = e1000_adjust_serdes_amplitude_82540(hw);
if (ret_val)
goto out;
}
/* Adjust VCO speed to improve BER performance */
ret_val = e1000_set_vco_speed_82540(hw);
if (ret_val)
goto out;
default:
break;
}
ret_val = e1000_setup_fiber_serdes_link_generic(hw);
out:
return ret_val;
}
/**
* 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.
**/
static s32
e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 nvm_data;
DEBUGFUNC("e1000_adjust_serdes_amplitude_82540");
ret_val = e1000_read_nvm(hw, NVM_SERDES_AMPLITUDE, 1, &nvm_data);
if (ret_val) {
goto out;
}
if (nvm_data != NVM_RESERVED_WORD) {
/* Adjust serdes output amplitude only. */
nvm_data &= NVM_SERDES_AMPLITUDE_MASK;
ret_val = e1000_write_phy_reg(hw,
M88E1000_PHY_EXT_CTRL,
nvm_data);
if (ret_val)
goto out;
}
out:
return ret_val;
}
/**
* e1000_set_vco_speed_82540 - Set VCO speed for better performance
* @hw - pointer to the HW structure
*
* Set the VCO speed to improve Bit Error Rate (BER) performance.
**/
static s32
e1000_set_vco_speed_82540(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 default_page = 0;
u16 phy_data;
DEBUGFUNC("e1000_set_vco_speed_82540");
/* Set PHY register 30, page 5, bit 8 to 0 */
ret_val = e1000_read_phy_reg(hw,
M88E1000_PHY_PAGE_SELECT,
&default_page);
if (ret_val)
goto out;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
if (ret_val)
goto out;
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
if (ret_val)
goto out;
phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
if (ret_val)
goto out;
/* Set PHY register 30, page 4, bit 11 to 1 */
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
if (ret_val)
goto out;
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
if (ret_val)
goto out;
phy_data |= M88E1000_PHY_VCO_REG_BIT11;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
if (ret_val)
goto out;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
default_page);
out:
return ret_val;
}
/**
* e1000_set_phy_mode_82540 - Set PHY to class A mode
* @hw - pointer to the HW structure
*
* Sets the PHY to class A mode and assumes the following operations will
* follow to enable the new class mode:
* 1. Do a PHY soft reset.
* 2. Restart auto-negotiation or force link.
**/
static s32
e1000_set_phy_mode_82540(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS;
u16 nvm_data;
DEBUGFUNC("e1000_set_phy_mode_82540");
if (hw->mac.type != e1000_82545_rev_3)
goto out;
ret_val = e1000_read_nvm(hw, NVM_PHY_CLASS_WORD, 1, &nvm_data);
if (ret_val) {
ret_val = -E1000_ERR_PHY;
goto out;
}
if ((nvm_data != NVM_RESERVED_WORD) && (nvm_data & NVM_PHY_CLASS_A)) {
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
0x000B);
if (ret_val) {
ret_val = -E1000_ERR_PHY;
goto out;
}
ret_val = e1000_write_phy_reg(hw,
M88E1000_PHY_GEN_CONTROL,
0x8104);
if (ret_val) {
ret_val = -E1000_ERR_PHY;
goto out;
}
phy->reset_disable = FALSE;
}
out:
return ret_val;
}
/**
* e1000_clear_hw_cntrs_82540 - Clear device specific hardware counters
* @hw - pointer to the HW structure
*
* Clears the hardware counters by reading the counter registers.
**/
STATIC void
e1000_clear_hw_cntrs_82540(struct e1000_hw *hw)
{
volatile u32 temp;
DEBUGFUNC("e1000_clear_hw_cntrs_82540");
e1000_clear_hw_cntrs_base_generic(hw);
temp = E1000_READ_REG(hw, E1000_PRC64);
temp = E1000_READ_REG(hw, E1000_PRC127);
temp = E1000_READ_REG(hw, E1000_PRC255);
temp = E1000_READ_REG(hw, E1000_PRC511);
temp = E1000_READ_REG(hw, E1000_PRC1023);
temp = E1000_READ_REG(hw, E1000_PRC1522);
temp = E1000_READ_REG(hw, E1000_PTC64);
temp = E1000_READ_REG(hw, E1000_PTC127);
temp = E1000_READ_REG(hw, E1000_PTC255);
temp = E1000_READ_REG(hw, E1000_PTC511);
temp = E1000_READ_REG(hw, E1000_PTC1023);
temp = E1000_READ_REG(hw, E1000_PTC1522);
temp = E1000_READ_REG(hw, E1000_ALGNERRC);
temp = E1000_READ_REG(hw, E1000_RXERRC);
temp = E1000_READ_REG(hw, E1000_TNCRS);
temp = E1000_READ_REG(hw, E1000_CEXTERR);
temp = E1000_READ_REG(hw, E1000_TSCTC);
temp = E1000_READ_REG(hw, E1000_TSCTFC);
temp = E1000_READ_REG(hw, E1000_MGTPRC);
temp = E1000_READ_REG(hw, E1000_MGTPDC);
temp = E1000_READ_REG(hw, E1000_MGTPTC);
}

1312
sys/dev/em/e1000_82541.c Normal file

File diff suppressed because it is too large Load Diff

93
sys/dev/em/e1000_82541.h Normal file
View File

@ -0,0 +1,93 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_82541_H_
#define _E1000_82541_H_
#include "e1000_api.h"
#define NVM_WORD_SIZE_BASE_SHIFT_82541 (NVM_WORD_SIZE_BASE_SHIFT + 1)
#define IGP01E1000_PHY_CHANNEL_NUM 4
#define IGP01E1000_PHY_AGC_A 0x1172
#define IGP01E1000_PHY_AGC_B 0x1272
#define IGP01E1000_PHY_AGC_C 0x1472
#define IGP01E1000_PHY_AGC_D 0x1872
#define IGP01E1000_PHY_AGC_PARAM_A 0x1171
#define IGP01E1000_PHY_AGC_PARAM_B 0x1271
#define IGP01E1000_PHY_AGC_PARAM_C 0x1471
#define IGP01E1000_PHY_AGC_PARAM_D 0x1871
#define IGP01E1000_PHY_EDAC_MU_INDEX 0xC000
#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000
#define IGP01E1000_PHY_DSP_RESET 0x1F33
#define IGP01E1000_PHY_DSP_FFE 0x1F35
#define IGP01E1000_PHY_DSP_FFE_CM_CP 0x0069
#define IGP01E1000_PHY_DSP_FFE_DEFAULT 0x002A
#define IGP01E1000_IEEE_FORCE_GIG 0x0140
#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
#define IGP01E1000_AGC_LENGTH_SHIFT 7
#define IGP01E1000_AGC_RANGE 10
#define FFE_IDLE_ERR_COUNT_TIMEOUT_20 20
#define FFE_IDLE_ERR_COUNT_TIMEOUT_100 100
#define IGP01E1000_ANALOG_FUSE_STATUS 0x20D0
#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x20D1
#define IGP01E1000_ANALOG_FUSE_CONTROL 0x20DC
#define IGP01E1000_ANALOG_FUSE_BYPASS 0x20DE
#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED 0x0100
#define IGP01E1000_ANALOG_FUSE_FINE_MASK 0x0F80
#define IGP01E1000_ANALOG_FUSE_COARSE_MASK 0x0070
#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH 0x0040
#define IGP01E1000_ANALOG_FUSE_COARSE_10 0x0010
#define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080
#define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500
#define IGP01E1000_ANALOG_FUSE_POLY_MASK 0xF000
#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL 0x0002
#define IGP01E1000_MSE_CHANNEL_D 0x000F
#define IGP01E1000_MSE_CHANNEL_C 0x00F0
#define IGP01E1000_MSE_CHANNEL_B 0x0F00
#define IGP01E1000_MSE_CHANNEL_A 0xF000
#endif

558
sys/dev/em/e1000_82542.c Normal file
View File

@ -0,0 +1,558 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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$
/* e1000_82542 (rev 1 & 2)
*/
#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);
STATIC s32 e1000_get_bus_info_82542(struct e1000_hw *hw);
STATIC s32 e1000_reset_hw_82542(struct e1000_hw *hw);
STATIC s32 e1000_init_hw_82542(struct e1000_hw *hw);
STATIC s32 e1000_setup_link_82542(struct e1000_hw *hw);
STATIC s32 e1000_led_on_82542(struct e1000_hw *hw);
STATIC s32 e1000_led_off_82542(struct e1000_hw *hw);
STATIC void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw);
struct e1000_dev_spec_82542 {
boolean_t dma_fairness;
};
/**
* e1000_init_phy_params_82542 - Init PHY func ptrs.
* @hw - pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_phy_params_82542(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_phy_params_82542");
phy->type = e1000_phy_none;
return ret_val;
}
/**
* e1000_init_nvm_params_82542 - Init NVM func ptrs.
* @hw - pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_nvm_params_82542(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
struct e1000_functions *func = &hw->func;
DEBUGFUNC("e1000_init_nvm_params_82542");
nvm->address_bits = 6;
nvm->delay_usec = 50;
nvm->opcode_bits = 3;
nvm->type = e1000_nvm_eeprom_microwire;
nvm->word_size = 64;
/* Function Pointers */
func->read_nvm = e1000_read_nvm_microwire;
func->release_nvm = e1000_stop_nvm;
func->write_nvm = e1000_write_nvm_microwire;
func->update_nvm = e1000_update_nvm_checksum_generic;
func->validate_nvm = e1000_validate_nvm_checksum_generic;
return E1000_SUCCESS;
}
/**
* e1000_init_mac_params_82542 - Init MAC func ptrs.
* @hw - pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_mac_params_82542(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_mac_params_82542");
/* Set media type */
hw->media_type = e1000_media_type_fiber;
/* Set mta register count */
mac->mta_reg_count = 128;
/* Set rar entry count */
mac->rar_entry_count = E1000_RAR_ENTRIES;
/* Function pointers */
/* bus type/speed/width */
func->get_bus_info = e1000_get_bus_info_82542;
/* reset */
func->reset_hw = e1000_reset_hw_82542;
/* hw initialization */
func->init_hw = e1000_init_hw_82542;
/* link setup */
func->setup_link = e1000_setup_link_82542;
/* phy/fiber/serdes setup */
func->setup_physical_interface = e1000_setup_fiber_serdes_link_generic;
/* check for link */
func->check_for_link = e1000_check_for_fiber_link_generic;
/* multicast address update */
func->mc_addr_list_update = e1000_mc_addr_list_update_generic;
/* writing VFTA */
func->write_vfta = e1000_write_vfta_generic;
/* clearing VFTA */
func->clear_vfta = e1000_clear_vfta_generic;
/* setting MTA */
func->mta_set = e1000_mta_set_generic;
/* turn on/off LED */
func->led_on = e1000_led_on_82542;
func->led_off = e1000_led_off_82542;
/* remove device */
func->remove_device = e1000_remove_device_generic;
/* clear hardware counters */
func->clear_hw_cntrs = e1000_clear_hw_cntrs_82542;
/* link info */
func->get_link_up_info = e1000_get_speed_and_duplex_fiber_serdes_generic;
hw->dev_spec_size = sizeof(struct e1000_dev_spec_82542);
/* Device-specific structure allocation */
ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size);
return ret_val;
}
/**
* e1000_init_function_pointers_82542 - Init func ptrs.
* @hw - pointer to the HW structure
*
* The only function explicitly called by the api module to initialize
* all function pointers and parameters.
**/
void
e1000_init_function_pointers_82542(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_init_function_pointers_82542");
hw->func.init_mac_params = e1000_init_mac_params_82542;
hw->func.init_nvm_params = e1000_init_nvm_params_82542;
hw->func.init_phy_params = e1000_init_phy_params_82542;
}
/**
* e1000_get_bus_info_82542 - Obtain bus information for adapter
* @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
* pointer entry point called by the api module.
**/
STATIC s32
e1000_get_bus_info_82542(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_get_bus_info_82542");
hw->bus.type = e1000_bus_type_pci;
hw->bus.speed = e1000_bus_speed_unknown;
hw->bus.width = e1000_bus_width_unknown;
return E1000_SUCCESS;
}
/**
* e1000_reset_hw_82542 - Reset hardware
* @hw - pointer to the HW structure
*
* 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_82542(struct e1000_hw *hw)
{
struct e1000_bus_info *bus = &hw->bus;
s32 ret_val = E1000_SUCCESS;
u32 ctrl, icr;
DEBUGFUNC("e1000_reset_hw_82542");
if (hw->revision_id == E1000_REVISION_2) {
DEBUGOUT("Disabling MWI on 82542 rev 2\n");
e1000_pci_clear_mwi(hw);
}
DEBUGOUT("Masking off all interrupts\n");
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
E1000_WRITE_REG(hw, E1000_RCTL, 0);
E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
E1000_WRITE_FLUSH(hw);
/* Delay to allow any outstanding PCI transactions to complete before
* resetting the device
*/
msec_delay(10);
ctrl = E1000_READ_REG(hw, E1000_CTRL);
DEBUGOUT("Issuing a global reset to 82542/82543 MAC\n");
E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
e1000_reload_nvm(hw);
msec_delay(2);
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
icr = E1000_READ_REG(hw, E1000_ICR);
if (hw->revision_id == E1000_REVISION_2) {
if (bus->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
e1000_pci_set_mwi(hw);
}
return ret_val;
}
/**
* e1000_init_hw_82542 - Initialize hardware
* @hw - pointer to the HW structure
*
* This inits the hardware readying it for operation. This is a
* function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_hw_82542(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
struct e1000_dev_spec_82542 *dev_spec;
s32 ret_val = E1000_SUCCESS;
u32 ctrl;
u16 i;
DEBUGFUNC("e1000_init_hw_82542");
dev_spec = (struct e1000_dev_spec_82542 *)hw->dev_spec;
/* Disabling VLAN filtering */
E1000_WRITE_REG(hw, E1000_VET, 0);
e1000_clear_vfta(hw);
/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
if (hw->revision_id == E1000_REVISION_2) {
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
e1000_pci_clear_mwi(hw);
E1000_WRITE_REG(hw, E1000_RCTL, E1000_RCTL_RST);
E1000_WRITE_FLUSH(hw);
msec_delay(5);
}
/* Setup the receive address. */
e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
if (hw->revision_id == E1000_REVISION_2) {
E1000_WRITE_REG(hw, E1000_RCTL, 0);
E1000_WRITE_FLUSH(hw);
msec_delay(1);
if (hw->bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
e1000_pci_set_mwi(hw);
}
/* Zero out the Multicast HASH table */
DEBUGOUT("Zeroing the MTA\n");
for (i = 0; i < mac->mta_reg_count; i++)
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
/* Set the PCI priority bit correctly in the CTRL register. This
* determines if the adapter gives priority to receives, or if it
* gives equal priority to transmits and receives.
*/
if (dev_spec->dma_fairness) {
ctrl = E1000_READ_REG(hw, E1000_CTRL);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR);
}
/* Setup link and flow control */
ret_val = e1000_setup_link_82542(hw);
/* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there
* is no link.
*/
e1000_clear_hw_cntrs_82542(hw);
return ret_val;
}
/**
* e1000_setup_link_82542 - Setup flow control and link settings
* @hw - pointer to the HW structure
*
* Determines which flow control settings to use, then configures flow
* control. Calls the appropriate media-specific link configuration
* function. Assuming the adapter has a valid link partner, a valid link
* should be established. Assumes the hardware has previously been reset
* and the transmitter and receiver are not enabled. This is a function
* pointer entry point called by the api module.
**/
STATIC s32
e1000_setup_link_82542(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_setup_link_82542");
ret_val = e1000_set_default_fc_generic(hw);
if (ret_val)
goto out;
mac->fc &= ~e1000_fc_tx_pause;
if (mac->report_tx_early == 1)
mac->fc &= ~e1000_fc_rx_pause;
/* We want to save off the original Flow Control configuration just in
* case we get disconnected and then reconnected into a different hub
* or switch with different Flow Control capabilities.
*/
mac->original_fc = mac->fc;
DEBUGOUT1("After fix-ups FlowControl is now = %x\n", mac->fc);
/* Call the necessary subroutine to configure the link. */
ret_val = func->setup_physical_interface(hw);
if (ret_val)
goto out;
/* Initialize the flow control address, type, and PAUSE timer
* registers to their default values. This is done even if flow
* control is disabled, because it does not hurt anything to
* initialize these registers.
*/
DEBUGOUT("Initializing Flow Control address, type and timer regs\n");
E1000_WRITE_REG(hw, E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW);
E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
E1000_WRITE_REG(hw, E1000_FCT, FLOW_CONTROL_TYPE);
E1000_WRITE_REG(hw, E1000_FCTTV, mac->fc_pause_time);
ret_val = e1000_set_fc_watermarks_generic(hw);
out:
return ret_val;
}
/**
* e1000_led_on_82542 - Turn on SW controllable LED
* @hw - pointer to the HW structure
*
* Turns the SW defined LED on. This is a function pointer entry point
* called by the api module.
**/
STATIC s32
e1000_led_on_82542(struct e1000_hw *hw)
{
u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
DEBUGFUNC("e1000_led_on_82542");
ctrl |= E1000_CTRL_SWDPIN0;
ctrl |= E1000_CTRL_SWDPIO0;
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
return E1000_SUCCESS;
}
/**
* e1000_led_off_82542 - Turn off SW controllable LED
* @hw - pointer to the HW structure
*
* Turns the SW defined LED off. This is a function pointer entry point
* called by the api module.
**/
STATIC s32
e1000_led_off_82542(struct e1000_hw *hw)
{
u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
DEBUGFUNC("e1000_led_off_82542");
ctrl &= ~E1000_CTRL_SWDPIN0;
ctrl |= E1000_CTRL_SWDPIO0;
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
return E1000_SUCCESS;
}
/**
* e1000_translate_register_82542 - Translate the proper regiser offset
* @reg - e1000 register to be read
*
* Registers in 82542 are located in different offsets than other adapters
* even though they function in the same manner. This function takes in
* the name of the register to read and returns the correct offset for
* 82542 silicon.
**/
u32
e1000_translate_register_82542(u32 reg)
{
/* Some of the 82542 registers are located at different
* offsets than they are in newer adapters.
* Despite the difference in location, the registers
* function in the same manner.
*/
switch (reg) {
case E1000_RA:
reg = 0x00040;
break;
case E1000_RDTR:
reg = 0x00108;
break;
case E1000_RDBAL:
reg = 0x00110;
break;
case E1000_RDBAH:
reg = 0x00114;
break;
case E1000_RDLEN:
reg = 0x00118;
break;
case E1000_RDH:
reg = 0x00120;
break;
case E1000_RDT:
reg = 0x00128;
break;
case E1000_RDBAL1:
reg = 0x00138;
break;
case E1000_RDBAH1:
reg = 0x0013C;
break;
case E1000_RDLEN1:
reg = 0x00140;
break;
case E1000_RDH1:
reg = 0x00148;
break;
case E1000_RDT1:
reg = 0x00150;
break;
case E1000_FCRTH:
reg = 0x00160;
break;
case E1000_FCRTL:
reg = 0x00168;
break;
case E1000_MTA:
reg = 0x00200;
break;
case E1000_TDBAL:
reg = 0x00420;
break;
case E1000_TDBAH:
reg = 0x00424;
break;
case E1000_TDLEN:
reg = 0x00428;
break;
case E1000_TDH:
reg = 0x00430;
break;
case E1000_TDT:
reg = 0x00438;
break;
case E1000_TIDV:
reg = 0x00440;
break;
case E1000_VFTA:
reg = 0x00600;
break;
case E1000_TDFH:
reg = 0x08010;
break;
case E1000_TDFT:
reg = 0x08018;
break;
default:
break;
}
return reg;
}
/**
* e1000_clear_hw_cntrs_82542 - Clear device specific hardware counters
* @hw - pointer to the HW structure
*
* Clears the hardware counters by reading the counter registers.
**/
STATIC void
e1000_clear_hw_cntrs_82542(struct e1000_hw *hw)
{
volatile u32 temp;
DEBUGFUNC("e1000_clear_hw_cntrs_82542");
e1000_clear_hw_cntrs_base_generic(hw);
temp = E1000_READ_REG(hw, E1000_PRC64);
temp = E1000_READ_REG(hw, E1000_PRC127);
temp = E1000_READ_REG(hw, E1000_PRC255);
temp = E1000_READ_REG(hw, E1000_PRC511);
temp = E1000_READ_REG(hw, E1000_PRC1023);
temp = E1000_READ_REG(hw, E1000_PRC1522);
temp = E1000_READ_REG(hw, E1000_PTC64);
temp = E1000_READ_REG(hw, E1000_PTC127);
temp = E1000_READ_REG(hw, E1000_PTC255);
temp = E1000_READ_REG(hw, E1000_PTC511);
temp = E1000_READ_REG(hw, E1000_PTC1023);
temp = E1000_READ_REG(hw, E1000_PTC1522);
}

1650
sys/dev/em/e1000_82543.c Normal file

File diff suppressed because it is too large Load Diff

52
sys/dev/em/e1000_82543.h Normal file
View File

@ -0,0 +1,52 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_82543_H_
#define _E1000_82543_H_
#include "e1000_api.h"
#define PHY_PREAMBLE 0xFFFFFFFF
#define PHY_PREAMBLE_SIZE 32
#define PHY_SOF 0x1
#define PHY_OP_READ 0x2
#define PHY_OP_WRITE 0x1
#define PHY_TURNAROUND 0x2
#define TBI_COMPAT_ENABLED 0x1 /* Global "knob" for the workaround */
#define TBI_SBP_ENABLED 0x2 /* If TBI_COMPAT_ENABLED,
* then this is the current state (on/off) */
#endif

1340
sys/dev/em/e1000_82571.c Normal file

File diff suppressed because it is too large Load Diff

49
sys/dev/em/e1000_82571.h Normal file
View File

@ -0,0 +1,49 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_82571_H_
#define _E1000_82571_H_
#include "e1000_api.h"
#define ID_LED_RESERVED_F746 0xF746
#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_OFF1_ON2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2))
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
#endif

1528
sys/dev/em/e1000_82575.c Normal file

File diff suppressed because it is too large Load Diff

284
sys/dev/em/e1000_82575.h Normal file
View File

@ -0,0 +1,284 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_82575_H_
#define _E1000_82575_H_
#include "e1000_api.h"
/* Receive Address Register Count
* Number of high/low register pairs in the RAR. The RAR (Receive Address
* Registers) holds the directed and multicast addresses that we monitor.
* These entries are also used for MAC-based filtering.
*/
#define E1000_RAR_ENTRIES_82575 16
#ifdef E1000_BIT_FIELDS
struct e1000_adv_data_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
union {
u32 data;
struct {
u32 datalen :16; /* Data buffer length */
u32 rsvd :4;
u32 dtyp :4; /* Descriptor type */
u32 dcmd :8; /* Descriptor command */
} config;
} lower;
union {
u32 data;
struct {
u32 status :4; /* Descriptor status */
u32 idx :4;
u32 popts :6; /* Packet Options */
u32 paylen :18; /* Payload length */
} options;
} upper;
};
#define E1000_TXD_DTYP_ADV_C 0x2 /* Advanced Context Descriptor */
#define E1000_TXD_DTYP_ADV_D 0x3 /* Advanced Data Descriptor */
#define E1000_ADV_TXD_CMD_DEXT 0x20 /* Descriptor extension (0 = legacy) */
#define E1000_ADV_TUCMD_SNAP 0x1 /* SNAP indication */
#define E1000_ADV_TUCMD_IPV4 0x2 /* IP Packet Type: 1=IPv4 */
#define E1000_ADV_TUCMD_IPV6 0x0 /* IP Packet Type: 0=IPv6 */
#define E1000_ADV_TUCMD_L4T_UDP 0x0 /* L4 Packet TYPE of UDP */
#define E1000_ADV_TUCMD_L4T_TCP 0x4 /* L4 Packet TYPE of TCP */
#define E1000_ADV_TUCMD_MKRREQ 0x10 /* Indicates markers are required */
#define E1000_ADV_DCMD_EOP 0x1 /* End of Packet */
#define E1000_ADV_DCMD_IFCS 0x2 /* Insert FCS (Ethernet CRC) */
#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 */
struct e1000_adv_context_desc {
union {
u32 ip_config;
struct {
u32 iplen :9;
u32 maclen :7;
u32 vlan_tag :16;
} fields;
} ip_setup;
u32 seq_num;
union {
u64 l4_config;
struct {
u32 mkrloc :9;
u32 tucmd :11;
u32 dtyp :4;
u32 adv :8;
u32 rsvd :4;
u32 idx :4;
u32 l4len :8;
u32 mss :16;
} fields;
} l4_setup;
};
#endif
/* SRRCTL bit definitions */
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00
#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
#define E1000_SRRCTL_DESCTYPE_LEGACY 0x00000000
#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000
#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
#define E1000_TX_HEAD_WB_ENABLE 0x1
#define E1000_TX_SEQNUM_WB_ENABLE 0x2
#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002
#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
#define E1000_EICR_TX_QUEUE ( \
E1000_EICR_TX_QUEUE0 | \
E1000_EICR_TX_QUEUE1 | \
E1000_EICR_TX_QUEUE2 | \
E1000_EICR_TX_QUEUE3)
#define E1000_EICR_RX_QUEUE ( \
E1000_EICR_RX_QUEUE0 | \
E1000_EICR_RX_QUEUE1 | \
E1000_EICR_RX_QUEUE2 | \
E1000_EICR_RX_QUEUE3)
#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE
#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE
#define EIMS_ENABLE_MASK ( \
E1000_EIMS_RX_QUEUE | \
E1000_EIMS_TX_QUEUE | \
E1000_EIMS_TCP_TIMER | \
E1000_EIMS_OTHER)
/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */
#define E1000_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */
#define E1000_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */
#define E1000_IMIREX_SIZE_BP 0x00001000 /* Packet size bypass */
#define E1000_IMIREX_CTRL_URG 0x00002000 /* Check URG bit in header */
#define E1000_IMIREX_CTRL_ACK 0x00004000 /* Check ACK bit in header */
#define E1000_IMIREX_CTRL_PSH 0x00008000 /* Check PSH bit in header */
#define E1000_IMIREX_CTRL_RST 0x00010000 /* Check RST bit in header */
#define E1000_IMIREX_CTRL_SYN 0x00020000 /* Check SYN bit in header */
#define E1000_IMIREX_CTRL_FIN 0x00040000 /* Check FIN bit in header */
#define E1000_IMIREX_CTRL_BP 0x00080000 /* Bypass check of control bits */
/* Receive Descriptor - Advanced */
union e1000_adv_rx_desc {
struct {
u64 pkt_addr; /* Packet buffer address */
u64 hdr_addr; /* Header buffer address */
} read;
struct {
struct {
struct {
u16 pkt_info; /* RSS type, Packet type */
u16 hdr_info; /* Split Header,
* header buffer length */
} lo_dword;
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; /* Packet length */
u16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define E1000_RXDADV_RSSTYPE_MASK 0x0000F000
#define E1000_RXDADV_RSSTYPE_SHIFT 12
#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
#define E1000_RXDADV_SPLITHEADER_EN 0x00001000
#define E1000_RXDADV_SPH 0x8000
#define E1000_RXDADV_HBO 0x00800000
/* RSS Hash results */
#define E1000_RXDADV_RSSTYPE_NONE 0x00000000
#define E1000_RXDADV_RSSTYPE_IPV4 0x00000001
#define E1000_RXDADV_RSSTYPE_IPV4_TCP 0x00000002
#define E1000_RXDADV_RSSTYPE_IPV6 0x00000003
#define E1000_RXDADV_RSSTYPE_IPV6_TCP 0x00000004
#define E1000_RXDADV_RSSTYPE_IPV6_EX 0x00000005
#define E1000_RXDADV_RSSTYPE_IPV6_TCP_EX 0x00000006
#define E1000_RXDADV_RSSTYPE_IPV4_UDP 0x00000007
#define E1000_RXDADV_RSSTYPE_IPV6_UDP 0x00000008
#define E1000_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009
/* Transmit Descriptor - Advanced */
union e1000_adv_tx_desc {
struct {
u64 buffer_addr; /* Address of descriptor's data buf */
u32 cmd_type_len;
u32 olinfo_status;
} read;
struct {
u64 rsvd; /* Reserved */
u32 nxtseq_seed;
u32 status;
} wb;
};
/* Adv Transmit Descriptor Config Masks */
#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
#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_ADV_MAC_LINKSEC 0x00040000 /* Apply LinkSec on packet */
#define E1000_ADV_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 */
#define E1000_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU*/
#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
/* Context descriptors */
struct e1000_adv_tx_context_desc {
u32 vlan_macip_lens;
u32 seqnum_seed;
u32 type_tucmd_mlhl;
u32 mss_l4len_idx;
};
#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
#define E1000_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
#define E1000_ADVTXD_TUCMD_SNAP 0x00000200 /* SNAP indication */
#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
#define E1000_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
#define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
#define E1000_ADVTXD_TUCMD_MKRREQ 0x00002000 /* Req requires Markers and CRC */
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
/* Additional Transmit Descriptor Control definitions */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
#define E1000_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. write-back flushing */
#define E1000_TXDCTL_PRIORITY 0x08000000 /* Tx Queue Arbitration Priority
0=low, 1=high */
/* Additional Receive Descriptor Control definitions */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
#define E1000_RXDCTL_SWFLSH 0x04000000 /* Rx Desc. write-back flushing */
/* Direct Cache Access (DCA) definitions */
#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5)
#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6)
#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7)
#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5)
#endif

1213
sys/dev/em/e1000_api.c Normal file

File diff suppressed because it is too large Load Diff

163
sys/dev/em/e1000_api.h Normal file
View File

@ -0,0 +1,163 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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"
s32 e1000_set_mac_type(struct e1000_hw *hw);
s32 e1000_setup_init_funcs(struct e1000_hw *hw, boolean_t 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_mc_addr_list_update(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);
s32 e1000_phy_hw_reset(struct e1000_hw *hw);
s32 e1000_phy_commit(struct e1000_hw *hw);
s32 e1000_read_mac_addr(struct e1000_hw *hw);
s32 e1000_read_part_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, boolean_t active);
s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
boolean_t e1000_check_mng_mode(struct e1000_hw *hw);
boolean_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
boolean_t 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);
void e1000_tbi_adjust_stats_82543(struct e1000_hw *hw,
struct e1000_hw_stats *stats,
u32 frame_len, u8 *mac_addr);
void e1000_set_tbi_compatibility_82543(struct e1000_hw *hw,
boolean_t state);
boolean_t e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw);
#ifndef NO_82542_SUPPORT
u32 e1000_translate_register_82542(u32 reg);
#endif
void e1000_init_script_state_82541(struct e1000_hw *hw, boolean_t state);
boolean_t e1000_get_laa_state_82571(struct e1000_hw *hw);
void e1000_set_laa_state_82571(struct e1000_hw *hw, boolean_t state);
void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
boolean_t state);
void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
u32 e1000_translate_register_adoram(u32 reg);
/* 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) \
(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) > ((a)->mac.min_frame_size - VLAN_TAG_SIZE)) && \
((length) <= ((a)->mac.max_frame_size + 1))) : \
(((length) > (a)->mac.min_frame_size) && \
((length) <= ((a)->mac.max_frame_size + VLAN_TAG_SIZE + 1)))))
#endif

1403
sys/dev/em/e1000_defines.h Normal file

File diff suppressed because it is too large Load Diff

724
sys/dev/em/e1000_hw.h Normal file
View File

@ -0,0 +1,724 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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;
#ifndef NO_82542_SUPPORT
#define E1000_DEV_ID_82542 0x1000
#endif
#define E1000_DEV_ID_82543GC_FIBER 0x1001
#define E1000_DEV_ID_82543GC_COPPER 0x1004
#define E1000_DEV_ID_82544EI_COPPER 0x1008
#define E1000_DEV_ID_82544EI_FIBER 0x1009
#define E1000_DEV_ID_82544GC_COPPER 0x100C
#define E1000_DEV_ID_82544GC_LOM 0x100D
#define E1000_DEV_ID_82540EM 0x100E
#define E1000_DEV_ID_82540EM_LOM 0x1015
#define E1000_DEV_ID_82540EP_LOM 0x1016
#define E1000_DEV_ID_82540EP 0x1017
#define E1000_DEV_ID_82540EP_LP 0x101E
#define E1000_DEV_ID_82545EM_COPPER 0x100F
#define E1000_DEV_ID_82545EM_FIBER 0x1011
#define E1000_DEV_ID_82545GM_COPPER 0x1026
#define E1000_DEV_ID_82545GM_FIBER 0x1027
#define E1000_DEV_ID_82545GM_SERDES 0x1028
#define E1000_DEV_ID_82546EB_COPPER 0x1010
#define E1000_DEV_ID_82546EB_FIBER 0x1012
#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
#define E1000_DEV_ID_82546GB_COPPER 0x1079
#define E1000_DEV_ID_82546GB_FIBER 0x107A
#define E1000_DEV_ID_82546GB_SERDES 0x107B
#define E1000_DEV_ID_82546GB_PCIE 0x108A
#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
#define E1000_DEV_ID_82541EI 0x1013
#define E1000_DEV_ID_82541EI_MOBILE 0x1018
#define E1000_DEV_ID_82541ER_LOM 0x1014
#define E1000_DEV_ID_82541ER 0x1078
#define E1000_DEV_ID_82541GI 0x1076
#define E1000_DEV_ID_82541GI_LF 0x107C
#define E1000_DEV_ID_82541GI_MOBILE 0x1077
#define E1000_DEV_ID_82547EI 0x1019
#define E1000_DEV_ID_82547EI_MOBILE 0x101A
#define E1000_DEV_ID_82547GI 0x1075
#define E1000_DEV_ID_82571EB_COPPER 0x105E
#define E1000_DEV_ID_82571EB_FIBER 0x105F
#define E1000_DEV_ID_82571EB_SERDES 0x1060
#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC
#define E1000_DEV_ID_82572EI_COPPER 0x107D
#define E1000_DEV_ID_82572EI_FIBER 0x107E
#define E1000_DEV_ID_82572EI_SERDES 0x107F
#define E1000_DEV_ID_82572EI 0x10B9
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82573L 0x109A
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
#define E1000_DEV_ID_ICH8_IGP_C 0x104B
#define E1000_DEV_ID_ICH8_IFE 0x104C
#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_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_82575EM_COPPER 0x10AA
#define E1000_DEV_ID_82575EM_FIBER_SERDES 0x10AC
#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,
#ifndef NO_82542_SUPPORT
e1000_82542,
#endif
e1000_82543,
e1000_82544,
e1000_82540,
e1000_82545,
e1000_82545_rev_3,
e1000_82546,
e1000_82546_rev_3,
e1000_82541,
e1000_82541_rev_2,
e1000_82547,
e1000_82547_rev_2,
e1000_82571,
e1000_82572,
e1000_82573,
e1000_80003es2lan,
e1000_ich8lan,
e1000_ich9lan,
e1000_82575,
e1000_num_macs
} 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_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_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_mode;
typedef enum {
e1000_ffe_config_enabled = 0,
e1000_ffe_config_active,
e1000_ffe_config_blocked
} e1000_ffe_config;
typedef enum {
e1000_dsp_config_disabled = 0,
e1000_dsp_config_enabled,
e1000_dsp_config_activated,
e1000_dsp_config_undefined = 0xFF
} e1000_dsp_config;
/* 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 gorcl;
u64 gorch;
u64 gotcl;
u64 gotch;
u64 rnbc;
u64 ruc;
u64 rfc;
u64 roc;
u64 rjc;
u64 mgprc;
u64 mgpdc;
u64 mgptc;
u64 torl;
u64 torh;
u64 totl;
u64 toth;
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 hgorcl;
u64 hgorch;
u64 hgotcl;
u64 hgotch;
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_functions {
/* Function pointers for the MAC. */
s32 (*init_mac_params)(struct e1000_hw *);
s32 (*blink_led)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
boolean_t (*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 (*mc_addr_list_update)(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 (*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*);
/* Function pointers for the PHY. */
s32 (*init_phy_params)(struct e1000_hw *);
s32 (*acquire_phy)(struct e1000_hw *);
s32 (*check_polarity)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*commit_phy)(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_phy_info)(struct e1000_hw *);
s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
void (*release_phy)(struct e1000_hw *);
s32 (*reset_phy)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, boolean_t);
s32 (*set_d3_lplu_state)(struct e1000_hw *, boolean_t);
s32 (*write_phy_reg)(struct e1000_hw *, u32, u16);
/* Function pointers for the NVM. */
s32 (*init_nvm_params)(struct e1000_hw *);
s32 (*acquire_nvm)(struct e1000_hw *);
s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *);
void (*release_nvm)(struct e1000_hw *);
void (*reload_nvm)(struct e1000_hw *);
s32 (*update_nvm)(struct e1000_hw *);
s32 (*valid_led_default)(struct e1000_hw *, u16 *);
s32 (*validate_nvm)(struct e1000_hw *);
s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
};
struct e1000_mac_info {
u8 addr[6];
u8 perm_addr[6];
e1000_mac_type type;
e1000_fc_mode fc;
e1000_fc_mode original_fc;
u32 collision_delta;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 max_frame_size;
u32 mc_filter_type;
u32 min_frame_size;
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;
u16 fc_high_water;
u16 fc_low_water;
u16 fc_pause_time;
u8 forced_speed_duplex;
boolean_t adaptive_ifs;
boolean_t arc_subsystem_valid;
boolean_t asf_firmware_present;
boolean_t autoneg;
boolean_t autoneg_failed;
boolean_t disable_av;
boolean_t disable_hw_init_bits;
boolean_t fc_send_xon;
boolean_t fc_strict_ieee;
boolean_t get_link_status;
boolean_t ifs_params_forced;
boolean_t in_ifs_mode;
boolean_t report_tx_early;
boolean_t serdes_has_link;
boolean_t tx_pkt_filtering;
};
struct e1000_phy_info {
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;
u16 autoneg_advertised;
u16 autoneg_mask;
u16 cable_length;
u16 max_cable_length;
u16 min_cable_length;
u8 mdix;
boolean_t disable_polarity_correction;
boolean_t is_mdix;
boolean_t polarity_correction;
boolean_t reset_disable;
boolean_t speed_downgraded;
boolean_t wait_for_link;
};
struct e1000_nvm_info {
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_hw {
void *back;
void *dev_spec;
u8 *hw_addr;
u8 *flash_address;
unsigned long io_base;
struct e1000_functions func;
struct e1000_mac_info mac;
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
struct e1000_host_mng_dhcp_cookie mng_cookie;
e1000_media_type media_type;
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

2482
sys/dev/em/e1000_ich8lan.c Normal file

File diff suppressed because it is too large Load Diff

117
sys/dev/em/e1000_ich8lan.h Normal file
View File

@ -0,0 +1,117 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_ICH8LAN_H_
#define _E1000_ICH8LAN_H_
#include "e1000_api.h"
#define ICH_FLASH_GFPREG 0x0000
#define ICH_FLASH_HSFSTS 0x0004
#define ICH_FLASH_HSFCTL 0x0006
#define ICH_FLASH_FADDR 0x0008
#define ICH_FLASH_FDATA0 0x0010
#define ICH_FLASH_READ_COMMAND_TIMEOUT 500
#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500
#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 3000000
#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
#define ICH_FLASH_CYCLE_REPEAT_COUNT 10
#define ICH_CYCLE_READ 0
#define ICH_CYCLE_WRITE 2
#define ICH_CYCLE_ERASE 3
#define FLASH_GFPREG_BASE_MASK 0x1FFF
#define FLASH_SECTOR_ADDR_SHIFT 12
#define E1000_SHADOW_RAM_WORDS 2048
#define ICH_FLASH_SEG_SIZE_256 256
#define ICH_FLASH_SEG_SIZE_4K 4096
#define ICH_FLASH_SEG_SIZE_8K 8192
#define ICH_FLASH_SEG_SIZE_64K 65536
#define ICH_FLASH_SECTOR_SIZE 4096
#define ICH_FLASH_REG_MAPSIZE 0x00A0
#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */
#define E1000_ICH_FWSM_DISSW 0x10000000 /* FW Disables SW Writes */
#define E1000_ICH_FWSM_FW_VALID 0x00008000 /* FW established a valid
* mode.
*/
#define E1000_ICH_MNG_IAMT_MODE 0x2
#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_DEF1_OFF2 << 8) | \
(ID_LED_DEF1_ON2 << 4) | \
(ID_LED_DEF1_DEF2))
#define E1000_ICH_NVM_SIG_WORD 0x13
#define E1000_ICH_NVM_SIG_MASK 0xC000
#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 PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7
#define PHY_PAGE_SHIFT 5
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
((reg) & MAX_PHY_REG_ADDRESS))
#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */
#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */
#define IGP3_CAPABILITY PHY_REG(776, 19) /* Capability */
#define IGP3_PM_CTRL PHY_REG(769, 20) /* Power Management Control */
#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002
#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
#define IGP3_PM_CTRL_FORCE_PWR_DOWN 0x0020
/* Additional interrupts need to be handled for ICH family:
DSW = The FW changed the status of the DISSW bit in FWSM
PHYINT = The LAN connected device generates an interrupt
EPRST = Manageability reset event */
#define IMS_ICH_ENABLE_MASK (\
E1000_IMS_DSW | \
E1000_IMS_PHYINT | \
E1000_IMS_EPRST)
#endif

1987
sys/dev/em/e1000_mac.c Normal file

File diff suppressed because it is too large Load Diff

93
sys/dev/em/e1000_mac.h Normal file
View File

@ -0,0 +1,93 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_
#include "e1000_api.h"
/* Functions that should not be called directly from drivers but can be used
* by other files in this 'shared code'
*/
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_mc_addr_list_update_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);
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

391
sys/dev/em/e1000_manage.c Normal file
View File

@ -0,0 +1,391 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_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 operaton
* 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 managament mode
* @hw - pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
* manageability is enabled, else false (0).
**/
boolean_t
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.
**/
boolean_t
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;
boolean_t tx_filter = TRUE;
DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
/* No manageability, no filtering */
if (!e1000_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 = e1000_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 = e1000_mng_enable_host_if(hw);
if (ret_val)
goto out;
/* Populate the host interface with the contents of "buffer". */
ret_val = e1000_mng_host_if_write(hw, buffer, length,
sizeof(hdr), &(hdr.checksum));
if (ret_val)
goto out;
/* Write the manageability command header */
ret_val = e1000_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 - Writes 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.
**/
boolean_t
e1000_enable_mng_pass_thru(struct e1000_hw *hw)
{
u32 manc;
u32 fwsm, factps;
boolean_t 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 == TRUE) {
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;
}

90
sys/dev/em/e1000_manage.h Normal file
View File

@ -0,0 +1,90 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_
#include "e1000_api.h"
boolean_t e1000_check_mng_mode_generic(struct e1000_hw *hw);
boolean_t 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 /* Number of bytes in range */
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Number of dwords in range */
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
#define E1000_HICR_C 0x02 /* Driver sets this bit when done
* to put command in RAM */
#define E1000_HICR_SV 0x04 /* Status Validity */
#define E1000_HICR_FW_RESET_ENABLE 0x40
#define E1000_HICR_FW_RESET 0x80
#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management
* Technology signature */
#endif

900
sys/dev/em/e1000_nvm.c Normal file
View File

@ -0,0 +1,900 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_nvm.h"
/**
* 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 Microcwire 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 = e1000_acquire_nvm(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:
e1000_release_nvm(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 = e1000_acquire_nvm(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:
e1000_release_nvm(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,
* 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 likley 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 = e1000_acquire_nvm(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:
e1000_release_nvm(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 likley 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 = e1000_acquire_nvm(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:
e1000_release_nvm(hw);
out:
return ret_val;
}
/**
* e1000_read_part_num_generic - Read device part number
* @hw - pointer to the HW structure
* @part_num - pointer to device part number
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in part_num.
**/
s32
e1000_read_part_num_generic(struct e1000_hw *hw, u32 *part_num)
{
s32 ret_val;
u16 nvm_data;
DEBUGFUNC("e1000_read_part_num_generic");
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
*part_num = (u32)(nvm_data << 16);
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
*part_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 = e1000_read_nvm(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 = e1000_read_nvm(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 = e1000_read_nvm(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 = e1000_write_nvm(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);
}
/* Function pointers local to this file and not intended for public use */
/**
* e1000_acquire_nvm - Acquire exclusive access to EEPROM
* @hw - pointer to the HW structure
*
* For those silicon families which have implemented a NVM acquire function,
* run the defined function else return success.
**/
s32
e1000_acquire_nvm(struct e1000_hw *hw)
{
if (hw->func.acquire_nvm != NULL)
return hw->func.acquire_nvm(hw);
else
return E1000_SUCCESS;
}
/**
* e1000_release_nvm - Release exclusive access to EEPROM
* @hw - pointer to the HW structure
*
* For those silicon families which have implemented a NVM release function,
* run the defined fucntion else return success.
**/
void
e1000_release_nvm(struct e1000_hw *hw)
{
if (hw->func.release_nvm != NULL)
hw->func.release_nvm(hw);
}

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

@ -0,0 +1,68 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_
#include "e1000_api.h"
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_part_num_generic(struct e1000_hw *hw, u32 *part_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);
/* Function pointers */
s32 e1000_acquire_nvm(struct e1000_hw *hw);
void e1000_release_nvm(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#endif

188
sys/dev/em/e1000_osdep.h Normal file
View File

@ -0,0 +1,188 @@
/**************************************************************************
Copyright (c) 2001-2007, 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;
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;
};
#ifdef NO_82542_SUPPORT
#define E1000_REGISTER(hw, reg) reg
#else
#define E1000_REGISTER(hw, reg) (((hw)->mac.type >= e1000_82543) \
? reg : e1000_translate_register_82542(reg))
#endif
#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_ */

2022
sys/dev/em/e1000_phy.c Normal file

File diff suppressed because it is too large Load Diff

168
sys/dev/em/e1000_phy.h Normal file
View File

@ -0,0 +1,168 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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;
#include "e1000_api.h"
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_phy_force_speed_duplex(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, boolean_t 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, boolean_t *success);
s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
/* 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 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
#define IGP01E1000_GMII_FLEX_SPD 0x0010 /* Enable flexible speed
* on link-up */
#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

455
sys/dev/em/e1000_regs.h Normal file
View File

@ -0,0 +1,455 @@
/*******************************************************************************
Copyright (c) 2001-2007, 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_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - 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_EITR0 0x01680 /* Ext. Int. Throttling Rate Vector 0 - RW */
#define E1000_EITR1 0x01684 /* Ext. Int. Throttling Rate Vector 1 - RW */
#define E1000_EITR2 0x01688 /* Ext. Int. Throttling Rate Vector 2 - RW */
#define E1000_EITR3 0x0168C /* Ext. Int. Throttling Rate Vector 3 - RW */
#define E1000_EITR4 0x01690 /* Ext. Int. Throttling Rate Vector 4 - RW */
#define E1000_EITR5 0x01694 /* Ext. Int. Throttling Rate Vector 5 - RW */
#define E1000_EITR6 0x01698 /* Ext. Int. Throttling Rate Vector 6 - RW */
#define E1000_EITR7 0x0169C /* Ext. Int. Throttling Rate Vector 7 - RW */
#define E1000_EITR8 0x016A0 /* Ext. Int. Throttling Rate Vector 8 - RW */
#define E1000_EITR9 0x016A4 /* Ext. Int. Throttling Rate Vector 9 - RW */
#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_RDFPCQ0 0x02430
#define E1000_RDFPCQ1 0x02434
#define E1000_RDFPCQ2 0x02438
#define E1000_RDFPCQ3 0x0243C
#define E1000_PBRTH 0x02458 /* PB RX Arbitration Threshold - RW */
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
#define E1000_SRRCTL0 0x0280C
#define E1000_SRRCTL(_n) (0x280C + (_n << 8)) /* 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_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */
#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */
#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */
#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */
#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */
#define E1000_RXDCTL 0x02828 /* RX Descriptor Control queue 0 - RW */
#define E1000_RXDCTL1 0x02928 /* RX Descriptor Control queue 1 - 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_REG(_n) (E1000_RDBAL + (_n << 8))
#define E1000_RDBAH_REG(_n) (E1000_RDBAH + (_n << 8))
#define E1000_RDLEN_REG(_n) (E1000_RDLEN + (_n << 8))
#define E1000_RDH_REG(_n) (E1000_RDH + (_n << 8))
#define E1000_RDT_REG(_n) (E1000_RDT + (_n << 8))
#define E1000_RXDCTL_REG(_n) (E1000_RXDCTL + (_n << 8))
#define E1000_TDBAL_REG(_n) (E1000_TDBAL + (_n << 8))
#define E1000_TDBAH_REG(_n) (E1000_TDBAH + (_n << 8))
#define E1000_TDLEN_REG(_n) (E1000_TDLEN + (_n << 8))
#define E1000_TDH_REG(_n) (E1000_TDH + (_n << 8))
#define E1000_TDT_REG(_n) (E1000_TDT + (_n << 8))
#define E1000_TXDCTL_REG(_n) (E1000_TXDCTL + (_n << 8))
#define E1000_TARC_REG(_n) (E1000_TARC0 + (_n << 8))
#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
#define E1000_DCA_RXCTRL0 0x02814 /* RX Queue 0 DCA CTRL - RW */
#define E1000_DCA_RXCTRL1 0x02914 /* RX Queue 1 DCA CTRL - RW */
#define E1000_RDBAL2 0x02A00 /* RX Descriptor Base Low Queue 2 - RW */
#define E1000_RDBAH2 0x02A04 /* RX Descriptor Base High Queue 2 - RW */
#define E1000_RDLEN2 0x02A08 /* RX Descriptor Length Queue 2 - RW */
#define E1000_RDH2 0x02A10 /* RX Descriptor Head Queue 2 - RW */
#define E1000_DCA_RXCTRL2 0x02A14 /* RX Queue 2 DCA CTRL - RW */
#define E1000_RDT2 0x02A18 /* RX Descriptor Tail Queue 2 - RW */
#define E1000_RXDCTL2 0x02A28 /* RX Descriptor Control queue 2 - RW */
#define E1000_RDBAL3 0x02B00 /* RX Descriptor Base Low Queue 3 - RW */
#define E1000_RDBAH3 0x02B04 /* RX Descriptor Base High Queue 3 - RW */
#define E1000_RDLEN3 0x02B08 /* RX Descriptor Length Queue 3 - RW */
#define E1000_RDH3 0x02B10 /* RX Descriptor Head Queue 3 - RW */
#define E1000_DCA_RXCTRL3 0x02B14 /* RX Queue 3 DCA Control - RW */
#define E1000_RDT3 0x02B18 /* RX Descriptor Tail Queue 3 - RW */
#define E1000_RXDCTL3 0x02B28 /* RX Descriptor Control Queue 3 - RW */
#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
#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_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
#define E1000_TDT 0x03818 /* TX Descriptor Tail - RW */
#define E1000_TDBAL0 E1000_TDBAL /* TX Descriptor Base Address Low - RW */
#define E1000_TDBAH0 E1000_TDBAH /* TX Descriptor Base Address High - RW */
#define E1000_TDLEN0 E1000_TDLEN /* TX Descriptor Length - RW */
#define E1000_TDH0 E1000_TDH /* TX Descriptor Head - RW */
#define E1000_TDT0 E1000_TDT /* TX Descriptor Tail - RW */
#define E1000_TIDV 0x03820 /* TX Interrupt Delay Value - RW */
#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */
#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */
#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */
#define E1000_DCA_TXCTRL0 0x03814 /* TX Queue 0 DCA CTRL - RW */
#define E1000_TDWBAL0 0x03838 /* TX Desc. WB Addr Low Queue 0 - RW */
#define E1000_TDWBAH0 0x0383C /* TX Desc. WB Addr High Queue 0 - RW */
#define E1000_DCA_TXCTRL(_n) (E1000_DCA_TXCTRL0 + (_n << 8))
#define E1000_TDWBAL_REG(_n) (E1000_TDWBAL0 + (_n << 8))
#define E1000_TDWBAH_REG(_n) (E1000_TDWBAH0 + (_n << 8))
#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */
#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */
#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */
#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */
#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */
#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */
#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */
#define E1000_DCA_TXCTRL1 0x03914 /* TX Queue 0 DCA CTRL - RW */
#define E1000_TDWBAL1 0x03938 /* TX Descriptor WB Addr Low Queue 1 - RW */
#define E1000_TDWBAH1 0x0393C /* TX Descriptor WB Addr High Queue 1 - RW */
#define E1000_TDBAL2 0x03A00 /* TX Descriptor Base Low Queue 2 - RW */
#define E1000_TDBAH2 0x03A04 /* TX Descriptor Base High Queue 2 - RW */
#define E1000_TDLEN2 0x03A08 /* TX Descriptor Length Queue 2 - RW */
#define E1000_TDH2 0x03A10 /* TX Descriptor Head Queue 2 - RW */
#define E1000_DCA_TXCTRL2 0x03A14 /* TX Queue 2 DCA Control - RW */
#define E1000_TDT2 0x03A18 /* TX Descriptor Tail Queue 2 - RW */
#define E1000_TXDCTL2 0x03A28 /* TX Descriptor Control 2 - RW */
#define E1000_TDWBAL2 0x03A38 /* TX Descriptor WB Addr Low Queue 2 - RW */
#define E1000_TDWBAH2 0x03A3C /* TX Descriptor WB Addr High Queue 2 - RW */
#define E1000_TDBAL3 0x03B00 /* TX Descriptor Base Low Queue 3 - RW */
#define E1000_TDBAH3 0x03B04 /* TX Descriptor Base High Queue 3 - RW */
#define E1000_TDLEN3 0x03B08 /* TX Descriptor Length Queue 3 - RW */
#define E1000_TDH3 0x03B10 /* TX Descriptor Head Queue 3 - RW */
#define E1000_DCA_TXCTRL3 0x03B14 /* TX Queue 3 DCA Control - RW */
#define E1000_TDT3 0x03B18 /* TX Descriptor Tail Queue 3 - RW */
#define E1000_TXDCTL3 0x03B28 /* TX Descriptor Control 3 - RW */
#define E1000_TDWBAL3 0x03B38 /* TX Descriptor WB Addr Low Queue 3 - RW */
#define E1000_TDWBAH3 0x03B3C /* TX Descriptor WB Addr High Queue 3 - 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_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 */
#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_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 Inteface Control */
/* RSS registers */
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_IMIR0 0x05A80 /* Immediate Interrupt RX 0 - RW */
#define E1000_IMIR1 0x05A84 /* Immediate Interrupt RX 1 - RW */
#define E1000_IMIR2 0x05A88 /* Immediate Interrupt RX 2 - RW */
#define E1000_IMIR3 0x05A8C /* Immediate Interrupt RX 3 - RW */
#define E1000_IMIR4 0x05A90 /* Immediate Interrupt RX 4 - RW */
#define E1000_IMIR5 0x05A94 /* Immediate Interrupt RX 5 - RW */
#define E1000_IMIR6 0x05A98 /* Immediate Interrupt RX 6 - RW */
#define E1000_IMIR7 0x05A9C /* Immediate Interrupt RX 7 - RW */
#define E1000_IMIREX0 0x05AA0 /* Immediate Interrupt RX Extended 0 - RW */
#define E1000_IMIREX1 0x05AA4 /* Immediate Interrupt RX Extended 1 - RW */
#define E1000_IMIREX2 0x05AA8 /* Immediate Interrupt RX Extended 2 - RW */
#define E1000_IMIREX3 0x05AAC /* Immediate Interrupt RX Extended 3 - RW */
#define E1000_IMIREX4 0x05AB0 /* Immediate Interrupt RX Extended 4 - RW */
#define E1000_IMIREX5 0x05AB4 /* Immediate Interrupt RX Extended 5 - RW */
#define E1000_IMIREX6 0x05AB8 /* Immediate Interrupt RX Extended 6 - RW */
#define E1000_IMIREX7 0x05ABC /* Immediate Interrupt RX Extended 7 - RW */
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */
#define E1000_MSIXBM0 0x01600 /* MSI-X Allocation Register 0 - RW */
#define E1000_MSIXBM1 0x01604 /* MSI-X Allocation Register 1 - RW */
#define E1000_MSIXBM2 0x01608 /* MSI-X Allocation Register 2 - RW */
#define E1000_MSIXBM3 0x0160C /* MSI-X Allocation Register 3 - RW */
#define E1000_MSIXBM4 0x01610 /* MSI-X Allocation Register 4 - RW */
#define E1000_MSIXBM5 0x01614 /* MSI-X Allocation Register 5 - RW */
#define E1000_MSIXBM6 0x01618 /* MSI-X Allocation Register 6 - RW */
#define E1000_MSIXBM7 0x0161C /* MSI-X Allocation Register 7 - RW */
#define E1000_MSIXBM8 0x01620 /* MSI-X Allocation Register 8 - RW */
#define E1000_MSIXBM9 0x01624 /* MSI-X Allocation Register 9 - RW */
#define E1000_MSIXTADD0 0x0C000 /* MSI-X Table entry addr low reg 0 - RW */
#define E1000_MSIXTADD1 0x0C010 /* MSI-X Table entry addr low reg 1 - RW */
#define E1000_MSIXTADD2 0x0C020 /* MSI-X Table entry addr low reg 2 - RW */
#define E1000_MSIXTADD3 0x0C030 /* MSI-X Table entry addr low reg 3 - RW */
#define E1000_MSIXTADD4 0x0C040 /* MSI-X Table entry addr low reg 4 - RW */
#define E1000_MSIXTADD5 0x0C050 /* MSI-X Table entry addr low reg 5 - RW */
#define E1000_MSIXTADD6 0x0C060 /* MSI-X Table entry addr low reg 6 - RW */
#define E1000_MSIXTADD7 0x0C070 /* MSI-X Table entry addr low reg 7 - RW */
#define E1000_MSIXTADD8 0x0C080 /* MSI-X Table entry addr low reg 8 - RW */
#define E1000_MSIXTADD9 0x0C090 /* MSI-X Table entry addr low reg 9 - RW */
#define E1000_MSIXTUADD0 0x0C004 /* MSI-X Table entry addr upper reg 0 - RW */
#define E1000_MSIXTUADD1 0x0C014 /* MSI-X Table entry addr upper reg 1 - RW */
#define E1000_MSIXTUADD2 0x0C024 /* MSI-X Table entry addr upper reg 2 - RW */
#define E1000_MSIXTUADD3 0x0C034 /* MSI-X Table entry addr upper reg 3 - RW */
#define E1000_MSIXTUADD4 0x0C044 /* MSI-X Table entry addr upper reg 4 - RW */
#define E1000_MSIXTUADD5 0x0C054 /* MSI-X Table entry addr upper reg 5 - RW */
#define E1000_MSIXTUADD6 0x0C064 /* MSI-X Table entry addr upper reg 6 - RW */
#define E1000_MSIXTUADD7 0x0C074 /* MSI-X Table entry addr upper reg 7 - RW */
#define E1000_MSIXTUADD8 0x0C084 /* MSI-X Table entry addr upper reg 8 - RW */
#define E1000_MSIXTUADD9 0x0C094 /* MSI-X Table entry addr upper reg 9 - RW */
#define E1000_MSIXTMSG0 0x0C008 /* MSI-X Table entry message reg 0 - RW */
#define E1000_MSIXTMSG1 0x0C018 /* MSI-X Table entry message reg 1 - RW */
#define E1000_MSIXTMSG2 0x0C028 /* MSI-X Table entry message reg 2 - RW */
#define E1000_MSIXTMSG3 0x0C038 /* MSI-X Table entry message reg 3 - RW */
#define E1000_MSIXTMSG4 0x0C048 /* MSI-X Table entry message reg 4 - RW */
#define E1000_MSIXTMSG5 0x0C058 /* MSI-X Table entry message reg 5 - RW */
#define E1000_MSIXTMSG6 0x0C068 /* MSI-X Table entry message reg 6 - RW */
#define E1000_MSIXTMSG7 0x0C078 /* MSI-X Table entry message reg 7 - RW */
#define E1000_MSIXTMSG8 0x0C088 /* MSI-X Table entry message reg 8 - RW */
#define E1000_MSIXTMSG9 0x0C098 /* MSI-X Table entry message reg 9 - RW */
#define E1000_MSIXVCTRL0 0x0C00C /* MSI-X Table entry vector ctrl reg 0 - RW */
#define E1000_MSIXVCTRL1 0x0C01C /* MSI-X Table entry vector ctrl reg 1 - RW */
#define E1000_MSIXVCTRL2 0x0C02C /* MSI-X Table entry vector ctrl reg 2 - RW */
#define E1000_MSIXVCTRL3 0x0C03C /* MSI-X Table entry vector ctrl reg 3 - RW */
#define E1000_MSIXVCTRL4 0x0C04C /* MSI-X Table entry vector ctrl reg 4 - RW */
#define E1000_MSIXVCTRL5 0x0C05C /* MSI-X Table entry vector ctrl reg 5 - RW */
#define E1000_MSIXVCTRL6 0x0C06C /* MSI-X Table entry vector ctrl reg 6 - RW */
#define E1000_MSIXVCTRL7 0x0C07C /* MSI-X Table entry vector ctrl reg 7 - RW */
#define E1000_MSIXVCTRL8 0x0C08C /* MSI-X Table entry vector ctrl reg 8 - RW */
#define E1000_MSIXVCTRL9 0x0C09C /* MSI-X Table entry vector ctrl reg 9 - RW */
#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */
#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/**************************************************************************
Copyright (c) 2001-2006, Intel Corporation
Copyright (c) 2001-2007, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -30,8 +30,7 @@ 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_
@ -48,7 +47,7 @@ POSSIBILITY OF SUCH DAMAGE.
* 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 em_tx_desc)) % 128 == 0
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
#define EM_MIN_TXD 80
#define EM_MAX_TXD_82543 256
@ -66,12 +65,12 @@ POSSIBILITY OF SUCH DAMAGE.
* 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 em_tx_desc)) % 128 == 0
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
#define EM_MIN_RXD 80
#define EM_MAX_RXD_82543 256
#define EM_MAX_RXD 4096
#define EM_DEFAULT_RXD EM_MAX_RXD_82543
#define EM_DEFAULT_RXD EM_MAX_RXD_82543
/*
* EM_TIDV - Transmit Interrupt Delay Value
@ -141,7 +140,7 @@ POSSIBILITY OF SUCH DAMAGE.
/*
* Inform the stack about transmit segmentation offload capabilities.
*/
#define EM_TCPSEG_FEATURES CSUM_TSO
#define EM_TCPSEG_FEATURES CSUM_TSO
/*
* This parameter controls the duration of transmit watchdog timer.
@ -152,7 +151,8 @@ POSSIBILITY OF SUCH DAMAGE.
* This parameter controls when the driver calls the routine to reclaim
* transmit descriptors.
*/
#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
/*
* This parameter controls whether or not autonegotation is enabled.
@ -169,41 +169,36 @@ POSSIBILITY OF SUCH DAMAGE.
*/
#define WAIT_FOR_AUTO_NEG_DEFAULT 0
/*
* EM_MASTER_SLAVE is only defined to enable a workaround for a known compatibility issue
* with 82541/82547 devices and some switches. See the "Known Limitations" section of
* the README file for a complete description and a list of affected switches.
*
* 0 = Hardware default
* 1 = Master mode
* 2 = Slave mode
* 3 = Auto master/slave
*/
/* #define EM_MASTER_SLAVE 2 */
/*
* Limitation of some PCIe chipsets when using TSO
*/
#define EM_TSO_PCIE_SEGMENT_SIZE 4096
/* Tunables -- End */
#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
ADVERTISE_1000_FULL)
#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 EM_MASTER_SLAVE e1000_ms_hw_default
/*
* Micellaneous constants
*/
#define EM_VENDOR_ID 0x8086
#define EM_FLASH 0x0014 /* Flash memory on ICH8 */
#define EM_FLASH 0x0014
#define EM_JUMBO_PBA 0x00000028
#define EM_DEFAULT_PBA 0x00000030
#define EM_SMARTSPEED_DOWNSHIFT 3
#define EM_SMARTSPEED_MAX 15
#define EM_MAX_INTR 10
#define EM_TSO_SEG_SIZE 4096 /* Max dma seg size */
#define MAX_NUM_MULTICAST_ADDRESSES 128
#define PCI_ANY_ID (~0U)
#define ETHER_ALIGN 2
#define EM_TX_BUFFER_SIZE ((uint32_t) 1514)
#define EM_FC_PAUSE_TIME 0x0680
#define EM_EEPROM_APME 0x400;
/*
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
@ -215,14 +210,15 @@ POSSIBILITY OF SUCH DAMAGE.
#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */
/* PCI Config defines */
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
#define EM_BAR_TYPE_MASK 0x00000001
#define EM_BAR_TYPE_MMEM 0x00000000
#define EM_BAR_TYPE_IO 0x00000001
#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
#define EM_BAR_MEM_TYPE_MASK 0x00000006
#define EM_BAR_MEM_TYPE_32BIT 0x00000000
#define EM_BAR_MEM_TYPE_64BIT 0x00000004
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
#define EM_BAR_TYPE_MASK 0x00000001
#define EM_BAR_TYPE_MMEM 0x00000000
#define EM_BAR_TYPE_IO 0x00000001
#define EM_BAR_TYPE_FLASH 0x0014
#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
#define EM_BAR_MEM_TYPE_MASK 0x00000006
#define EM_BAR_MEM_TYPE_32BIT 0x00000000
#define EM_BAR_MEM_TYPE_64BIT 0x00000004
/* Defines for printing debug information */
#define DEBUG_INIT 0
@ -239,50 +235,40 @@ POSSIBILITY OF SUCH DAMAGE.
#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)
/* Supported RX Buffer Sizes */
#define EM_RXBUFFER_2048 2048
#define EM_RXBUFFER_4096 4096
#define EM_RXBUFFER_8192 8192
#define EM_RXBUFFER_16384 16384
#define EM_MAX_SCATTER 64
#define EM_TSO_SIZE 65535
typedef enum _XSUM_CONTEXT_T {
OFFLOAD_NONE,
OFFLOAD_TCP_IP,
OFFLOAD_UDP_IP
} XSUM_CONTEXT_T;
#define EM_MAX_SCATTER 64
#define EM_TSO_SIZE 65535 /* maxsize of a dma transfer */
#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */
#define ETH_ZLEN 60
#define ETH_ADDR_LEN 6
struct adapter;
struct em_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 */
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
* em_dma_malloc() and em_dma_free().
* e1000_dma_malloc and e1000_dma_free.
*/
struct em_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;
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;
};
/* Driver softc. */
/* Our adapter structure */
struct adapter {
struct ifnet *ifp;
struct em_hw hw;
struct e1000_hw hw;
/* FreeBSD operating-system-specific structures. */
struct em_osdep osdep;
struct e1000_osdep osdep;
struct device *dev;
struct resource *res_memory;
struct resource *flash_mem;
@ -298,9 +284,12 @@ struct adapter {
int if_flags;
struct mtx mtx;
int em_insert_vlan_header;
struct task link_task;
struct task rxtx_task;
struct taskqueue *tq; /* private task queue */
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 */
uint32_t part_num;
@ -313,8 +302,6 @@ struct adapter {
struct em_int_delay_info rx_int_delay;
struct em_int_delay_info rx_abs_int_delay;
XSUM_CONTEXT_T active_checksum_context;
/*
* Transmit definitions
*
@ -325,7 +312,7 @@ struct adapter {
* The number of remaining tx_desc is num_tx_desc_avail.
*/
struct em_dma_alloc txdma; /* bus_dma glue for tx desc */
struct em_tx_desc *tx_desc_base;
struct e1000_tx_desc *tx_desc_base;
uint32_t next_avail_tx_desc;
uint32_t next_tx_to_clean;
volatile uint16_t num_tx_desc_avail;
@ -333,7 +320,13 @@ struct adapter {
uint32_t txd_cmd;
struct em_buffer *tx_buffer_area;
bus_dma_tag_t txtag; /* dma tag for tx */
uint32_t tx_tso; /* last tx was tso */
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
@ -344,7 +337,7 @@ struct adapter {
* The next pair to check on receive is at offset next_rx_desc_to_check
*/
struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */
struct em_rx_desc *rx_desc_base;
struct e1000_rx_desc *rx_desc_base;
uint32_t next_rx_desc_to_check;
uint32_t rx_buffer_len;
uint16_t num_rx_desc;
@ -353,11 +346,15 @@ struct adapter {
bus_dma_tag_t rxtag;
bus_dmamap_t rx_sparemap;
/* First/last mbuf pointers, for collecting multisegment RX packets. */
/*
* First/last mbuf pointers, for
* collecting multisegment RX packets.
*/
struct mbuf *fmp;
struct mbuf *lmp;
/* Misc stats maintained by the driver */
unsigned long dropped_pkts;
unsigned long mbuf_alloc_failed;
unsigned long mbuf_cluster_failed;
unsigned long no_tx_desc_avail1;
@ -386,7 +383,7 @@ struct adapter {
boolean_t pcix_82544;
boolean_t in_detach;
struct em_hw_stats stats;
struct e1000_hw_stats stats;
};
/* ******************************************************************************
@ -406,7 +403,7 @@ typedef struct _em_vendor_info_t {
struct em_buffer {
int next_eop; /* Index of the desc to watch */
int next_eop; /* Index of the desc to watch */
struct mbuf *m_head;
bus_dmamap_t map; /* bus_dma map for packet */
};
@ -414,14 +411,14 @@ struct em_buffer {
/* For 82544 PCIX Workaround */
typedef struct _ADDRESS_LENGTH_PAIR
{
uint64_t address;
uint32_t length;
uint64_t address;
uint32_t length;
} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
typedef struct _DESCRIPTOR_PAIR
{
ADDRESS_LENGTH_PAIR descriptor[4];
uint32_t elements;
ADDRESS_LENGTH_PAIR descriptor[4];
uint32_t elements;
} DESC_ARRAY, *PDESC_ARRAY;
#define EM_LOCK_INIT(_sc, _name) \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,177 +0,0 @@
/**************************************************************************
Copyright (c) 2001-2006, 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/systm.h>
#include <sys/bus.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/socket.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.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);
#ifdef DBG
#define DEBUGOUT(S) printf(S "\n")
#define DEBUGOUT1(S,A) printf(S "\n",A)
#define DEBUGOUT2(S,A,B) printf(S "\n",A,B)
#define DEBUGOUT3(S,A,B,C) printf(S "\n",A,B,C)
#define DEBUGOUT7(S,A,B,C,D,E,F,G) printf(S "\n",A,B,C,D,E,F,G)
#else
#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)
#endif
#define FALSE 0
#define TRUE 1
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
struct em_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;
device_t dev;
};
#define E1000_WRITE_FLUSH(hw) E1000_READ_REG(hw, STATUS)
/* Read from an absolute offset in the adapter's memory space */
#define E1000_READ_OFFSET(hw, offset) \
bus_space_read_4( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_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 em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, offset, value)
/* Convert a register name to its offset in the adapter's memory space */
#define E1000_REG_OFFSET(hw, reg) \
((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg)
/*
* Register READ/WRITE macros.
*
* XXXGL: Due to define's namespace mangling in recent version of
* if_em_hw.*, we prepend "_" to the register name in all macros,
* to prevent reg from being substituted, and then, in E1000_REG_OFFSET()
* we prepend either "E1000" or "E1000_82542".
*
* P.S. The problematic defines are E1000_PHY_CTRL and PHY_CTRL.
*
* P.P.S. Intel has removed E1000_REG_OFFSET() and copy-pasted it to all
* macros.
*/
#define _E1000_REG_OFFSET(hw, reg) \
((hw)->mac_type >= em_82543 ? E1000##reg : E1000_82542##reg)
#define E1000_READ_REG(hw, reg) \
E1000_READ_OFFSET(hw, _E1000_REG_OFFSET(hw, _##reg))
#define E1000_WRITE_REG(hw, reg, value) \
E1000_WRITE_OFFSET(hw, _E1000_REG_OFFSET(hw, _##reg), value)
#define E1000_READ_REG_ARRAY(hw, reg, index) \
E1000_READ_OFFSET(hw, _E1000_REG_OFFSET(hw, _##reg) + ((index) << 2))
#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
#define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \
E1000_WRITE_OFFSET(hw, _E1000_REG_OFFSET(hw, _##reg) + ((index) << 2), value)
#define E1000_WRITE_REG_ARRAY_BYTE(hw, reg, index, value) \
bus_space_write_1( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
_E1000_REG_OFFSET(hw, _##reg) + (index), \
value)
#define E1000_WRITE_REG_ARRAY_WORD(hw, reg, index, value) \
bus_space_write_2( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
_E1000_REG_OFFSET(hw, _##reg) + (index), \
value)
#define E1000_WRITE_REG_ARRAY_DWORD(hw, reg, index, value) \
E1000_WRITE_OFFSET(hw, _E1000_REG_OFFSET(hw, _##reg) + ((index) << 2), value)
#define E1000_READ_ICH_FLASH_REG(hw, reg) \
bus_space_read_4(((struct em_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct em_osdep *)(hw)->back)->flash_bus_space_handle, reg)
#define E1000_READ_ICH_FLASH_REG16(hw, reg) \
bus_space_read_2(((struct em_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct em_osdep *)(hw)->back)->flash_bus_space_handle, reg)
#define E1000_WRITE_ICH_FLASH_REG(hw, reg, value) \
bus_space_write_4(((struct em_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct em_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
#define E1000_WRITE_ICH_FLASH_REG16(hw, reg, value) \
bus_space_write_2(((struct em_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct em_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
#define em_io_read(hw, port) \
bus_space_read_4(((struct em_osdep *)(hw)->back)->io_bus_space_tag, \
((struct em_osdep *)(hw)->back)->io_bus_space_handle, (port))
#define em_io_write(hw, port, value) \
bus_space_write_4(((struct em_osdep *)(hw)->back)->io_bus_space_tag, \
((struct em_osdep *)(hw)->back)->io_bus_space_handle, (port), \
(value))
#endif /* _FREEBSD_OS_H_ */

View File

@ -1,9 +1,23 @@
#$FreeBSD$
$FreeBSD$
.PATH: ${.CURDIR}/../../dev/em
KMOD = if_em
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
.PATH: ${.CURDIR}/../../dev/em
# NOTE: this absolute path is somewhat of a hack, but necessary for
# the new shared code
CFLAGS += -I/usr/src/sys/dev/em
KMOD= if_em
SRCS= if_em.c if_em_hw.c
SRCS+= device_if.h bus_if.h pci_if.h
# DEVICE_POLLING gives you Legacy interrupt handling
#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}
.include <bsd.kmod.mk>