summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/beatnik
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 09:53:31 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:44 +0200
commit031df3914990db0336a0d386fb53558b05de467e (patch)
tree4661e22f0cdb3f9d06879f0194b77c75f62bac79 /c/src/lib/libbsp/powerpc/beatnik
parentbsps: Move interrupt controller support to bsps (diff)
downloadrtems-031df3914990db0336a0d386fb53558b05de467e.tar.bz2
bsps: Move legacy network drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/beatnik')
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/Makefile.am16
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_em/LICENSE31
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_em/README332
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em.c3847
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em.h493
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_hw.c6636
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_hw.h2678
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_osdep.h146
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_rtems.c106
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_em/rtemscompat_defs.h198
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/gtethreg.h854
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/gtvar.h170
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfe.c2642
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfe_rtems.c129
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfevar.h225
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/rtemscompat_defs.h161
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mv643xx_eth.c3318
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mve_smallbuf_tst.c145
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_mve/testing.c324
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/porting/LICENSE51
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/porting/Makefile.template84
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/porting/README104
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/porting/if_xxx.modini.c34
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/porting/if_xxx_rtems.c500
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/porting/pcireg.h405
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat.h456
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat1.h219
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat_defs.h.template97
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/support/bsp_attach.c468
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/support/early_link_status.c40
30 files changed, 8 insertions, 24901 deletions
diff --git a/c/src/lib/libbsp/powerpc/beatnik/Makefile.am b/c/src/lib/libbsp/powerpc/beatnik/Makefile.am
index e5c57f8dc3..4de5536771 100644
--- a/c/src/lib/libbsp/powerpc/beatnik/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/beatnik/Makefile.am
@@ -84,14 +84,14 @@ librtemsbsp_a_SOURCES += ../shared/pci/pcifinddevice.c
#network
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += network/if_em/if_em.c
-librtemsbsp_a_SOURCES += network/if_em/if_em_hw.c
-librtemsbsp_a_SOURCES += network/if_em/if_em_rtems.c
-librtemsbsp_a_SOURCES += network/if_gfe/if_gfe.c
-librtemsbsp_a_SOURCES += network/if_gfe/if_gfe_rtems.c
-librtemsbsp_a_SOURCES += network/if_mve/mv643xx_eth.c
-librtemsbsp_a_SOURCES += network/support/bsp_attach.c
-librtemsbsp_a_SOURCES += network/support/early_link_status.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/net/if_em/if_em.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/net/if_em/if_em_hw.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/net/if_em/if_em_rtems.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/net/if_gfe/if_gfe.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/net/if_gfe/if_gfe_rtems.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/net/if_mve/mv643xx_eth.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/net/support/bsp_attach.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/net/support/early_link_status.c
endif
# tod
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/LICENSE b/c/src/lib/libbsp/powerpc/beatnik/network/if_em/LICENSE
deleted file mode 100644
index ba90c4a817..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/LICENSE
+++ /dev/null
@@ -1,31 +0,0 @@
-$FreeBSD: /repoman/r/ncvs/src/sys/dev/em/LICENSE,v 1.3 2005/01/06 01:42:38 imp Exp $
-/*-
-Copyright (c) 2001-2003, 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.
-*/
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/README b/c/src/lib/libbsp/powerpc/beatnik/network/if_em/README
deleted file mode 100644
index b4eef8dbb7..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/README
+++ /dev/null
@@ -1,332 +0,0 @@
-$FreeBSD: /repoman/r/ncvs/src/sys/dev/em/README,v 1.10 2005/07/11 02:33:25 delphij Exp $
-FreeBSD* Driver for the Intel(R) PRO/1000 Family of Adapters
-============================================================
-
-March 18, 2005
-
-
-Contents
-========
-
-- Overview
-- Identifying Your Adapter
-- Building and Installation
-- Speed and Duplex Configuration
-- Additional Configurations
-- Known Limitations
-- Support
-- License
-
-
-Overview
-========
-
-This file describes the FreeBSD* driver, version 2.1.x, for the Intel(R)
-PRO/1000 Family of Adapters. This driver has been developed for use with
-FreeBSD, version 5.x.
-
-For questions related to hardware requirements, refer to the documentation
-supplied with your Intel PRO/1000 adapter. All hardware requirements listed
-apply to use with FreeBSD.
-
-
-Identifying Your Adapter
-========================
-
-For information on how to identify your adapter, go to the Adapter &
-Driver ID Guide at:
-
-http://support.intel.com/support/network/adapter/pro100/21397.htm
-
-
-For the latest Intel network drivers for FreeBSD, see:
-
-http://appsr.intel.com/scripts-df/support_intel.asp
-
-
-NOTE: Mobile adapters are not fully supported.
-
-
-Building and Installation
-=========================
-
-NOTE: The driver can be installed as a dynamic loadable kernel module or
- compiled into the kernel. You must have kernel sources installed in
- order to compile the driver module.
-
-In the instructions below, x.x.x is the driver version as indicated in the
-name of the driver tar file.
-
-1. Move the base driver tar file to the directory of your choice. For
- example, use /home/username/em or /usr/local/src/em.
-
-2. Untar/unzip the archive:
-
- tar xvfz em-x.x.x.tar.gz
-
- This will create an em-x.x.x directory.
-
-3. To create a loadable module, perform the following steps.
- NOTE: To compile the driver into the kernel, go directly to step 4.
-
- a. To compile the module
-
- cd em-x.x.x
- make
-
- b. To install the compiled module in system directory:
-
- make install
-
- c. If you want the driver to load automatically when the system is booted:
-
- 1. Edit /boot/loader.conf, and add the following line:
-
- if_em_load="YES"
-
-4. To compile the driver into the kernel:
-
- cd em-x.x.x/src
-
- cp if_em* /usr/src/sys/dev/em
-
- cp Makefile.kernel /usr/src/sys/modules/em/Makefile
-
- Edit the /usr/src/sys/conf/files.i386 file, and add the following lines only if
- they don't already exist:
-
- dev/em/if_em.c optional em
-
- dev/em/if_em_hw.c optional em
-
- Remove the following lines from the /usr/src/sys/conf/files.i386 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:
-
- 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.
-
-5. To assign an IP address to the interface, enter the following:
-
- ifconfig em<interface_num> <IP_address>
-
-6. Verify that the interface works. Enter the following, where <IP_address>
- is the IP address for another machine on the same subnet as the interface
- that is being tested:
-
- ping <IP_address>
-
-7. To configure the IP address to remain after reboot, edit /etc/rc.conf,
- and create the appropriate ifconfig_em<interface_num>entry:
-
- ifconfig_em<interface_num>="<ifconfig_settings>"
-
- Example usage:
-
- ifconfig_em0="inet 192.168.10.1 netmask 255.255.255.0"
-
- NOTE: For assistance, see the ifconfig man page.
-
-
-Speed and Duplex Configuration
-==============================
-
-By default, the adapter auto-negotiates the speed and duplex of the
-connection. If there is a specific need, the ifconfig utility can be used to
-configure the speed and duplex settings on the adapter. Example usage:
-
- ifconfig em<interface_num> <IP_address> media 100baseTX mediaopt
- full-duplex
-
- NOTE: Only use mediaopt to set the driver to full-duplex. If mediaopt is
- not specified and you are not running at gigabit speed, the driver
- defaults to half-duplex.
-
-
-This driver supports the following media type options:
-
- autoselect - Enables auto-negotiation for speed and duplex.
-
- 10baseT/UTP - Sets speed to 10 Mbps. Use the ifconfig mediaopt
- option to select full-duplex mode.
-
- 100baseTX - Sets speed to 100 Mbps. Use the ifconfig mediaopt
- option to select full-duplex mode.
-
- 1000baseTX - Sets speed to 1000 Mbps. In this case, the driver
- supports only full-duplex mode.
-
- 1000baseSX - Sets speed to 1000 Mbps. In this case, the driver
- supports only full-duplex mode.
-
-For more information on the ifconfig utility, see the ifconfig man page.
-
-
-Additional Configurations
-=========================
-
-The driver supports Transmit/Receive Checksum Offload and Jumbo Frames on
-all but the 82542-based adapters. For specific adapters, refer to the
-Identifying Your Adapter section.
-
- Jumbo Frames
- ------------
- To enable Jumbo Frames, use the ifconfig utility to increase the MTU
- beyond 1500 bytes.
-
- NOTES: Only enable Jumbo Frames if your network infrastructure supports
- them.
-
- The Jumbo Frames setting on the switch must be set to at least
- 22 bytes larger than that of the MTU.
-
- The Intel PRO/1000 PM Network Connection does not support jumbo
- frames.
-
-
- The Jumbo Frames MTU range for Intel Adapters is 1500 to 16114. The default
- MTU range is 1500. To modify the setting, enter the following:
-
- ifconfig em<interface_num> <hostname or IP address> mtu 9000
-
- To confirm the MTU used between two specific devices, use:
-
- route get <destination_IP_address>
-
- VLANs
- -----
- To create a new VLAN interface:
-
- ifconfig <vlan_name> create
-
- To associate the VLAN interface with a physical interface and
- assign a VLAN ID, IP address, and netmask:
-
- ifconfig <vlan_name> <ip_address> netmask <subnet_mask> vlan
- <vlan_id> vlandev <physical_interface>
-
- Example:
-
- ifconfig vlan10 10.0.0.1 netmask 255.255.255.0 vlan10 vlandev em0
-
- 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:
-
- ifconfig <vlan_name> destroy
-
- Polling
- -------
- NOTES: DEVICE POLLING is only valid for non-SMP 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:
-
- options DEVICE_POLLING
- options HZ=1000
-
- At runtime use:
- sysctl kern.polling.enable=1 to turn polling on
- Use:
- sysctl kern.polling.enable=0 to turn polling off
-
- Checksum Offload
- ----------------
- Checksum offloading is not supported on 82542 Gigabit adapters.
-
- Checksum offloading supports both TCP and UDP packets and is
- supported for both transmit and receive.
-
- Checksum offloading can be enabled or disabled using ifconfig.
- Both transmit and receive offloading will be either enabled or
- disabled together. You cannot enable/disable one without the other.
-
- To enable checksum offloading:
-
- ifconfig <interface_num> rxcsum
-
- To disable checksum offloading:
-
- ifconfig <interface_num> -rxcsum
-
- To confirm the current setting:
-
- ifconfig <interface_num>
-
- Look for the presence or absence of the following line:
-
- options=3 <RXCSUM,TXCSUM>
-
- See the ifconfig man page for further information.
-
-Known Limitations
-=================
-
- There are known performance issues with this driver when running UDP traffic
- with Jumbo Frames.
-
- 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
- include:
- Planex FXG-08TE
- I-O Data ETG-SH8
-
- 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
- from within the comments. For example, change from:
-
- /* #define EM_MASTER_SLAVE 2 */
- to:
- #define EM_MASTER_SLAVE 2
-
- Use one of the following options:
- 1 = Master mode
- 2 = Slave mode
- 3 = Auto master/slave
- Setting 2 is recommended.
-
- Recompile the module:
- a. To compile the module
- cd em-x.x.x
- make clean
- make
-
- b. To install the compiled module in system directory:
- make install
-
-
-Support
-=======
-
-For general information and support, go to the Intel support website at:
-
- http://support.intel.com
-
-If an issue is identified, support is through email only at:
-freebsdnic@mailbox.intel.com
-
-License
-=======
-
-This software program is released under the terms of a license agreement
-between you ('Licensee') and Intel. Do not use or load this software or any
-associated materials (collectively, the 'Software') until you have carefully
-read the full terms and conditions of the LICENSE located in this software
-package. By loading or using the Software, you agree to the terms of this
-Agreement. If you do not agree with the terms of this Agreement, do not
-install or use the Software.
-
-* Other names and brands may be claimed as the property of others.
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em.c b/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em.c
deleted file mode 100644
index db3607a20d..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em.c
+++ /dev/null
@@ -1,3847 +0,0 @@
-/**************************************************************************
-
-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:
-
- 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: /repoman/r/ncvs/src/sys/dev/em/if_em.c,v 1.67 2005/08/03 00:18:29 rwatson Exp $*/
-#ifndef __rtems__
-#include <dev/em/if_em.h>
-#else
-#include <rtems.h>
-#include "rtemscompat_defs.h"
-#include "../porting/rtemscompat.h"
-#include "if_em.h"
-#include "../porting/rtemscompat1.h"
-#include <inttypes.h>
-#endif
-
-/*********************************************************************
- * Set this to one to display debug statistics
- *********************************************************************/
-int em_display_debug_stats = 0;
-
-/*********************************************************************
- * Linked list of board private structures for all NICs found
- *********************************************************************/
-
-struct adapter *em_adapter_list = NULL;
-
-
-/*********************************************************************
- * Driver version
- *********************************************************************/
-
-char em_driver_version[] = "2.1.7";
-
-
-/*********************************************************************
- * PCI Device ID Table
- *
- * Used by probe to select devices to load on
- * Last field stores an index into em_strings
- * Last entry must be all 0s
- *
- * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
- *********************************************************************/
-
-static em_vendor_info_t em_vendor_info_array[] =
-{
- /* Intel(R) PRO/1000 Network Connection */
- { 0x8086, E1000_DEV_ID_82540EM, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82540EM_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82540EP, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82540EP_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82540EP_LP, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82541EI, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541ER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541ER_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541GI, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541GI_LF, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82541GI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82542, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82543GC_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82543GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82544EI_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82544EI_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82544GC_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82544GC_LOM, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82545EM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82545EM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82545GM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82545GM_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82545GM_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82546EB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546EB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546EB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_PCIE, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82547EI, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82547EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82547GI, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- { 0x8086, E1000_DEV_ID_82573E, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, E1000_DEV_ID_82573E_IAMT, PCI_ANY_ID, PCI_ANY_ID, 0},
-
- /* required last entry */
- { 0, 0, 0, 0, 0}
-};
-
-/*********************************************************************
- * Table of branding strings for all supported NICs.
- *********************************************************************/
-
-static char *em_strings[] = {
- "Intel(R) PRO/1000 Network Connection"
-};
-
-/*********************************************************************
- * Function prototypes
- *********************************************************************/
-static int em_probe(device_t);
-static int em_attach(device_t);
-#if !defined(__rtems__) || defined(DEBUG_MODULAR)
-static int em_detach(device_t);
-#endif
-#ifndef __rtems__
-static int em_shutdown(device_t);
-#endif
-static void em_intr(void *);
-static void em_start(struct ifnet *);
-#ifndef __rtems__
-static int em_ioctl(struct ifnet *, u_long, caddr_t);
-#else
-static int em_ioctl(struct ifnet *, ioctl_command_t, caddr_t);
-#endif
-static void em_watchdog(struct ifnet *);
-static void em_init(void *);
-static void em_init_locked(struct adapter *);
-static void em_stop(void *);
-static void em_media_status(struct ifnet *, struct ifmediareq *);
-#ifndef __rtems__
-static int em_media_change(struct ifnet *);
-#else
-static int em_media_change(struct ifnet *ifp, struct rtems_ifmedia *ifm);
-#endif
-static void em_identify_hardware(struct adapter *);
-static int em_allocate_pci_resources(struct adapter *);
-#ifndef __rtems__
-static void em_free_pci_resources(struct adapter *);
-static void em_local_timer(void *);
-#endif
-static int em_hardware_init(struct adapter *);
-static void em_setup_interface(device_t, struct adapter *);
-static int em_setup_transmit_structures(struct adapter *);
-static void em_initialize_transmit_unit(struct adapter *);
-static int em_setup_receive_structures(struct adapter *);
-static void em_initialize_receive_unit(struct adapter *);
-static void em_enable_intr(struct adapter *);
-static void em_disable_intr(struct adapter *);
-static void em_free_transmit_structures(struct adapter *);
-static void em_free_receive_structures(struct adapter *);
-static void em_update_stats_counters(struct adapter *);
-static void em_clean_transmit_interrupts(struct adapter *);
-static int em_allocate_receive_structures(struct adapter *);
-static int em_allocate_transmit_structures(struct adapter *);
-static void em_process_receive_interrupts(struct adapter *, int);
-#ifndef __rtems__
-static void em_receive_checksum(struct adapter *,
- struct em_rx_desc *,
- struct mbuf *);
-static void em_transmit_checksum_setup(struct adapter *,
- struct mbuf *,
- u_int32_t *,
- u_int32_t *);
-#endif
-static void em_set_promisc(struct adapter *);
-static void em_disable_promisc(struct adapter *);
-static void em_set_multi(struct adapter *);
-static void em_print_hw_stats(struct adapter *);
-static void em_print_link_status(struct adapter *);
-static int em_get_buf(int i, struct adapter *,
- struct mbuf *);
-#ifndef __rtems__
-static void em_enable_vlans(struct adapter *);
-static void em_disable_vlans(struct adapter *);
-#endif
-static int em_encap(struct adapter *, struct mbuf **);
-#ifndef __rtems__
-static void em_smartspeed(struct adapter *);
-#endif
-static int em_82547_fifo_workaround(struct adapter *, int);
-static void em_82547_update_fifo_head(struct adapter *, int);
-static int em_82547_tx_fifo_reset(struct adapter *);
-#ifndef __rtems__
-static void em_82547_move_tail(void *arg);
-#endif
-static void em_82547_move_tail_locked(struct adapter *);
-static int em_dma_malloc(struct adapter *, bus_size_t,
- struct em_dma_alloc *, int);
-static void em_dma_free(struct adapter *, struct em_dma_alloc *);
-#ifndef __rtems__
-static void em_print_debug_info(struct adapter *);
-#endif
-static int em_is_valid_ether_addr(u_int8_t *);
-#ifndef __rtems__
-static int em_sysctl_stats(SYSCTL_HANDLER_ARGS);
-static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
-#endif
-static u_int32_t em_fill_descriptors (u_int64_t address,
- u_int32_t length,
- PDESC_ARRAY desc_array);
-#ifndef __rtems__
-static int em_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
-static void em_add_int_delay_sysctl(struct adapter *, const char *,
- const char *, struct em_int_delay_info *,
- int, int);
-#endif
-
-/*********************************************************************
- * FreeBSD Device Interface Entry Points
- *********************************************************************/
-
-#ifndef __rtems__
-static device_method_t em_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, em_probe),
- DEVMETHOD(device_attach, em_attach),
- DEVMETHOD(device_detach, em_detach),
- DEVMETHOD(device_shutdown, em_shutdown),
- {0, 0}
-};
-
-static driver_t em_driver = {
- "em", em_methods, sizeof(struct adapter ),
-};
-
-static devclass_t em_devclass;
-DRIVER_MODULE(em, pci, em_driver, em_devclass, 0, 0);
-MODULE_DEPEND(em, pci, 1, 1, 1);
-MODULE_DEPEND(em, ether, 1, 1, 1);
-#else
-net_drv_tbl_t METHODS = {
- n_probe : em_probe,
- n_attach : em_attach,
-#ifdef DEBUG_MODULAR
- n_detach : em_detach,
-#else
- n_detach: 0,
-#endif
- n_intr : em_intr,
-};
-#endif
-
-/*********************************************************************
- * Tunable default values.
- *********************************************************************/
-
-#define E1000_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000)
-#define E1000_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024)
-
-#ifndef __rtems__
-static int em_tx_int_delay_dflt = E1000_TICKS_TO_USECS(EM_TIDV);
-static int em_rx_int_delay_dflt = E1000_TICKS_TO_USECS(EM_RDTR);
-static int em_tx_abs_int_delay_dflt = E1000_TICKS_TO_USECS(EM_TADV);
-static int em_rx_abs_int_delay_dflt = E1000_TICKS_TO_USECS(EM_RADV);
-
-TUNABLE_INT("hw.em.tx_int_delay", &em_tx_int_delay_dflt);
-TUNABLE_INT("hw.em.rx_int_delay", &em_rx_int_delay_dflt);
-TUNABLE_INT("hw.em.tx_abs_int_delay", &em_tx_abs_int_delay_dflt);
-TUNABLE_INT("hw.em.rx_abs_int_delay", &em_rx_abs_int_delay_dflt);
-#endif
-
-/*********************************************************************
- * Device identification routine
- *
- * em_probe determines if the driver should be loaded on
- * adapter based on PCI vendor/device id of the adapter.
- *
- * return BUS_PROBE_DEFAULT on success, positive on failure
- *********************************************************************/
-
-static int
-em_probe(device_t dev)
-{
- em_vendor_info_t *ent;
-
- u_int16_t pci_vendor_id = 0;
- u_int16_t pci_device_id = 0;
- u_int16_t pci_subvendor_id = 0;
- u_int16_t pci_subdevice_id = 0;
- char adapter_name[60];
-
- INIT_DEBUGOUT("em_probe: begin");
-
- pci_vendor_id = pci_get_vendor(dev);
- if (pci_vendor_id != EM_VENDOR_ID)
- return(ENXIO);
-
- pci_device_id = pci_get_device(dev);
- pci_subvendor_id = pci_get_subvendor(dev);
- pci_subdevice_id = pci_get_subdevice(dev);
-
- ent = em_vendor_info_array;
- while (ent->vendor_id != 0) {
- if ((pci_vendor_id == ent->vendor_id) &&
- (pci_device_id == ent->device_id) &&
-
- ((pci_subvendor_id == ent->subvendor_id) ||
- (ent->subvendor_id == PCI_ANY_ID)) &&
-
- ((pci_subdevice_id == ent->subdevice_id) ||
- (ent->subdevice_id == PCI_ANY_ID))) {
- sprintf(adapter_name, "%s, Version - %s",
- em_strings[ent->index],
- em_driver_version);
- device_set_desc_copy(dev, adapter_name);
- return(BUS_PROBE_DEFAULT);
- }
- ent++;
- }
-
- return(ENXIO);
-}
-
-/*********************************************************************
- * Device initialization routine
- *
- * The attach entry point is called when the driver is being loaded.
- * This routine identifies the type of hardware, allocates all resources
- * and initializes the hardware.
- *
- * return 0 on success, positive on failure
- *********************************************************************/
-
-static int
-em_attach(device_t dev)
-{
- struct adapter * adapter;
- int tsize, rsize;
- int error = 0;
-
- INIT_DEBUGOUT("em_attach: begin");
-
- /* Allocate, clear, and link in our adapter structure */
- if (!(adapter = device_get_softc(dev))) {
- printf("em: adapter structure allocation failed\n");
- return(ENOMEM);
- }
-#ifndef __rtems__
- bzero(adapter, sizeof(struct adapter ));
-#else
- /* softc structure is maintained outside of this
- * and the osdep already contains vital fields (memory address)
- */
-#endif
- adapter->dev = dev;
- adapter->osdep.dev = dev;
- adapter->unit = device_get_unit(dev);
- EM_LOCK_INIT(adapter, device_get_nameunit(dev));
-
- if (em_adapter_list != NULL)
- em_adapter_list->prev = adapter;
- adapter->next = em_adapter_list;
- em_adapter_list = adapter;
-
-#ifndef __rtems__
- /* SYSCTL stuff */
- SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "debug_info", CTLTYPE_INT|CTLFLAG_RW,
- (void *)adapter, 0,
- em_sysctl_debug_info, "I", "Debug Information");
-
- SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "stats", CTLTYPE_INT|CTLFLAG_RW,
- (void *)adapter, 0,
- em_sysctl_stats, "I", "Statistics");
-#endif
-
- callout_init(&adapter->timer, CALLOUT_MPSAFE);
- callout_init(&adapter->tx_fifo_timer, CALLOUT_MPSAFE);
-
- /* Determine hardware revision */
- em_identify_hardware(adapter);
-
-#ifndef __rtems__
- /* Set up some sysctls for the tunable interrupt delays */
- em_add_int_delay_sysctl(adapter, "rx_int_delay",
- "receive interrupt delay in usecs", &adapter->rx_int_delay,
- E1000_REG_OFFSET(&adapter->hw, RDTR), em_rx_int_delay_dflt);
- em_add_int_delay_sysctl(adapter, "tx_int_delay",
- "transmit interrupt delay in usecs", &adapter->tx_int_delay,
- E1000_REG_OFFSET(&adapter->hw, TIDV), em_tx_int_delay_dflt);
- if (adapter->hw.mac_type >= em_82540) {
- em_add_int_delay_sysctl(adapter, "rx_abs_int_delay",
- "receive interrupt delay limit in usecs",
- &adapter->rx_abs_int_delay,
- E1000_REG_OFFSET(&adapter->hw, RADV),
- em_rx_abs_int_delay_dflt);
- em_add_int_delay_sysctl(adapter, "tx_abs_int_delay",
- "transmit interrupt delay limit in usecs",
- &adapter->tx_abs_int_delay,
- E1000_REG_OFFSET(&adapter->hw, TADV),
- em_tx_abs_int_delay_dflt);
- }
-#endif
-
- /* Parameters (to be read from user) */
- adapter->num_tx_desc = EM_MAX_TXD;
- adapter->num_rx_desc = EM_MAX_RXD;
-#ifdef __rtems__
- if ( dev->d_ifconfig->rbuf_count > 0 ) {
- adapter->num_rx_desc = dev->d_ifconfig->rbuf_count;
- }
- if ( adapter->num_rx_desc < 80 )
- adapter->num_rx_desc = 80;
- if ( adapter->num_rx_desc > 256 )
- adapter->num_rx_desc = 256;
- if ( dev->d_ifconfig->xbuf_count > 0 ) {
- adapter->num_tx_desc = dev->d_ifconfig->xbuf_count;
- }
- if ( adapter->num_tx_desc < 80 )
- adapter->num_tx_desc = 80;
- if ( adapter->num_tx_desc > 256 )
- adapter->num_tx_desc = 256;
- adapter->tx_cleanup_threshold = adapter->num_tx_desc/8;
-#endif
- adapter->hw.autoneg = DO_AUTO_NEG;
- adapter->hw.wait_autoneg_complete = WAIT_FOR_AUTO_NEG_DEFAULT;
- adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
- adapter->hw.tbi_compatibility_en = TRUE;
- adapter->rx_buffer_len = EM_RXBUFFER_2048;
-
- /*
- * These parameters control the automatic generation(Tx) and
- * response(Rx) to Ethernet PAUSE frames.
- */
- adapter->hw.fc_high_water = FC_DEFAULT_HI_THRESH;
- adapter->hw.fc_low_water = FC_DEFAULT_LO_THRESH;
- adapter->hw.fc_pause_time = FC_DEFAULT_TX_TIMER;
- adapter->hw.fc_send_xon = TRUE;
- adapter->hw.fc = em_fc_full;
-
- adapter->hw.phy_init_script = 1;
- adapter->hw.phy_reset_disable = FALSE;
-
-#ifndef EM_MASTER_SLAVE
- adapter->hw.master_slave = em_ms_hw_default;
-#else
- adapter->hw.master_slave = EM_MASTER_SLAVE;
-#endif
- /*
- * Set the max frame size assuming standard ethernet
- * sized frames
- */
- adapter->hw.max_frame_size =
- ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN;
-
- adapter->hw.min_frame_size =
- MINIMUM_ETHERNET_PACKET_SIZE + ETHER_CRC_LEN;
-
- /*
- * This controls when hardware reports transmit completion
- * status.
- */
- adapter->hw.report_tx_early = 1;
-
-
- if (em_allocate_pci_resources(adapter)) {
- printf("em%d: Allocation of PCI resources failed\n",
- adapter->unit);
- error = ENXIO;
- goto err_pci;
- }
-
-
- /* Initialize eeprom parameters */
- em_init_eeprom_params(&adapter->hw);
-
- tsize = EM_ROUNDUP(adapter->num_tx_desc *
- sizeof(struct em_tx_desc), 4096);
-
- /* Allocate Transmit Descriptor ring */
- if (em_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
- printf("em%d: Unable to allocate tx_desc memory\n",
- adapter->unit);
- error = ENOMEM;
- goto err_tx_desc;
- }
- adapter->tx_desc_base = (struct em_tx_desc *) adapter->txdma.dma_vaddr;
-
- rsize = EM_ROUNDUP(adapter->num_rx_desc *
- sizeof(struct em_rx_desc), 4096);
-
- /* Allocate Receive Descriptor ring */
- if (em_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
- printf("em%d: Unable to allocate rx_desc memory\n",
- adapter->unit);
- error = ENOMEM;
- goto err_rx_desc;
- }
- adapter->rx_desc_base = (struct em_rx_desc *) adapter->rxdma.dma_vaddr;
-
- /* Initialize the hardware */
- if (em_hardware_init(adapter)) {
- printf("em%d: Unable to initialize the hardware\n",
- adapter->unit);
- error = EIO;
- goto err_hw_init;
- }
-
- /* Copy the permanent MAC address out of the EEPROM */
- if (em_read_mac_addr(&adapter->hw) < 0) {
- printf("em%d: EEPROM read error while reading mac address\n",
- adapter->unit);
- error = EIO;
- goto err_mac_addr;
- }
-
-#ifdef __rtems__
- /* if the configuration has not set a mac address, copy the permanent
- * address from the device to the arpcom struct.
- */
- {
- int i;
- for ( i=0; i<ETHER_ADDR_LEN; i++ ) {
- if ( adapter->arpcom.ac_enaddr[i] )
- break;
- }
- if ( i >= ETHER_ADDR_LEN ) {
- /* all nulls */
- bcopy(adapter->hw.mac_addr, adapter->arpcom.ac_enaddr,
- ETHER_ADDR_LEN);
- }
- }
-#endif
-
- if (!em_is_valid_ether_addr(adapter->hw.mac_addr)) {
- printf("em%d: Invalid mac address\n", adapter->unit);
- error = EIO;
- goto err_mac_addr;
- }
-
- /* Setup OS specific network interface */
- em_setup_interface(dev, adapter);
-
- /* Initialize statistics */
- em_clear_hw_cntrs(&adapter->hw);
- em_update_stats_counters(adapter);
- adapter->hw.get_link_status = 1;
-#ifndef __rtems__
- em_check_for_link(&adapter->hw);
-#else
- /* first check during hw init usually fails - probably we need to wait longer;
- * could take a while till the link is up, depends on the partner?
- * in any case, rather than waiting here we just proceed...
- */
- em_check_for_link(&adapter->hw);
- /* em_check_for_link doesn't update 'link_active'
- * -- they usually call em_print_link_status() right
- * after check_for_link, so let's repeat this
- * algorithm here.
- */
- em_print_link_status(adapter);
-#endif
-
- /* Print the link status */
- if (adapter->link_active == 1) {
- em_get_speed_and_duplex(&adapter->hw, &adapter->link_speed,
- &adapter->link_duplex);
- printf("em%d: Speed:%d Mbps Duplex:%s\n",
- adapter->unit,
- adapter->link_speed,
- adapter->link_duplex == FULL_DUPLEX ? "Full" : "Half");
- } else
- printf("em%d: Speed:N/A Duplex:N/A\n", adapter->unit);
-
- /* Identify 82544 on PCIX */
- em_get_bus_info(&adapter->hw);
- if(adapter->hw.bus_type == em_bus_type_pcix &&
- adapter->hw.mac_type == em_82544) {
- adapter->pcix_82544 = TRUE;
- }
- else {
- adapter->pcix_82544 = FALSE;
- }
- INIT_DEBUGOUT("em_attach: end");
- return(0);
-
-err_mac_addr:
-err_hw_init:
- em_dma_free(adapter, &adapter->rxdma);
-err_rx_desc:
- em_dma_free(adapter, &adapter->txdma);
-err_tx_desc:
-err_pci:
-#ifndef __rtems__
- em_free_pci_resources(adapter);
-#endif
- return(error);
-
-}
-
-/*********************************************************************
- * Device removal routine
- *
- * The detach entry point is called when the driver is being removed.
- * This routine stops the adapter and deallocates all the resources
- * that were allocated for driver operation.
- *
- * return 0 on success, positive on failure
- *********************************************************************/
-
-#if !defined(__rtems__) || defined(DEBUG_MODULAR)
-
-static int
-em_detach(device_t dev)
-{
- struct adapter * adapter = device_get_softc(dev);
- struct ifnet *ifp = &adapter->arpcom.ac_if;
-
- INIT_DEBUGOUT("em_detach: begin");
-
- EM_LOCK(adapter);
- adapter->in_detach = 1;
- em_stop(adapter);
- em_phy_hw_reset(&adapter->hw);
- EM_UNLOCK(adapter);
-#ifndef __rtems__
-#if __FreeBSD_version < 500000
- ether_ifdetach(adapter->ifp, ETHER_BPF_SUPPORTED);
-#else
- ether_ifdetach(adapter->ifp);
- if_free(ifp);
-#endif
- em_free_pci_resources(adapter);
- bus_generic_detach(dev);
-#else
- ether_ifdetach(ifp);
-#endif
-
- /* Free Transmit Descriptor ring */
- if (adapter->tx_desc_base) {
- em_dma_free(adapter, &adapter->txdma);
- adapter->tx_desc_base = NULL;
- }
-
- /* Free Receive Descriptor ring */
- if (adapter->rx_desc_base) {
- em_dma_free(adapter, &adapter->rxdma);
- adapter->rx_desc_base = NULL;
- }
-
- /* Remove from the adapter list */
- if (em_adapter_list == adapter)
- em_adapter_list = adapter->next;
- if (adapter->next != NULL)
- adapter->next->prev = adapter->prev;
- if (adapter->prev != NULL)
- adapter->prev->next = adapter->next;
-
- EM_LOCK_DESTROY(adapter);
-
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
- ifp->if_timer = 0;
-
- return(0);
-}
-
-#endif
-
-#ifndef __rtems__
-/*********************************************************************
- *
- * Shutdown entry point
- *
- **********************************************************************/
-
-static int
-em_shutdown(device_t dev)
-{
- struct adapter *adapter = device_get_softc(dev);
- EM_LOCK(adapter);
- em_stop(adapter);
- EM_UNLOCK(adapter);
- return(0);
-}
-#endif
-
-/*********************************************************************
- * Transmit entry point
- *
- * em_start is called by the stack to initiate a transmit.
- * The driver will remain in this routine as long as there are
- * packets to transmit and transmit resources are available.
- * In case resources are not available stack is notified and
- * the packet is requeued.
- **********************************************************************/
-
-static void
-em_start_locked(struct ifnet *ifp)
-{
- struct mbuf *m_head;
- struct adapter *adapter = ifp->if_softc;
-
- mtx_assert(&adapter->mtx, MA_OWNED);
-
- if (!adapter->link_active)
- return;
-
- while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
-
- if (m_head == NULL) break;
-
- /*
- * em_encap() can modify our pointer, and or make it NULL on
- * failure. In that event, we can't requeue.
- */
- if (em_encap(adapter, &m_head)) {
- if (m_head == NULL)
- break;
- ifp->if_flags |= IFF_OACTIVE;
- IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
- break;
- }
-
- /* Send a copy of the frame to the BPF listener */
-#if __FreeBSD_version < 500000 && !defined(__rtems__)
- if (ifp->if_bpf)
- bpf_mtap(ifp, m_head);
-#else
- BPF_MTAP(ifp, m_head);
-#endif
-
- /* Set timeout in case hardware has problems transmitting */
- ifp->if_timer = EM_TX_TIMEOUT;
-
- }
- return;
-}
-
-static void
-em_start(struct ifnet *ifp)
-{
- struct adapter *adapter RTEMS_UNUSED = ifp->if_softc;
-
- EM_LOCK(adapter);
- em_start_locked(ifp);
- EM_UNLOCK(adapter);
- return;
-}
-
-/*********************************************************************
- * Ioctl entry point
- *
- * em_ioctl is called when the user wants to configure the
- * interface.
- *
- * return 0 on success, positive on failure
- **********************************************************************/
-
-#ifndef __rtems__
-static int
-em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-#else
-static int
-em_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-#endif
-{
-#ifndef __rtems__
- int mask, reinit, error = 0;
-#else
- int error = 0;
-#endif
- struct ifreq *ifr = (struct ifreq *) data;
- struct adapter * adapter = ifp->if_softc;
-
- if (adapter->in_detach) return(error);
-
- switch (command) {
- case SIOCSIFADDR:
- case SIOCGIFADDR:
- IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFADDR (Get/Set Interface Addr)");
- ether_ioctl(ifp, command, data);
- break;
- case SIOCSIFMTU:
- IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
- if (ifr->ifr_mtu > MAX_JUMBO_FRAME_SIZE - ETHER_HDR_LEN || \
- /* 82573 does not support jumbo frames */
- (adapter->hw.mac_type == em_82573 && ifr->ifr_mtu > ETHERMTU) ) {
- error = EINVAL;
- } else {
- EM_LOCK(adapter);
- ifp->if_mtu = ifr->ifr_mtu;
- adapter->hw.max_frame_size =
- ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
- em_init_locked(adapter);
- EM_UNLOCK(adapter);
- }
- break;
- case SIOCSIFFLAGS:
- IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)");
- EM_LOCK(adapter);
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_flags & IFF_RUNNING)) {
- em_init_locked(adapter);
- }
-
- em_disable_promisc(adapter);
- em_set_promisc(adapter);
- } else {
- if (ifp->if_flags & IFF_RUNNING) {
- em_stop(adapter);
- }
- }
- EM_UNLOCK(adapter);
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
-#ifdef __rtems__
- if ( (error = ( SIOCADDMULTI == command ?
- ether_addmulti( ifr, (struct arpcom*)ifp ) :
- ether_delmulti( ifr, (struct arpcom*)ifp ) ) ) ) {
- if ( ENETRESET == error )
- error = 0;
- else
- break;
- }
-#endif
- IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI");
- if (ifp->if_flags & IFF_RUNNING) {
- EM_LOCK(adapter);
- em_disable_intr(adapter);
- em_set_multi(adapter);
- if (adapter->hw.mac_type == em_82542_rev2_0) {
- em_initialize_receive_unit(adapter);
- }
-#ifdef DEVICE_POLLING
- if (!(ifp->if_flags & IFF_POLLING))
-#endif
- em_enable_intr(adapter);
- EM_UNLOCK(adapter);
- }
- break;
-#ifndef __rtems__
- case SIOCSIFMEDIA:
- case SIOCGIFMEDIA:
- IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFMEDIA (Get/Set Interface Media)");
- error = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
- break;
-#else
- case SIOCSIFMEDIA:
- {
- struct rtems_ifmedia mhack;
- mhack.ifm_media = ifr->ifr_media;
- error = em_media_change(ifp, &mhack);
- }
- break;
- case SIOCGIFMEDIA:
- {
- struct ifmediareq ifmr;
- em_media_status(ifp, &ifmr);
- ifr->ifr_media = ifmr.ifm_active;
- /* add-in rtems flags */
- if ( adapter->link_active )
- ifr->ifr_media |= IFM_LINK_OK;
- if ( !adapter->hw.autoneg )
- ifr->ifr_media |= IFM_ANEG_DIS;
- error = 0;
- }
- break;
-#endif
-#ifndef __rtems__
- case SIOCSIFCAP:
- IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
- reinit = 0;
- mask = ifr->ifr_reqcap ^ ifp->if_capenable;
- if (mask & IFCAP_POLLING)
- ifp->if_capenable ^= IFCAP_POLLING;
- if (mask & IFCAP_HWCSUM) {
- ifp->if_capenable ^= IFCAP_HWCSUM;
- reinit = 1;
- }
- if (mask & IFCAP_VLAN_HWTAGGING) {
- ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
- reinit = 1;
- }
- if (reinit && (ifp->if_flags & IFF_RUNNING))
- em_init(adapter);
- break;
-#endif
-
-#ifdef __rtems__
- case SIO_RTEMS_SHOW_STATS:
- em_print_hw_stats(adapter);
- error = 0;
- break;
-#endif
-
- default:
- IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%x)", (int)command);
- error = EINVAL;
- }
-
- return(error);
-}
-
-/*********************************************************************
- * Watchdog entry point
- *
- * This routine is called whenever hardware quits transmitting.
- *
- **********************************************************************/
-
-static void
-em_watchdog(struct ifnet *ifp)
-{
- struct adapter * adapter;
- adapter = ifp->if_softc;
-
- /* If we are in this routine because of pause frames, then
- * don't reset the hardware.
- */
- if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF) {
- ifp->if_timer = EM_TX_TIMEOUT;
- return;
- }
-
- if (em_check_for_link(&adapter->hw))
- printf("em%d: watchdog timeout -- resetting\n", adapter->unit);
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- em_init(adapter);
-
- ifp->if_oerrors++;
- return;
-}
-
-/*********************************************************************
- * Init entry point
- *
- * This routine is used in two ways. It is used by the stack as
- * init entry point in network interface structure. It is also used
- * by the driver as a hw/sw initialization routine to get to a
- * consistent state.
- *
- * return 0 on success, positive on failure
- **********************************************************************/
-
-static void
-em_init_locked(struct adapter * adapter)
-{
- struct ifnet *ifp;
-
- uint32_t pba;
- ifp = &adapter->arpcom.ac_if;
-
- INIT_DEBUGOUT("em_init: begin");
-
- mtx_assert(&adapter->mtx, MA_OWNED);
-
- em_stop(adapter);
-
- /* Packet Buffer Allocation (PBA)
- * Writing PBA sets the receive portion of the buffer
- * the remainder is used for the transmit buffer.
- *
- * Devices before the 82547 had a Packet Buffer of 64K.
- * Default allocation: PBA=48K for Rx, leaving 16K for Tx.
- * After the 82547 the buffer was reduced to 40K.
- * Default allocation: PBA=30K for Rx, leaving 10K for Tx.
- * Note: default does not leave enough room for Jumbo Frame >10k.
- */
- if(adapter->hw.mac_type < em_82547) {
- /* Total FIFO is 64K */
- if(adapter->rx_buffer_len > EM_RXBUFFER_8192)
- pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */
- else
- pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */
- } else {
- /* Total FIFO is 40K */
- if(adapter->hw.max_frame_size > EM_RXBUFFER_8192) {
- pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */
- } else {
- pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */
- }
- adapter->tx_fifo_head = 0;
- adapter->tx_head_addr = pba << EM_TX_HEAD_ADDR_SHIFT;
- adapter->tx_fifo_size = (E1000_PBA_40K - pba) << EM_PBA_BYTES_SHIFT;
- }
- INIT_DEBUGOUT1("em_init: pba=%" PRId32 "K",pba);
- E1000_WRITE_REG(&adapter->hw, PBA, pba);
-
- /* Get the latest mac address, User can use a LAA */
- bcopy(adapter->arpcom.ac_enaddr, adapter->hw.mac_addr,
- ETHER_ADDR_LEN);
-
- /* Initialize the hardware */
- if (em_hardware_init(adapter)) {
- printf("em%d: Unable to initialize the hardware\n",
- adapter->unit);
- return;
- }
-
-#ifndef __rtems__
- if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
- em_enable_vlans(adapter);
-#endif
-
- /* Prepare transmit descriptors and buffers */
- if (em_setup_transmit_structures(adapter)) {
- printf("em%d: Could not setup transmit structures\n",
- adapter->unit);
- em_stop(adapter);
- return;
- }
- em_initialize_transmit_unit(adapter);
-
- /* Setup Multicast table */
- em_set_multi(adapter);
-
- /* Prepare receive descriptors and buffers */
- if (em_setup_receive_structures(adapter)) {
- printf("em%d: Could not setup receive structures\n",
- adapter->unit);
- em_stop(adapter);
- return;
- }
- em_initialize_receive_unit(adapter);
-
- /* Don't loose promiscuous settings */
- em_set_promisc(adapter);
-
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-
-#ifndef __rtems__
- if (adapter->hw.mac_type >= em_82543) {
- if (ifp->if_capenable & IFCAP_TXCSUM)
- ifp->if_hwassist = EM_CHECKSUM_FEATURES;
- else
- ifp->if_hwassist = 0;
- }
-#endif
-
- callout_reset(&adapter->timer, hz, em_local_timer, adapter);
- em_clear_hw_cntrs(&adapter->hw);
-#ifdef DEVICE_POLLING
- /*
- * Only enable interrupts if we are not polling, make sure
- * they are off otherwise.
- */
- if (ifp->if_flags & IFF_POLLING)
- em_disable_intr(adapter);
- else
-#endif /* DEVICE_POLLING */
- em_enable_intr(adapter);
-
- /* Don't reset the phy next time init gets called */
- adapter->hw.phy_reset_disable = TRUE;
-
- return;
-}
-
-static void
-em_init(void *arg)
-{
- struct adapter * adapter = arg;
-
- EM_LOCK(adapter);
- em_init_locked(adapter);
- EM_UNLOCK(adapter);
- return;
-}
-
-
-#ifdef DEVICE_POLLING
-static poll_handler_t em_poll;
-
-static void
-em_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
-{
- struct adapter *adapter = ifp->if_softc;
- u_int32_t reg_icr;
-
- mtx_assert(&adapter->mtx, MA_OWNED);
-
- if (!(ifp->if_capenable & IFCAP_POLLING)) {
- ether_poll_deregister(ifp);
- cmd = POLL_DEREGISTER;
- }
- if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
- em_enable_intr(adapter);
- return;
- }
- if (cmd == POLL_AND_CHECK_STATUS) {
- reg_icr = E1000_READ_REG(&adapter->hw, ICR);
- if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- callout_stop(&adapter->timer);
- adapter->hw.get_link_status = 1;
- em_check_for_link(&adapter->hw);
- em_print_link_status(adapter);
- callout_reset(&adapter->timer, hz, em_local_timer, adapter);
- }
- }
- if (ifp->if_flags & IFF_RUNNING) {
- em_process_receive_interrupts(adapter, count);
- em_clean_transmit_interrupts(adapter);
- }
-
- if (ifp->if_flags & IFF_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- em_start_locked(ifp);
-}
-
-static void
-em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
-{
- struct adapter *adapter = ifp->if_softc;
-
- EM_LOCK(adapter);
- em_poll_locked(ifp, cmd, count);
- EM_UNLOCK(adapter);
-}
-#endif /* DEVICE_POLLING */
-
-/*********************************************************************
- *
- * Interrupt Service routine
- *
- **********************************************************************/
-static void
-em_intr(void *arg)
-{
- u_int32_t loop_cnt = EM_MAX_INTR;
- u_int32_t reg_icr;
- struct ifnet *ifp;
- struct adapter *adapter = arg;
-
- EM_LOCK(adapter);
-
- ifp = &adapter->arpcom.ac_if;
-
-#ifdef DEVICE_POLLING
- if (ifp->if_flags & IFF_POLLING) {
- EM_UNLOCK(adapter);
- return;
- }
-
- if ((ifp->if_capenable & IFCAP_POLLING) &&
- ether_poll_register(em_poll, ifp)) {
- em_disable_intr(adapter);
- em_poll_locked(ifp, 0, 1);
- EM_UNLOCK(adapter);
- return;
- }
-#endif /* DEVICE_POLLING */
-
- reg_icr = E1000_READ_REG(&adapter->hw, ICR);
- if (!reg_icr) {
- EM_UNLOCK(adapter);
- return;
- }
-
- /* Link status change */
- if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- callout_stop(&adapter->timer);
- adapter->hw.get_link_status = 1;
- em_check_for_link(&adapter->hw);
- em_print_link_status(adapter);
- callout_reset(&adapter->timer, hz, em_local_timer, adapter);
- }
-
- while (loop_cnt > 0) {
- if (ifp->if_flags & IFF_RUNNING) {
- em_process_receive_interrupts(adapter, -1);
- em_clean_transmit_interrupts(adapter);
- }
- loop_cnt--;
- }
-
- if (ifp->if_flags & IFF_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- em_start_locked(ifp);
-
- EM_UNLOCK(adapter);
- return;
-}
-
-
-
-/*********************************************************************
- *
- * Media Ioctl callback
- *
- * This routine is called whenever the user queries the status of
- * the interface using ifconfig.
- *
- **********************************************************************/
-static void
-em_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct adapter * adapter = ifp->if_softc;
-
- INIT_DEBUGOUT("em_media_status: begin");
-
- em_check_for_link(&adapter->hw);
- if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) {
- if (adapter->link_active == 0) {
- em_get_speed_and_duplex(&adapter->hw,
- &adapter->link_speed,
- &adapter->link_duplex);
- adapter->link_active = 1;
- }
- } else {
- if (adapter->link_active == 1) {
- adapter->link_speed = 0;
- adapter->link_duplex = 0;
- adapter->link_active = 0;
- }
- }
-
- ifmr->ifm_status = IFM_AVALID;
- ifmr->ifm_active = IFM_ETHER;
-
- if (!adapter->link_active)
- return;
-
- ifmr->ifm_status |= IFM_ACTIVE;
-
- if (adapter->hw.media_type == em_media_type_fiber) {
- ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
- } else {
- switch (adapter->link_speed) {
- case 10:
- ifmr->ifm_active |= IFM_10_T;
- break;
- case 100:
- ifmr->ifm_active |= IFM_100_TX;
- break;
- case 1000:
-#if __FreeBSD_version < 500000 && !defined(__rtems__)
- ifmr->ifm_active |= IFM_1000_TX;
-#else
- ifmr->ifm_active |= IFM_1000_T;
-#endif
- break;
- }
- if (adapter->link_duplex == FULL_DUPLEX)
- ifmr->ifm_active |= IFM_FDX;
- else
- ifmr->ifm_active |= IFM_HDX;
- }
- return;
-}
-
-/*********************************************************************
- *
- * Media Ioctl callback
- *
- * This routine is called when the user changes speed/duplex using
- * media/mediopt option with ifconfig.
- *
- **********************************************************************/
-static int
-#ifndef __rtems__
-em_media_change(struct ifnet *ifp)
-#else
-em_media_change(struct ifnet *ifp, struct rtems_ifmedia *ifm)
-#endif
-{
- struct adapter * adapter = ifp->if_softc;
-#ifndef __rtems__
- struct ifmedia *ifm = &adapter->media;
-#endif
-
- INIT_DEBUGOUT("em_media_change: begin");
-
- if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
- return(EINVAL);
-
- switch (IFM_SUBTYPE(ifm->ifm_media)) {
- case IFM_AUTO:
- adapter->hw.autoneg = DO_AUTO_NEG;
- adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
- break;
- case IFM_1000_SX:
-#if __FreeBSD_version < 500000 && !defined(__rtems__)
- case IFM_1000_TX:
-#else
- case IFM_1000_T:
-#endif
- adapter->hw.autoneg = DO_AUTO_NEG;
- adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
- break;
- case IFM_100_TX:
- adapter->hw.autoneg = FALSE;
- adapter->hw.autoneg_advertised = 0;
- if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
- adapter->hw.forced_speed_duplex = em_100_full;
- else
- adapter->hw.forced_speed_duplex = em_100_half;
- break;
- case IFM_10_T:
- adapter->hw.autoneg = FALSE;
- adapter->hw.autoneg_advertised = 0;
- if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
- adapter->hw.forced_speed_duplex = em_10_full;
- else
- adapter->hw.forced_speed_duplex = em_10_half;
- break;
- default:
- printf("em%d: Unsupported media type\n", adapter->unit);
- }
-
- /* As the speed/duplex settings my have changed we need to
- * reset the PHY.
- */
- adapter->hw.phy_reset_disable = FALSE;
-
- em_init(adapter);
-
- return(0);
-}
-
-/*********************************************************************
- *
- * This routine maps the mbufs to tx descriptors.
- *
- * return 0 on success, positive on failure
- **********************************************************************/
-static int
-em_encap(struct adapter *adapter, struct mbuf **m_headp)
-{
- u_int32_t txd_upper;
- u_int32_t txd_lower, txd_used = 0, txd_saved = 0;
- int i, j, error;
- u_int64_t address;
-
- struct mbuf *m_head;
-
- /* For 82544 Workaround */
- DESC_ARRAY desc_array;
- u_int32_t array_elements;
- u_int32_t counter;
-
-#ifndef __rtems__
-#if __FreeBSD_version < 500000
- struct ifvlan *ifv = NULL;
-#else
- struct m_tag *mtag;
-#endif
-#endif
- bus_dma_segment_t segs[EM_MAX_SCATTER];
-#ifndef __rtems__
- bus_dmamap_t map;
-#endif
- int nsegs;
- struct em_buffer *tx_buffer = NULL;
- struct em_tx_desc *current_tx_desc = NULL;
-#ifndef __rtems__
- struct ifnet *ifp = &adapter->arpcom.ac_if;
-#endif
-
- m_head = *m_headp;
-
- /*
- * Force a cleanup if number of TX descriptors
- * available hits the threshold
- */
- if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
- em_clean_transmit_interrupts(adapter);
- if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
- adapter->no_tx_desc_avail1++;
- return(ENOBUFS);
- }
- }
-
-#ifndef __rtems__
- /*
- * Map the packet for DMA.
- */
- if (bus_dmamap_create(adapter->txtag, BUS_DMA_NOWAIT, &map)) {
- adapter->no_tx_map_avail++;
- return (ENOMEM);
- }
- error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, m_head, segs,
- &nsegs, BUS_DMA_NOWAIT);
- if (error != 0) {
- adapter->no_tx_dma_setup++;
- bus_dmamap_destroy(adapter->txtag, map);
- return (error);
- }
-#else
- (void)error;
- {
- struct mbuf *m;
- for ( m=m_head, nsegs=0; m; m=m->m_next, nsegs++ ) {
- if ( nsegs >= sizeof(segs)/sizeof(segs[0]) ) {
- break;
- }
- segs[nsegs].ds_addr = mtod(m, unsigned);
- segs[nsegs].ds_len = m->m_len;
- }
- }
-#endif
- KASSERT(nsegs != 0, ("em_encap: empty packet"));
-
- if (nsegs > adapter->num_tx_desc_avail) {
- adapter->no_tx_desc_avail2++;
- bus_dmamap_destroy(adapter->txtag, map);
- return (ENOBUFS);
- }
-
-
-#ifndef __rtems__
- if (ifp->if_hwassist > 0) {
- em_transmit_checksum_setup(adapter, m_head,
- &txd_upper, &txd_lower);
- } else
-#endif
- txd_upper = txd_lower = 0;
-
-
-#ifndef __rtems__
- /* Find out if we are in vlan mode */
-#if __FreeBSD_version < 500000
- if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
- m_head->m_pkthdr.rcvif != NULL &&
- m_head->m_pkthdr.rcvif->if_type == IFT_L2VLAN)
- ifv = m_head->m_pkthdr.rcvif->if_softc;
-#else
- mtag = VLAN_OUTPUT_TAG(ifp, m_head);
-#endif
-
- /*
- * When operating in promiscuous mode, hardware encapsulation for
- * packets is disabled. This means we have to add the vlan
- * encapsulation in the driver, since it will have come down from the
- * VLAN layer with a tag instead of a VLAN header.
- */
- if (mtag != NULL && adapter->em_insert_vlan_header) {
- struct ether_vlan_header *evl;
- struct ether_header eh;
-
- m_head = m_pullup(m_head, sizeof(eh));
- if (m_head == NULL) {
- *m_headp = NULL;
- bus_dmamap_destroy(adapter->txtag, map);
- return (ENOBUFS);
- }
- eh = *mtod(m_head, struct ether_header *);
- M_PREPEND(m_head, sizeof(*evl), M_DONTWAIT);
- if (m_head == NULL) {
- *m_headp = NULL;
- bus_dmamap_destroy(adapter->txtag, map);
- return (ENOBUFS);
- }
- m_head = m_pullup(m_head, sizeof(*evl));
- if (m_head == NULL) {
- *m_headp = NULL;
- bus_dmamap_destroy(adapter->txtag, map);
- return (ENOBUFS);
- }
- evl = mtod(m_head, struct ether_vlan_header *);
- bcopy(&eh, evl, sizeof(*evl));
- evl->evl_proto = evl->evl_encap_proto;
- evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
- evl->evl_tag = htons(VLAN_TAG_VALUE(mtag));
- m_tag_delete(m_head, mtag);
- mtag = NULL;
- *m_headp = m_head;
- }
-#endif
-
- i = adapter->next_avail_tx_desc;
- if (adapter->pcix_82544) {
- txd_saved = i;
- txd_used = 0;
- }
- for (j = 0; j < nsegs; j++) {
- /* If adapter is 82544 and on PCIX bus */
- if(adapter->pcix_82544) {
- array_elements = 0;
- address = htole64(segs[j].ds_addr);
- /*
- * Check the Address and Length combination and
- * split the data accordingly
- */
- array_elements = em_fill_descriptors(address,
- htole32(segs[j].ds_len),
- &desc_array);
- for (counter = 0; counter < array_elements; counter++) {
- if (txd_used == adapter->num_tx_desc_avail) {
- adapter->next_avail_tx_desc = txd_saved;
- adapter->no_tx_desc_avail2++;
- bus_dmamap_destroy(adapter->txtag, map);
- return (ENOBUFS);
- }
- tx_buffer = &adapter->tx_buffer_area[i];
- current_tx_desc = &adapter->tx_desc_base[i];
- current_tx_desc->buffer_addr = htole64(
- desc_array.descriptor[counter].address);
- current_tx_desc->lower.data = htole32(
- (adapter->txd_cmd | txd_lower |
- (u_int16_t)desc_array.descriptor[counter].length));
- current_tx_desc->upper.data = htole32((txd_upper));
- if (++i == adapter->num_tx_desc)
- i = 0;
-
- tx_buffer->m_head = NULL;
- txd_used++;
- }
- } else {
- tx_buffer = &adapter->tx_buffer_area[i];
- current_tx_desc = &adapter->tx_desc_base[i];
-
- current_tx_desc->buffer_addr = htole64(segs[j].ds_addr);
- current_tx_desc->lower.data = htole32(
- adapter->txd_cmd | txd_lower | segs[j].ds_len);
- current_tx_desc->upper.data = htole32(txd_upper);
-
- if (++i == adapter->num_tx_desc)
- i = 0;
-
- tx_buffer->m_head = NULL;
- }
- }
-
- adapter->next_avail_tx_desc = i;
- if (adapter->pcix_82544) {
- adapter->num_tx_desc_avail -= txd_used;
- }
- else {
- adapter->num_tx_desc_avail -= nsegs;
- }
-
-#ifndef __rtems__
-#if __FreeBSD_version < 500000
- if (ifv != NULL) {
- /* Set the vlan id */
- current_tx_desc->upper.fields.special = htole16(ifv->ifv_tag);
-#else
- if (mtag != NULL) {
- /* Set the vlan id */
- current_tx_desc->upper.fields.special = htole16(VLAN_TAG_VALUE(mtag));
-#endif
-
- /* Tell hardware to add tag */
- current_tx_desc->lower.data |= htole32(E1000_TXD_CMD_VLE);
- }
-#endif
-
- tx_buffer->m_head = m_head;
-#ifndef __rtems__
- tx_buffer->map = map;
-#endif
- bus_dmamap_sync(adapter->txtag, map, BUS_DMASYNC_PREWRITE);
-
- /*
- * Last Descriptor of Packet needs End Of Packet (EOP)
- */
- current_tx_desc->lower.data |= htole32(E1000_TXD_CMD_EOP);
-
- /*
- * Advance the Transmit Descriptor Tail (Tdt), this tells the E1000
- * that this frame is available to transmit.
- */
- bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if (adapter->hw.mac_type == em_82547 &&
- adapter->link_duplex == HALF_DUPLEX) {
- em_82547_move_tail_locked(adapter);
- } else {
- E1000_WRITE_REG(&adapter->hw, TDT, i);
- if (adapter->hw.mac_type == em_82547) {
- em_82547_update_fifo_head(adapter, m_head->m_pkthdr.len);
- }
- }
-
- return(0);
-}
-
-/*********************************************************************
- *
- * 82547 workaround to avoid controller hang in half-duplex environment.
- * The workaround is to avoid queuing a large packet that would span
- * the internal Tx FIFO ring boundary. We need to reset the FIFO pointers
- * in this case. We do that only when FIFO is quiescent.
- *
- **********************************************************************/
-static void
-em_82547_move_tail_locked(struct adapter *adapter)
-{
- uint16_t hw_tdt;
- uint16_t sw_tdt;
- struct em_tx_desc *tx_desc;
- uint16_t length = 0;
- boolean_t eop = 0;
-
- EM_LOCK_ASSERT(adapter);
-
- hw_tdt = E1000_READ_REG(&adapter->hw, TDT);
- sw_tdt = adapter->next_avail_tx_desc;
-
- while (hw_tdt != sw_tdt) {
- tx_desc = &adapter->tx_desc_base[hw_tdt];
- length += tx_desc->lower.flags.length;
- eop = tx_desc->lower.data & E1000_TXD_CMD_EOP;
- if(++hw_tdt == adapter->num_tx_desc)
- hw_tdt = 0;
-
- if(eop) {
- if (em_82547_fifo_workaround(adapter, length)) {
- adapter->tx_fifo_wrk_cnt++;
- callout_reset(&adapter->tx_fifo_timer, 1,
- em_82547_move_tail, adapter);
- break;
- }
- E1000_WRITE_REG(&adapter->hw, TDT, hw_tdt);
- em_82547_update_fifo_head(adapter, length);
- length = 0;
- }
- }
- return;
-}
-
-#ifndef __rtems__
-static void
-em_82547_move_tail(void *arg)
-{
- struct adapter *adapter = arg;
-
- EM_LOCK(adapter);
- em_82547_move_tail_locked(adapter);
- EM_UNLOCK(adapter);
-}
-#endif
-
-static int
-em_82547_fifo_workaround(struct adapter *adapter, int len)
-{
- int fifo_space, fifo_pkt_len;
-
- fifo_pkt_len = EM_ROUNDUP(len + EM_FIFO_HDR, EM_FIFO_HDR);
-
- if (adapter->link_duplex == HALF_DUPLEX) {
- fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
-
- if (fifo_pkt_len >= (EM_82547_PKT_THRESH + fifo_space)) {
- if (em_82547_tx_fifo_reset(adapter)) {
- return(0);
- }
- else {
- return(1);
- }
- }
- }
-
- return(0);
-}
-
-static void
-em_82547_update_fifo_head(struct adapter *adapter, int len)
-{
- int fifo_pkt_len = EM_ROUNDUP(len + EM_FIFO_HDR, EM_FIFO_HDR);
-
- /* tx_fifo_head is always 16 byte aligned */
- adapter->tx_fifo_head += fifo_pkt_len;
- if (adapter->tx_fifo_head >= adapter->tx_fifo_size) {
- adapter->tx_fifo_head -= adapter->tx_fifo_size;
- }
-
- return;
-}
-
-
-static int
-em_82547_tx_fifo_reset(struct adapter *adapter)
-{
- uint32_t tctl;
-
- if ( (E1000_READ_REG(&adapter->hw, TDT) ==
- E1000_READ_REG(&adapter->hw, TDH)) &&
- (E1000_READ_REG(&adapter->hw, TDFT) ==
- E1000_READ_REG(&adapter->hw, TDFH)) &&
- (E1000_READ_REG(&adapter->hw, TDFTS) ==
- E1000_READ_REG(&adapter->hw, TDFHS)) &&
- (E1000_READ_REG(&adapter->hw, TDFPC) == 0)) {
-
- /* Disable TX unit */
- tctl = E1000_READ_REG(&adapter->hw, TCTL);
- E1000_WRITE_REG(&adapter->hw, TCTL, tctl & ~E1000_TCTL_EN);
-
- /* Reset FIFO pointers */
- E1000_WRITE_REG(&adapter->hw, TDFT, adapter->tx_head_addr);
- E1000_WRITE_REG(&adapter->hw, TDFH, adapter->tx_head_addr);
- E1000_WRITE_REG(&adapter->hw, TDFTS, adapter->tx_head_addr);
- E1000_WRITE_REG(&adapter->hw, TDFHS, adapter->tx_head_addr);
-
- /* Re-enable TX unit */
- E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
- E1000_WRITE_FLUSH(&adapter->hw);
-
- adapter->tx_fifo_head = 0;
- adapter->tx_fifo_reset_cnt++;
-
- return(TRUE);
- }
- else {
- return(FALSE);
- }
-}
-
-static void
-em_set_promisc(struct adapter * adapter)
-{
-
- u_int32_t reg_rctl;
- struct ifnet *ifp = &adapter->arpcom.ac_if;
-
- reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
-
- if (ifp->if_flags & IFF_PROMISC) {
- reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
- E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
-#ifndef __rtems__
- /* Disable VLAN stripping in promiscous mode
- * This enables bridging of vlan tagged frames to occur
- * and also allows vlan tags to be seen in tcpdump
- */
- if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
- em_disable_vlans(adapter);
- adapter->em_insert_vlan_header = 1;
-#endif
- } else if (ifp->if_flags & IFF_ALLMULTI) {
- reg_rctl |= E1000_RCTL_MPE;
- reg_rctl &= ~E1000_RCTL_UPE;
- E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
-#ifndef __rtems__
- adapter->em_insert_vlan_header = 0;
- } else
- adapter->em_insert_vlan_header = 0;
-#else
- }
-#endif
-
- return;
-}
-
-static void
-em_disable_promisc(struct adapter * adapter)
-{
- u_int32_t reg_rctl;
-#ifndef __rtems__
- struct ifnet *ifp = adapter->ifp;
-#endif
-
- reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
-
- reg_rctl &= (~E1000_RCTL_UPE);
- reg_rctl &= (~E1000_RCTL_MPE);
- E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
-
-#ifndef __rtems__
- if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
- em_enable_vlans(adapter);
- adapter->em_insert_vlan_header = 0;
-#endif
-
- return;
-}
-
-
-/*********************************************************************
- * Multicast Update
- *
- * This routine is called whenever multicast address list is updated.
- *
- **********************************************************************/
-
-static void
-em_set_multi(struct adapter * adapter)
-{
- u_int32_t reg_rctl = 0;
- u_int8_t mta[MAX_NUM_MULTICAST_ADDRESSES * ETH_LENGTH_OF_ADDRESS];
-#ifndef __rtems__
- struct ifmultiaddr *ifma;
-#endif
- int mcnt = 0;
- struct ifnet *ifp = &adapter->arpcom.ac_if;
-
- IOCTL_DEBUGOUT("em_set_multi: begin");
-
- if (adapter->hw.mac_type == em_82542_rev2_0) {
- reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
- if (adapter->hw.pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
- em_pci_clear_mwi(&adapter->hw);
- }
- reg_rctl |= E1000_RCTL_RST;
- E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
- msec_delay(5);
- }
-
-#ifndef __rtems__
- IF_ADDR_LOCK(ifp);
-#if __FreeBSD_version < 500000
- LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
-#else
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
-#endif
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
-
- if (mcnt == MAX_NUM_MULTICAST_ADDRESSES) break;
-
- bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
- &mta[mcnt*ETH_LENGTH_OF_ADDRESS], ETH_LENGTH_OF_ADDRESS);
- mcnt++;
- }
- IF_ADDR_UNLOCK(ifp);
-#else
- {
- /* Don't know how to handle address ranges - we warn and ignore
- * for now...
- */
- struct ether_multi *enm;
- struct ether_multistep step;
-
- ETHER_FIRST_MULTI(step, (struct arpcom*)ifp, enm);
- while ( enm != NULL ) {
- if ( mcnt == MAX_NUM_MULTICAST_ADDRESSES )
- break;
- if ( memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN) ) {
- printk("if_em: Unable to handle multicast wildcard (not ported yet); skipping/ignoring\n");
- goto skiptonext;
- } else {
- bcopy(enm->enm_addrlo, &mta[mcnt * ETHER_ADDR_LEN], ETHER_ADDR_LEN);
- }
- mcnt++;
-skiptonext:
- ETHER_NEXT_MULTI( step, enm );
- }
- }
-#endif
-
- if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) {
- reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
- reg_rctl |= E1000_RCTL_MPE;
- E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
- } else
- em_mc_addr_list_update(&adapter->hw, mta, mcnt, 0, 1);
-
- if (adapter->hw.mac_type == em_82542_rev2_0) {
- reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
- reg_rctl &= ~E1000_RCTL_RST;
- E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
- msec_delay(5);
- if (adapter->hw.pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
- em_pci_set_mwi(&adapter->hw);
- }
- }
-
- return;
-}
-
-#ifndef __rtems__
-/*********************************************************************
- * Timer routine
- *
- * This routine checks for link status and updates statistics.
- *
- **********************************************************************/
-
-static void
-em_local_timer(void *arg)
-{
- struct ifnet *ifp;
- struct adapter * adapter = arg;
- ifp = &adapter->arpcom.ac_if;
-
- EM_LOCK(adapter);
-
- em_check_for_link(&adapter->hw);
- em_print_link_status(adapter);
- em_update_stats_counters(adapter);
- if (em_display_debug_stats && ifp->if_flags & IFF_RUNNING) {
- em_print_hw_stats(adapter);
- }
- em_smartspeed(adapter);
-
- callout_reset(&adapter->timer, hz, em_local_timer, adapter);
-
- EM_UNLOCK(adapter);
- return;
-}
-#endif
-
-static void
-em_print_link_status(struct adapter * adapter)
-{
-#ifndef __rtems__
- struct ifnet *ifp = &adapter->arpcom.ac_if;
-#endif
-
- if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) {
- if (adapter->link_active == 0) {
- em_get_speed_and_duplex(&adapter->hw,
- &adapter->link_speed,
- &adapter->link_duplex);
- if (bootverbose)
- printf("em%d: Link is up %d Mbps %s\n",
- adapter->unit,
- adapter->link_speed,
- ((adapter->link_duplex == FULL_DUPLEX) ?
- "Full Duplex" : "Half Duplex"));
- adapter->link_active = 1;
- adapter->smartspeed = 0;
-#ifndef __rtems__
- if_link_state_change(ifp, LINK_STATE_UP);
-#endif
- }
- } else {
- if (adapter->link_active == 1) {
- adapter->link_speed = 0;
- adapter->link_duplex = 0;
- if (bootverbose)
- printf("em%d: Link is Down\n", adapter->unit);
- adapter->link_active = 0;
-#ifndef __rtems__
- if_link_state_change(ifp, LINK_STATE_UP);
- if_link_state_change(ifp, LINK_STATE_DOWN);
-#endif
- }
- }
-
- return;
-}
-
-/*********************************************************************
- *
- * This routine disables all traffic on the adapter by issuing a
- * global reset on the MAC and deallocates TX/RX buffers.
- *
- **********************************************************************/
-
-static void
-em_stop(void *arg)
-{
- struct ifnet *ifp;
- struct adapter * adapter = arg;
- ifp = &adapter->arpcom.ac_if;
-
- mtx_assert(&adapter->mtx, MA_OWNED);
-
- INIT_DEBUGOUT("em_stop: begin");
-#ifdef DEVICE_POLLING
- ether_poll_deregister(ifp);
-#endif
- em_disable_intr(adapter);
- em_reset_hw(&adapter->hw);
- callout_stop(&adapter->timer);
- callout_stop(&adapter->tx_fifo_timer);
- em_free_transmit_structures(adapter);
- em_free_receive_structures(adapter);
-
-
- /* Tell the stack that the interface is no longer active */
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-
- return;
-}
-
-
-/*********************************************************************
- *
- * Determine hardware revision.
- *
- **********************************************************************/
-static void
-em_identify_hardware(struct adapter * adapter)
-{
- device_t dev = adapter->dev;
-
- /* Make sure our PCI config space has the necessary stuff set */
- adapter->hw.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
- if (!((adapter->hw.pci_cmd_word & PCIM_CMD_BUSMASTEREN) &&
- (adapter->hw.pci_cmd_word & PCIM_CMD_MEMEN))) {
- printf("em%d: Memory Access and/or Bus Master bits were not set!\n",
- adapter->unit);
- adapter->hw.pci_cmd_word |=
- (PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
- pci_write_config(dev, PCIR_COMMAND, adapter->hw.pci_cmd_word, 2);
- }
-
- /* Save off the information about this board */
- adapter->hw.vendor_id = pci_get_vendor(dev);
- adapter->hw.device_id = pci_get_device(dev);
- adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1);
- adapter->hw.subsystem_vendor_id = pci_read_config(dev, PCIR_SUBVEND_0, 2);
- adapter->hw.subsystem_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
-
- /* Identify the MAC */
- if (em_set_mac_type(&adapter->hw))
- printf("em%d: Unknown MAC Type\n", adapter->unit);
-
- if(adapter->hw.mac_type == em_82541 ||
- adapter->hw.mac_type == em_82541_rev_2 ||
- adapter->hw.mac_type == em_82547 ||
- adapter->hw.mac_type == em_82547_rev_2)
- adapter->hw.phy_init_script = TRUE;
-
- return;
-}
-
-static int
-em_allocate_pci_resources(struct adapter * adapter)
-{
- int i, val, rid;
- device_t dev = adapter->dev;
-
- rid = EM_MMBA;
-
-#ifndef __rtems__
- adapter->res_memory = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &rid, RF_ACTIVE);
- if (!(adapter->res_memory)) {
- printf("em%d: Unable to allocate bus resource: memory\n",
- adapter->unit);
- return(ENXIO);
- }
- adapter->osdep.mem_bus_space_tag =
- rman_get_bustag(adapter->res_memory);
- adapter->osdep.mem_bus_space_handle =
- rman_get_bushandle(adapter->res_memory);
-#endif
-
- adapter->hw.hw_addr = (uint8_t *)&adapter->osdep.mem_bus_space_handle;
-
-
- if (adapter->hw.mac_type > em_82543) {
- /* Figure our where our IO BAR is ? */
- rid = EM_MMBA;
- for (i = 0; i < 5; i++) {
- val = pci_read_config(dev, rid, 4);
- if (val & 0x00000001) {
-#ifndef __rtems__
- adapter->io_rid = rid;
-#endif
- break;
- }
- rid += 4;
- }
-
-#ifndef __rtems__
- adapter->res_ioport = bus_alloc_resource_any(dev,
- SYS_RES_IOPORT,
- &adapter->io_rid,
- RF_ACTIVE);
- if (!(adapter->res_ioport)) {
- printf("em%d: Unable to allocate bus resource: ioport\n",
- adapter->unit);
- return(ENXIO);
- }
-
- adapter->hw.io_base =
- rman_get_start(adapter->res_ioport);
-#else
- adapter->hw.io_base = val & PCI_BASE_ADDRESS_IO_MASK;
-#endif
- }
-
-#ifndef __rtems__
- rid = 0x0;
- adapter->res_interrupt = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE |
- RF_ACTIVE);
- if (!(adapter->res_interrupt)) {
- printf("em%d: Unable to allocate bus resource: interrupt\n",
- adapter->unit);
- return(ENXIO);
- }
- if (bus_setup_intr(dev, adapter->res_interrupt,
- INTR_TYPE_NET | INTR_MPSAFE,
- (void (*)(void *)) em_intr, adapter,
- &adapter->int_handler_tag)) {
- printf("em%d: Error registering interrupt handler!\n",
- adapter->unit);
- return(ENXIO);
- }
-#endif
-
- adapter->hw.back = &adapter->osdep;
-
- return(0);
-}
-
-#ifndef __rtems__
-static void
-em_free_pci_resources(struct adapter * adapter)
-{
- device_t dev = adapter->dev;
-
- if (adapter->res_interrupt != NULL) {
- bus_teardown_intr(dev, adapter->res_interrupt,
- adapter->int_handler_tag);
- bus_release_resource(dev, SYS_RES_IRQ, 0,
- adapter->res_interrupt);
- }
- if (adapter->res_memory != NULL) {
- bus_release_resource(dev, SYS_RES_MEMORY, EM_MMBA,
- adapter->res_memory);
- }
-
- if (adapter->res_ioport != NULL) {
- bus_release_resource(dev, SYS_RES_IOPORT, adapter->io_rid,
- adapter->res_ioport);
- }
- return;
-}
-#endif
-
-/*********************************************************************
- *
- * Initialize the hardware to a configuration as specified by the
- * adapter structure. The controller is reset, the EEPROM is
- * verified, the MAC address is set, then the shared initialization
- * routines are called.
- *
- **********************************************************************/
-static int
-em_hardware_init(struct adapter * adapter)
-{
- INIT_DEBUGOUT("em_hardware_init: begin");
- /* Issue a global reset */
- em_reset_hw(&adapter->hw);
-
- /* When hardware is reset, fifo_head is also reset */
- adapter->tx_fifo_head = 0;
-
- /* Make sure we have a good EEPROM before we read from it */
- if (em_validate_eeprom_checksum(&adapter->hw) < 0) {
- printf("em%d: The EEPROM Checksum Is Not Valid\n",
- adapter->unit);
- return(EIO);
- }
-
- if (em_read_part_num(&adapter->hw, &(adapter->part_num)) < 0) {
- printf("em%d: EEPROM read error while reading part number\n",
- adapter->unit);
- return(EIO);
- }
-
- if (em_init_hw(&adapter->hw) < 0) {
- printf("em%d: Hardware Initialization Failed",
- adapter->unit);
- return(EIO);
- }
-
- em_check_for_link(&adapter->hw);
- if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)
- adapter->link_active = 1;
- else
- adapter->link_active = 0;
-
- if (adapter->link_active) {
- em_get_speed_and_duplex(&adapter->hw,
- &adapter->link_speed,
- &adapter->link_duplex);
- } else {
- adapter->link_speed = 0;
- adapter->link_duplex = 0;
- }
-
- return(0);
-}
-
-/*********************************************************************
- *
- * Setup networking device structure and register an interface.
- *
- **********************************************************************/
-static void
-em_setup_interface(device_t dev, struct adapter * adapter)
-{
- struct ifnet *ifp = &device_get_softc(dev)->arpcom.ac_if;
- INIT_DEBUGOUT("em_setup_interface: begin");
-
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_mtu = ETHERMTU;
- ifp->if_baudrate = 1000000000;
- ifp->if_init = em_init;
- ifp->if_softc = adapter;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-#ifdef __rtems__
- ifp->if_output = ether_output;
-#endif
- ifp->if_ioctl = em_ioctl;
- ifp->if_start = em_start;
- ifp->if_watchdog = em_watchdog;
-#ifndef __rtems__
- IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 1);
- ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 1;
- IFQ_SET_READY(&ifp->if_snd);
-#else
- ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 1;
-#endif
-
-#ifndef __rtems__
-#if __FreeBSD_version < 500000
- ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
-#else
- ether_ifattach(ifp, adapter->hw.mac_addr);
-#endif
-#else
- if ( !ifp->if_addrlist ) /* reattach hack */
- {
- if_attach(ifp);
- ether_ifattach(ifp);
- }
-#endif
-
-#ifndef __rtems__
- ifp->if_capabilities = ifp->if_capenable = 0;
-
- if (adapter->hw.mac_type >= em_82543) {
- ifp->if_capabilities |= IFCAP_HWCSUM;
- ifp->if_capenable |= IFCAP_HWCSUM;
- }
-
- /*
- * Tell the upper layer(s) we support long frames.
- */
- ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
-#if __FreeBSD_version >= 500000
- ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
- ifp->if_capenable |= IFCAP_VLAN_MTU;
-#endif
-
-#ifdef DEVICE_POLLING
- ifp->if_capabilities |= IFCAP_POLLING;
- ifp->if_capenable |= IFCAP_POLLING;
-#endif
-
- /*
- * Specify the media types supported by this adapter and register
- * callbacks to update media and link information
- */
- ifmedia_init(&adapter->media, IFM_IMASK, em_media_change,
- em_media_status);
- if (adapter->hw.media_type == em_media_type_fiber) {
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX | IFM_FDX,
- 0, NULL);
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX,
- 0, NULL);
- } else {
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T, 0, NULL);
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T | IFM_FDX,
- 0, NULL);
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX,
- 0, NULL);
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX | IFM_FDX,
- 0, NULL);
-#if __FreeBSD_version < 500000
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_TX | IFM_FDX,
- 0, NULL);
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_TX, 0, NULL);
-#else
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T | IFM_FDX,
- 0, NULL);
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T, 0, NULL);
-#endif
- }
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
- ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
-#endif
-
- return;
-}
-
-#ifndef __rtems__
-/*********************************************************************
- *
- * Workaround for SmartSpeed on 82541 and 82547 controllers
- *
- **********************************************************************/
-static void
-em_smartspeed(struct adapter *adapter)
-{
- uint16_t phy_tmp;
-
- if(adapter->link_active || (adapter->hw.phy_type != em_phy_igp) ||
- !adapter->hw.autoneg || !(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL))
- return;
-
- if(adapter->smartspeed == 0) {
- /* If Master/Slave config fault is asserted twice,
- * we assume back-to-back */
- em_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
- if(!(phy_tmp & SR_1000T_MS_CONFIG_FAULT)) return;
- em_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
- if(phy_tmp & SR_1000T_MS_CONFIG_FAULT) {
- em_read_phy_reg(&adapter->hw, PHY_1000T_CTRL,
- &phy_tmp);
- if(phy_tmp & CR_1000T_MS_ENABLE) {
- phy_tmp &= ~CR_1000T_MS_ENABLE;
- em_write_phy_reg(&adapter->hw,
- PHY_1000T_CTRL, phy_tmp);
- adapter->smartspeed++;
- if(adapter->hw.autoneg &&
- !em_phy_setup_autoneg(&adapter->hw) &&
- !em_read_phy_reg(&adapter->hw, PHY_CTRL,
- &phy_tmp)) {
- phy_tmp |= (MII_CR_AUTO_NEG_EN |
- MII_CR_RESTART_AUTO_NEG);
- em_write_phy_reg(&adapter->hw,
- PHY_CTRL, phy_tmp);
- }
- }
- }
- return;
- } else if(adapter->smartspeed == EM_SMARTSPEED_DOWNSHIFT) {
- /* If still no link, perhaps using 2/3 pair cable */
- em_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_tmp);
- phy_tmp |= CR_1000T_MS_ENABLE;
- em_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_tmp);
- if(adapter->hw.autoneg &&
- !em_phy_setup_autoneg(&adapter->hw) &&
- !em_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_tmp)) {
- phy_tmp |= (MII_CR_AUTO_NEG_EN |
- MII_CR_RESTART_AUTO_NEG);
- em_write_phy_reg(&adapter->hw, PHY_CTRL, phy_tmp);
- }
- }
- /* Restart process after EM_SMARTSPEED_MAX iterations */
- if(adapter->smartspeed++ == EM_SMARTSPEED_MAX)
- adapter->smartspeed = 0;
-
- return;
-}
-
-
-/*
- * Manage DMA'able memory.
- */
-static void
-em_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- if (error)
- return;
- *(bus_addr_t*) arg = segs->ds_addr;
- return;
-}
-#endif
-
-static int
-em_dma_malloc(struct adapter *adapter, bus_size_t size,
- struct em_dma_alloc *dma, int mapflags)
-{
- int r;
-
-#ifndef __rtems__
- r = bus_dma_tag_create(NULL, /* parent */
- PAGE_SIZE, 0, /* alignment, bounds */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- size, /* maxsize */
- 1, /* nsegments */
- size, /* maxsegsize */
- BUS_DMA_ALLOCNOW, /* flags */
- NULL, /* lockfunc */
- NULL, /* lockarg */
- &dma->dma_tag);
- if (r != 0) {
- printf("em%d: em_dma_malloc: bus_dma_tag_create failed; "
- "error %u\n", adapter->unit, r);
- goto fail_0;
- }
-
- r = bus_dmamem_alloc(dma->dma_tag, (void**) &dma->dma_vaddr,
- BUS_DMA_NOWAIT, &dma->dma_map);
-#else
- if ( (dma->malloc_base = malloc( size + PAGE_SIZE, M_DEVBUF, M_NOWAIT )) ) {
- r = 0;
- dma->dma_vaddr = (caddr_t)_DO_ALIGN(dma->malloc_base, PAGE_SIZE);
- } else {
- r = -1;
- }
-#endif
- if (r != 0) {
-#ifndef __rtems__
- printf("em%d: em_dma_malloc: bus_dmammem_alloc failed; "
- "size %ju, error %d\n", adapter->unit,
- (uintmax_t)size, r);
-#else
- printf("em%d: em_dma_malloc: bus_dmammem_alloc failed; "
- "size %u, error %d\n", adapter->unit,
- size, r);
-#endif
- goto fail_2;
- }
-
-#ifndef __rtems__
- r = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr,
- size,
- em_dmamap_cb,
- &dma->dma_paddr,
- mapflags | BUS_DMA_NOWAIT);
-#else
- dma->dma_paddr = kvtop(dma->dma_vaddr);
-#endif
- if (r != 0) {
- printf("em%d: em_dma_malloc: bus_dmamap_load failed; "
- "error %u\n", adapter->unit, r);
- goto fail_3;
- }
-
-#ifndef __rtems__
- dma->dma_size = size;
-#endif
- return (0);
-
-fail_3:
- bus_dmamap_unload(dma->dma_tag, dma->dma_map);
-fail_2:
-#ifndef __rtems__
- bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
-#else
- free(dma->malloc_base, M_DEVBUF);
- dma->dma_vaddr = dma->malloc_base = 0;
- dma->dma_paddr = 0;
-#endif
- bus_dma_tag_destroy(dma->dma_tag);
-#ifndef __rtems__
-fail_0:
- dma->dma_map = NULL;
- dma->dma_tag = NULL;
-#endif
- return (r);
-}
-
-static void
-em_dma_free(struct adapter *adapter, struct em_dma_alloc *dma)
-{
- bus_dmamap_unload(dma->dma_tag, dma->dma_map);
-#ifndef __rtems__
- bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
-#else
- free(dma->malloc_base, M_DEVBUF);
- dma->dma_vaddr = dma->malloc_base = 0;
- dma->dma_paddr = 0;
-#endif
- bus_dma_tag_destroy(dma->dma_tag);
-}
-
-
-/*********************************************************************
- *
- * Allocate memory for tx_buffer structures. The tx_buffer stores all
- * the information needed to transmit a packet on the wire.
- *
- **********************************************************************/
-static int
-em_allocate_transmit_structures(struct adapter * adapter)
-{
- if (!(adapter->tx_buffer_area =
- (struct em_buffer *) malloc(sizeof(struct em_buffer) *
- adapter->num_tx_desc, M_DEVBUF,
- M_NOWAIT))) {
- printf("em%d: Unable to allocate tx_buffer memory\n",
- adapter->unit);
- return ENOMEM;
- }
-
- bzero(adapter->tx_buffer_area,
- sizeof(struct em_buffer) * adapter->num_tx_desc);
-
- return 0;
-}
-
-/*********************************************************************
- *
- * Allocate and initialize transmit structures.
- *
- **********************************************************************/
-static int
-em_setup_transmit_structures(struct adapter * adapter)
-{
-#ifndef __rtems__
- /*
- * Setup DMA descriptor areas.
- */
- if (bus_dma_tag_create(NULL, /* parent */
- 1, 0, /* alignment, bounds */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MCLBYTES * 8, /* maxsize */
- EM_MAX_SCATTER, /* nsegments */
- MCLBYTES * 8, /* maxsegsize */
- BUS_DMA_ALLOCNOW, /* flags */
- NULL, /* lockfunc */
- NULL, /* lockarg */
- &adapter->txtag)) {
- printf("em%d: Unable to allocate TX DMA tag\n", adapter->unit);
- return (ENOMEM);
- }
-#endif
-
- if (em_allocate_transmit_structures(adapter))
- return (ENOMEM);
-
- bzero((void *) adapter->tx_desc_base,
- (sizeof(struct em_tx_desc)) * adapter->num_tx_desc);
-
- adapter->next_avail_tx_desc = 0;
- adapter->oldest_used_tx_desc = 0;
-
- /* Set number of descriptors available */
- adapter->num_tx_desc_avail = adapter->num_tx_desc;
-
- /* Set checksum context */
- adapter->active_checksum_context = OFFLOAD_NONE;
-
- return (0);
-}
-
-/*********************************************************************
- *
- * Enable transmit unit.
- *
- **********************************************************************/
-static void
-em_initialize_transmit_unit(struct adapter * adapter)
-{
- u_int32_t reg_tctl;
- u_int32_t reg_tipg = 0;
- u_int64_t bus_addr;
-
- INIT_DEBUGOUT("em_initialize_transmit_unit: begin");
- /* Setup the Base and Length of the Tx Descriptor Ring */
- bus_addr = adapter->txdma.dma_paddr;
- E1000_WRITE_REG(&adapter->hw, TDBAL, (u_int32_t)bus_addr);
- E1000_WRITE_REG(&adapter->hw, TDBAH, (u_int32_t)(bus_addr >> 32));
- E1000_WRITE_REG(&adapter->hw, TDLEN,
- adapter->num_tx_desc *
- sizeof(struct em_tx_desc));
-
- /* Setup the HW Tx Head and Tail descriptor pointers */
- E1000_WRITE_REG(&adapter->hw, TDH, 0);
- E1000_WRITE_REG(&adapter->hw, TDT, 0);
-
-
- HW_DEBUGOUT2("Base = %" PRIx32 ", Length = %" PRIx32 "\n",
- E1000_READ_REG(&adapter->hw, TDBAL),
- E1000_READ_REG(&adapter->hw, TDLEN));
-
- /* Set the default values for the Tx Inter Packet Gap timer */
- switch (adapter->hw.mac_type) {
- case em_82542_rev2_0:
- case em_82542_rev2_1:
- reg_tipg = DEFAULT_82542_TIPG_IPGT;
- reg_tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
- reg_tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
- break;
- default:
- if (adapter->hw.media_type == em_media_type_fiber)
- reg_tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
- else
- reg_tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
- reg_tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
- reg_tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
- }
-
- E1000_WRITE_REG(&adapter->hw, TIPG, reg_tipg);
- E1000_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay.value);
- if(adapter->hw.mac_type >= em_82540)
- E1000_WRITE_REG(&adapter->hw, TADV,
- adapter->tx_abs_int_delay.value);
-
- /* Program the Transmit Control Register */
- reg_tctl = E1000_TCTL_PSP | E1000_TCTL_EN |
- (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
- if (adapter->hw.mac_type >= em_82573)
- reg_tctl |= E1000_TCTL_MULR;
- if (adapter->link_duplex == 1) {
- reg_tctl |= E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT;
- } else {
- reg_tctl |= E1000_HDX_COLLISION_DISTANCE << E1000_COLD_SHIFT;
- }
- E1000_WRITE_REG(&adapter->hw, TCTL, reg_tctl);
-
- /* Setup Transmit Descriptor Settings for this adapter */
- adapter->txd_cmd = E1000_TXD_CMD_IFCS | E1000_TXD_CMD_RS;
-
- if (adapter->tx_int_delay.value > 0)
- adapter->txd_cmd |= E1000_TXD_CMD_IDE;
-
- return;
-}
-
-/*********************************************************************
- *
- * Free all transmit related data structures.
- *
- **********************************************************************/
-static void
-em_free_transmit_structures(struct adapter * adapter)
-{
- struct em_buffer *tx_buffer;
- int i;
-
- INIT_DEBUGOUT("free_transmit_structures: begin");
-
- if (adapter->tx_buffer_area != NULL) {
- tx_buffer = adapter->tx_buffer_area;
- for (i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
- if (tx_buffer->m_head != NULL) {
- bus_dmamap_unload(adapter->txtag, tx_buffer->map);
- bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
- m_freem(tx_buffer->m_head);
- }
- tx_buffer->m_head = NULL;
- }
- }
- if (adapter->tx_buffer_area != NULL) {
- free(adapter->tx_buffer_area, M_DEVBUF);
- adapter->tx_buffer_area = NULL;
- }
-#ifndef __rtems__
- if (adapter->txtag != NULL) {
- bus_dma_tag_destroy(adapter->txtag);
- adapter->txtag = NULL;
- }
-#endif
- return;
-}
-
-#ifndef __rtems__
-/*********************************************************************
- *
- * The offload context needs to be set when we transfer the first
- * packet of a particular protocol (TCP/UDP). We change the
- * context only if the protocol type changes.
- *
- **********************************************************************/
-static void
-em_transmit_checksum_setup(struct adapter * adapter,
- struct mbuf *mp,
- u_int32_t *txd_upper,
- u_int32_t *txd_lower)
-{
- struct em_context_desc *TXD;
- struct em_buffer *tx_buffer;
- int curr_txd;
-
- if (mp->m_pkthdr.csum_flags) {
-
- if (mp->m_pkthdr.csum_flags & CSUM_TCP) {
- *txd_upper = E1000_TXD_POPTS_TXSM << 8;
- *txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
- if (adapter->active_checksum_context == OFFLOAD_TCP_IP)
- return;
- else
- adapter->active_checksum_context = OFFLOAD_TCP_IP;
-
- } else if (mp->m_pkthdr.csum_flags & CSUM_UDP) {
- *txd_upper = E1000_TXD_POPTS_TXSM << 8;
- *txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
- if (adapter->active_checksum_context == OFFLOAD_UDP_IP)
- return;
- else
- adapter->active_checksum_context = OFFLOAD_UDP_IP;
- } else {
- *txd_upper = 0;
- *txd_lower = 0;
- return;
- }
- } else {
- *txd_upper = 0;
- *txd_lower = 0;
- return;
- }
-
- /* If we reach this point, the checksum offload context
- * needs to be reset.
- */
- curr_txd = adapter->next_avail_tx_desc;
- tx_buffer = &adapter->tx_buffer_area[curr_txd];
- TXD = (struct em_context_desc *) &adapter->tx_desc_base[curr_txd];
-
- TXD->lower_setup.ip_fields.ipcss = ETHER_HDR_LEN;
- TXD->lower_setup.ip_fields.ipcso =
- ETHER_HDR_LEN + offsetof(struct ip, ip_sum);
- TXD->lower_setup.ip_fields.ipcse =
- htole16(ETHER_HDR_LEN + sizeof(struct ip) - 1);
-
- TXD->upper_setup.tcp_fields.tucss =
- ETHER_HDR_LEN + sizeof(struct ip);
- TXD->upper_setup.tcp_fields.tucse = htole16(0);
-
- if (adapter->active_checksum_context == OFFLOAD_TCP_IP) {
- TXD->upper_setup.tcp_fields.tucso =
- ETHER_HDR_LEN + sizeof(struct ip) +
- offsetof(struct tcphdr, th_sum);
- } else if (adapter->active_checksum_context == OFFLOAD_UDP_IP) {
- TXD->upper_setup.tcp_fields.tucso =
- ETHER_HDR_LEN + sizeof(struct ip) +
- offsetof(struct udphdr, uh_sum);
- }
-
- TXD->tcp_seg_setup.data = htole32(0);
- TXD->cmd_and_length = htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT);
-
- tx_buffer->m_head = NULL;
-
- if (++curr_txd == adapter->num_tx_desc)
- curr_txd = 0;
-
- adapter->num_tx_desc_avail--;
- adapter->next_avail_tx_desc = curr_txd;
-
- return;
-}
-#endif
-
-/**********************************************************************
- *
- * Examine each tx_buffer in the used queue. If the hardware is done
- * processing the packet then free associated resources. The
- * tx_buffer is put back on the free queue.
- *
- **********************************************************************/
-static void
-em_clean_transmit_interrupts(struct adapter * adapter)
-{
- int i, num_avail;
- struct em_buffer *tx_buffer;
- struct em_tx_desc *tx_desc;
- struct ifnet *ifp = &adapter->arpcom.ac_if;
-
- mtx_assert(&adapter->mtx, MA_OWNED);
-
- if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
- return;
-
- num_avail = adapter->num_tx_desc_avail;
- i = adapter->oldest_used_tx_desc;
-
- tx_buffer = &adapter->tx_buffer_area[i];
- tx_desc = &adapter->tx_desc_base[i];
-
- bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
- BUS_DMASYNC_POSTREAD);
- while (tx_desc->upper.fields.status & E1000_TXD_STAT_DD) {
-
- tx_desc->upper.data = 0;
- num_avail++;
-
- if (tx_buffer->m_head) {
- ifp->if_opackets++;
- bus_dmamap_unload(adapter->txtag, tx_buffer->map);
- bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
-
- m_freem(tx_buffer->m_head);
- tx_buffer->m_head = NULL;
- }
-
- if (++i == adapter->num_tx_desc)
- i = 0;
-
- tx_buffer = &adapter->tx_buffer_area[i];
- tx_desc = &adapter->tx_desc_base[i];
- }
- bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-
- adapter->oldest_used_tx_desc = i;
-
- /*
- * If we have enough room, clear IFF_OACTIVE to tell the stack
- * that it is OK to send packets.
- * If there are no pending descriptors, clear the timeout. Otherwise,
- * if some descriptors have been freed, restart the timeout.
- */
- if (num_avail > EM_TX_CLEANUP_THRESHOLD) {
- ifp->if_flags &= ~IFF_OACTIVE;
- if (num_avail == adapter->num_tx_desc)
- ifp->if_timer = 0;
- else if (num_avail == adapter->num_tx_desc_avail)
- ifp->if_timer = EM_TX_TIMEOUT;
- }
- adapter->num_tx_desc_avail = num_avail;
- return;
-}
-
-/*********************************************************************
- *
- * Get a buffer from system mbuf buffer pool.
- *
- **********************************************************************/
-static int
-em_get_buf(int i, struct adapter *adapter,
- struct mbuf *nmp)
-{
- register struct mbuf *mp = nmp;
- struct em_buffer *rx_buffer;
- struct ifnet *ifp;
- bus_addr_t paddr;
-#ifndef __rtems__
- int error;
-#endif
-
- ifp = &adapter->arpcom.ac_if;
-
- if (mp == NULL) {
-#ifndef __rtems__
- mp = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-#else
- MGETHDR(mp, M_DONTWAIT, MT_DATA);
- if ( mp ) {
- MCLGET( mp, M_DONTWAIT );
- if ( !(mp->m_flags & M_EXT) ) {
- m_freem(mp);
- mp = 0;
- }
- }
-#endif
- if (mp == NULL) {
- adapter->mbuf_cluster_failed++;
- return(ENOBUFS);
- }
- mp->m_len = mp->m_pkthdr.len = MCLBYTES;
- } else {
- mp->m_len = mp->m_pkthdr.len = MCLBYTES;
- mp->m_data = mp->m_ext.ext_buf;
- mp->m_next = NULL;
- }
-
- if (ifp->if_mtu <= ETHERMTU) {
- m_adj(mp, ETHER_ALIGN);
- }
-
- rx_buffer = &adapter->rx_buffer_area[i];
-
-#ifndef __rtems__
- /*
- * Using memory from the mbuf cluster pool, invoke the
- * bus_dma machinery to arrange the memory mapping.
- */
- error = bus_dmamap_load(adapter->rxtag, rx_buffer->map,
- mtod(mp, void *), mp->m_len,
- em_dmamap_cb, &paddr, 0);
- if (error) {
- m_free(mp);
- return(error);
- }
-#else
- paddr = kvtop(mtod(mp, void*));
-#endif
-
- rx_buffer->m_head = mp;
- adapter->rx_desc_base[i].buffer_addr = htole64(paddr);
- bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD);
-
- return(0);
-}
-
-/*********************************************************************
- *
- * Allocate memory for rx_buffer structures. Since we use one
- * rx_buffer per received packet, the maximum number of rx_buffer's
- * that we'll need is equal to the number of receive descriptors
- * that we've allocated.
- *
- **********************************************************************/
-static int
-em_allocate_receive_structures(struct adapter * adapter)
-{
- int i, error;
-#ifndef __rtems__
- struct em_buffer *rx_buffer;
-#endif
-
- if (!(adapter->rx_buffer_area =
- (struct em_buffer *) malloc(sizeof(struct em_buffer) *
- adapter->num_rx_desc, M_DEVBUF,
- M_NOWAIT))) {
- printf("em%d: Unable to allocate rx_buffer memory\n",
- adapter->unit);
- return(ENOMEM);
- }
-
- bzero(adapter->rx_buffer_area,
- sizeof(struct em_buffer) * adapter->num_rx_desc);
-
-#ifndef __rtems__
- error = bus_dma_tag_create(NULL, /* parent */
- 1, 0, /* alignment, bounds */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MCLBYTES, /* maxsize */
- 1, /* nsegments */
- MCLBYTES, /* maxsegsize */
- BUS_DMA_ALLOCNOW, /* flags */
- NULL, /* lockfunc */
- NULL, /* lockarg */
- &adapter->rxtag);
- if (error != 0) {
- printf("em%d: em_allocate_receive_structures: "
- "bus_dma_tag_create failed; error %u\n",
- adapter->unit, error);
- goto fail_0;
- }
- rx_buffer = adapter->rx_buffer_area;
- for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
- error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
- &rx_buffer->map);
- if (error != 0) {
- printf("em%d: em_allocate_receive_structures: "
- "bus_dmamap_create failed; error %u\n",
- adapter->unit, error);
- goto fail_1;
- }
- }
-
-#else
- error = 0;
-#endif
-
- for (i = 0; i < adapter->num_rx_desc; i++) {
- error = em_get_buf(i, adapter, NULL);
- if (error != 0) {
- adapter->rx_buffer_area[i].m_head = NULL;
- adapter->rx_desc_base[i].buffer_addr = 0;
- return(error);
- }
- }
- bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-
- return(0);
-
-#ifndef __rtems__
-fail_1:
- bus_dma_tag_destroy(adapter->rxtag);
-fail_0:
- adapter->rxtag = NULL;
-#endif
- free(adapter->rx_buffer_area, M_DEVBUF);
- adapter->rx_buffer_area = NULL;
- return (error);
-}
-
-/*********************************************************************
- *
- * Allocate and initialize receive structures.
- *
- **********************************************************************/
-static int
-em_setup_receive_structures(struct adapter * adapter)
-{
- bzero((void *) adapter->rx_desc_base,
- (sizeof(struct em_rx_desc)) * adapter->num_rx_desc);
-
- if (em_allocate_receive_structures(adapter))
- return ENOMEM;
-
- /* Setup our descriptor pointers */
- adapter->next_rx_desc_to_check = 0;
- return(0);
-}
-
-/*********************************************************************
- *
- * Enable receive unit.
- *
- **********************************************************************/
-static void
-em_initialize_receive_unit(struct adapter * adapter)
-{
- u_int32_t reg_rctl;
-#ifndef __rtems__
- u_int32_t reg_rxcsum;
-#endif
- struct ifnet *ifp;
- u_int64_t bus_addr;
-
- INIT_DEBUGOUT("em_initialize_receive_unit: begin");
- ifp = &adapter->arpcom.ac_if;
-
- /* Make sure receives are disabled while setting up the descriptor ring */
- E1000_WRITE_REG(&adapter->hw, RCTL, 0);
-
- /* Set the Receive Delay Timer Register */
- E1000_WRITE_REG(&adapter->hw, RDTR,
- adapter->rx_int_delay.value | E1000_RDT_FPDB);
-
- if(adapter->hw.mac_type >= em_82540) {
- E1000_WRITE_REG(&adapter->hw, RADV,
- adapter->rx_abs_int_delay.value);
-
- /* Set the interrupt throttling rate. Value is calculated
- * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */
-#define MAX_INTS_PER_SEC 8000
-#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256)
- E1000_WRITE_REG(&adapter->hw, ITR, DEFAULT_ITR);
- }
-
- /* Setup the Base and Length of the Rx Descriptor Ring */
- bus_addr = adapter->rxdma.dma_paddr;
- E1000_WRITE_REG(&adapter->hw, RDBAL, (u_int32_t)bus_addr);
- E1000_WRITE_REG(&adapter->hw, RDBAH, (u_int32_t)(bus_addr >> 32));
- E1000_WRITE_REG(&adapter->hw, RDLEN, adapter->num_rx_desc *
- sizeof(struct em_rx_desc));
-
- /* Setup the HW Rx Head and Tail Descriptor Pointers */
- E1000_WRITE_REG(&adapter->hw, RDH, 0);
- E1000_WRITE_REG(&adapter->hw, RDT, adapter->num_rx_desc - 1);
-
- /* Setup the Receive Control Register */
- reg_rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
- E1000_RCTL_RDMTS_HALF |
- (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
-
- if (adapter->hw.tbi_compatibility_on == TRUE)
- reg_rctl |= E1000_RCTL_SBP;
-
-
- switch (adapter->rx_buffer_len) {
- default:
- case EM_RXBUFFER_2048:
- reg_rctl |= E1000_RCTL_SZ_2048;
- break;
- case EM_RXBUFFER_4096:
- reg_rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
- break;
- case EM_RXBUFFER_8192:
- reg_rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
- break;
- case EM_RXBUFFER_16384:
- reg_rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
- break;
- }
-
- if (ifp->if_mtu > ETHERMTU)
- reg_rctl |= E1000_RCTL_LPE;
-
-#ifndef __rtems__
- /* Enable 82543 Receive Checksum Offload for TCP and UDP */
- if ((adapter->hw.mac_type >= em_82543) &&
- (ifp->if_capenable & IFCAP_RXCSUM)) {
- reg_rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM);
- reg_rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL);
- E1000_WRITE_REG(&adapter->hw, RXCSUM, reg_rxcsum);
- }
-#endif
-
- /* Enable Receives */
- E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
-
- return;
-}
-
-/*********************************************************************
- *
- * Free receive related data structures.
- *
- **********************************************************************/
-static void
-em_free_receive_structures(struct adapter *adapter)
-{
- struct em_buffer *rx_buffer;
- int i;
-
- INIT_DEBUGOUT("free_receive_structures: begin");
-
- if (adapter->rx_buffer_area != NULL) {
- rx_buffer = adapter->rx_buffer_area;
- for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
-#ifndef __rtems__
- if (rx_buffer->map != NULL) {
- bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
- bus_dmamap_destroy(adapter->rxtag, rx_buffer->map);
- }
-#endif
- if (rx_buffer->m_head != NULL)
- m_freem(rx_buffer->m_head);
- rx_buffer->m_head = NULL;
- }
- }
- if (adapter->rx_buffer_area != NULL) {
- free(adapter->rx_buffer_area, M_DEVBUF);
- adapter->rx_buffer_area = NULL;
- }
-#ifndef __rtems__
- if (adapter->rxtag != NULL) {
- bus_dma_tag_destroy(adapter->rxtag);
- adapter->rxtag = NULL;
- }
-#endif
- return;
-}
-
-/*********************************************************************
- *
- * This routine executes in interrupt context. It replenishes
- * the mbufs in the descriptor and sends data which has been
- * dma'ed into host memory to upper layer.
- *
- * We loop at most count times if count is > 0, or until done if
- * count < 0.
- *
- *********************************************************************/
-static void
-em_process_receive_interrupts(struct adapter * adapter, int count)
-{
- struct ifnet *ifp;
- struct mbuf *mp;
-#if __FreeBSD_version < 500000
- struct ether_header *eh;
-#endif
- u_int8_t accept_frame = 0;
- u_int8_t eop = 0;
- u_int16_t len, desc_len, prev_len_adj;
- int i;
-
- /* Pointer to the receive descriptor being examined. */
- struct em_rx_desc *current_desc;
-
- mtx_assert(&adapter->mtx, MA_OWNED);
-
- ifp = &adapter->arpcom.ac_if;
- i = adapter->next_rx_desc_to_check;
- current_desc = &adapter->rx_desc_base[i];
- bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
- BUS_DMASYNC_POSTREAD);
-
- if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
- return;
- }
-
- while ((current_desc->status & E1000_RXD_STAT_DD) && (count != 0)) {
-
- mp = adapter->rx_buffer_area[i].m_head;
- bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map,
- BUS_DMASYNC_POSTREAD);
-
- accept_frame = 1;
- prev_len_adj = 0;
- desc_len = le16toh(current_desc->length);
- if (current_desc->status & E1000_RXD_STAT_EOP) {
- count--;
- eop = 1;
- if (desc_len < ETHER_CRC_LEN) {
- len = 0;
- prev_len_adj = ETHER_CRC_LEN - desc_len;
- }
- else {
- len = desc_len - ETHER_CRC_LEN;
- }
- } else {
- eop = 0;
- len = desc_len;
- }
-
- if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
- u_int8_t last_byte;
- u_int32_t pkt_len = desc_len;
-
- if (adapter->fmp != NULL)
- pkt_len += adapter->fmp->m_pkthdr.len;
-
- last_byte = *(mtod(mp, caddr_t) + desc_len - 1);
-
- if (TBI_ACCEPT(&adapter->hw, current_desc->status,
- current_desc->errors,
- pkt_len, last_byte)) {
- em_tbi_adjust_stats(&adapter->hw,
- &adapter->stats,
- pkt_len,
- adapter->hw.mac_addr);
- if (len > 0) len--;
- }
- else {
- accept_frame = 0;
- }
- }
-
- if (accept_frame) {
-
- if (em_get_buf(i, adapter, NULL) == ENOBUFS) {
- adapter->dropped_pkts++;
- em_get_buf(i, adapter, mp);
- if (adapter->fmp != NULL)
- m_freem(adapter->fmp);
- adapter->fmp = NULL;
- adapter->lmp = NULL;
- break;
- }
-
- /* Assign correct length to the current fragment */
- mp->m_len = len;
-
- if (adapter->fmp == NULL) {
- mp->m_pkthdr.len = len;
- adapter->fmp = mp; /* Store the first mbuf */
- adapter->lmp = mp;
- } else {
- /* Chain mbuf's together */
- mp->m_flags &= ~M_PKTHDR;
- /*
- * Adjust length of previous mbuf in chain if we
- * received less than 4 bytes in the last descriptor.
- */
- if (prev_len_adj > 0) {
- adapter->lmp->m_len -= prev_len_adj;
- adapter->fmp->m_pkthdr.len -= prev_len_adj;
- }
- adapter->lmp->m_next = mp;
- adapter->lmp = adapter->lmp->m_next;
- adapter->fmp->m_pkthdr.len += len;
- }
-
- if (eop) {
- adapter->fmp->m_pkthdr.rcvif = ifp;
- ifp->if_ipackets++;
-
-#if __FreeBSD_version < 500000
- eh = mtod(adapter->fmp, struct ether_header *);
- /* Remove ethernet header from mbuf */
- m_adj(adapter->fmp, sizeof(struct ether_header));
-#ifndef __rtems__
- em_receive_checksum(adapter, current_desc,
- adapter->fmp);
- if (current_desc->status & E1000_RXD_STAT_VP)
- VLAN_INPUT_TAG(eh, adapter->fmp,
- (current_desc->special &
- E1000_RXD_SPC_VLAN_MASK));
- else
-#endif
- ether_input(ifp, eh, adapter->fmp);
-#else
-
- em_receive_checksum(adapter, current_desc,
- adapter->fmp);
- if (current_desc->status & E1000_RXD_STAT_VP)
- VLAN_INPUT_TAG(ifp, adapter->fmp,
- (current_desc->special &
- E1000_RXD_SPC_VLAN_MASK),
- adapter->fmp = NULL);
-
- if (adapter->fmp != NULL) {
- EM_UNLOCK(adapter);
- (*ifp->if_input)(ifp, adapter->fmp);
- EM_LOCK(adapter);
- }
-#endif
- adapter->fmp = NULL;
- adapter->lmp = NULL;
- }
- } else {
- adapter->dropped_pkts++;
- em_get_buf(i, adapter, mp);
- if (adapter->fmp != NULL)
- m_freem(adapter->fmp);
- adapter->fmp = NULL;
- adapter->lmp = NULL;
- }
-
- /* Zero out the receive descriptors status */
- current_desc->status = 0;
-
- /* Advance the E1000's Receive Queue #0 "Tail Pointer". */
- E1000_WRITE_REG(&adapter->hw, RDT, i);
-
- /* Advance our pointers to the next descriptor */
- if (++i == adapter->num_rx_desc) {
- i = 0;
- current_desc = adapter->rx_desc_base;
- } else
- current_desc++;
- }
- bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- adapter->next_rx_desc_to_check = i;
- return;
-}
-
-#ifndef __rtems__
-/*********************************************************************
- *
- * Verify that the hardware indicated that the checksum is valid.
- * Inform the stack about the status of checksum so that stack
- * doesn't spend time verifying the checksum.
- *
- *********************************************************************/
-static void
-em_receive_checksum(struct adapter *adapter,
- struct em_rx_desc *rx_desc,
- struct mbuf *mp)
-{
- /* 82543 or newer only */
- if ((adapter->hw.mac_type < em_82543) ||
- /* Ignore Checksum bit is set */
- (rx_desc->status & E1000_RXD_STAT_IXSM)) {
- mp->m_pkthdr.csum_flags = 0;
- return;
- }
-
- if (rx_desc->status & E1000_RXD_STAT_IPCS) {
- /* Did it pass? */
- if (!(rx_desc->errors & E1000_RXD_ERR_IPE)) {
- /* IP Checksum Good */
- mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
- mp->m_pkthdr.csum_flags |= CSUM_IP_VALID;
-
- } else {
- mp->m_pkthdr.csum_flags = 0;
- }
- }
-
- if (rx_desc->status & E1000_RXD_STAT_TCPCS) {
- /* Did it pass? */
- if (!(rx_desc->errors & E1000_RXD_ERR_TCPE)) {
- mp->m_pkthdr.csum_flags |=
- (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
- mp->m_pkthdr.csum_data = htons(0xffff);
- }
- }
-
- return;
-}
-
-
-static void
-em_enable_vlans(struct adapter *adapter)
-{
- uint32_t ctrl;
-
- E1000_WRITE_REG(&adapter->hw, VET, ETHERTYPE_VLAN);
-
- ctrl = E1000_READ_REG(&adapter->hw, CTRL);
- ctrl |= E1000_CTRL_VME;
- E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
-
- return;
-}
-
-static void
-em_disable_vlans(struct adapter *adapter)
-{
- uint32_t ctrl;
-
- ctrl = E1000_READ_REG(&adapter->hw, CTRL);
- ctrl &= ~E1000_CTRL_VME;
- E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
-
- return;
-}
-#endif
-
-static void
-em_enable_intr(struct adapter * adapter)
-{
- E1000_WRITE_REG(&adapter->hw, IMS, (IMS_ENABLE_MASK));
- return;
-}
-
-static void
-em_disable_intr(struct adapter *adapter)
-{
- /*
- * The first version of 82542 had an errata where when link was forced it
- * would stay up even up even if the cable was disconnected. Sequence errors
- * were used to detect the disconnect and then the driver would unforce the link.
- * This code in the in the ISR. For this to work correctly the Sequence error
- * interrupt had to be enabled all the time.
- */
-
- if (adapter->hw.mac_type == em_82542_rev2_0)
- E1000_WRITE_REG(&adapter->hw, IMC,
- (0xffffffff & ~E1000_IMC_RXSEQ));
- else
- E1000_WRITE_REG(&adapter->hw, IMC,
- 0xffffffff);
- return;
-}
-
-static int
-em_is_valid_ether_addr(u_int8_t *addr)
-{
- char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
-
- if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) {
- return (FALSE);
- }
-
- return(TRUE);
-}
-
-void
-em_write_pci_cfg(struct em_hw *hw,
- uint32_t reg,
- uint16_t *value)
-{
- pci_write_config(((struct em_osdep *)hw->back)->dev, reg,
- *value, 2);
-}
-
-void
-em_read_pci_cfg(struct em_hw *hw, uint32_t reg,
- uint16_t *value)
-{
- *value = pci_read_config(((struct em_osdep *)hw->back)->dev,
- reg, 2);
- return;
-}
-
-void
-em_pci_set_mwi(struct em_hw *hw)
-{
- pci_write_config(((struct em_osdep *)hw->back)->dev,
- PCIR_COMMAND,
- (hw->pci_cmd_word | CMD_MEM_WRT_INVALIDATE), 2);
- return;
-}
-
-void
-em_pci_clear_mwi(struct em_hw *hw)
-{
- pci_write_config(((struct em_osdep *)hw->back)->dev,
- PCIR_COMMAND,
- (hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE), 2);
- return;
-}
-
-uint32_t
-em_io_read(struct em_hw *hw, unsigned long port)
-{
- return(inl(port));
-}
-
-void
-em_io_write(struct em_hw *hw, unsigned long port, uint32_t value)
-{
-#ifndef __rtems__
- outl(port, value);
-#else
- /* everybody else has this the other way round! */
- outl(value, port);
-#endif
- return;
-}
-
-/*********************************************************************
-* 82544 Coexistence issue workaround.
-* There are 2 issues.
-* 1. Transmit Hang issue.
-* To detect this issue, following equation can be used...
-* SIZE[3:0] + ADDR[2:0] = SUM[3:0].
-* If SUM[3:0] is in between 1 to 4, we will have this issue.
-*
-* 2. DAC issue.
-* To detect this issue, following equation can be used...
-* SIZE[3:0] + ADDR[2:0] = SUM[3:0].
-* If SUM[3:0] is in between 9 to c, we will have this issue.
-*
-*
-* WORKAROUND:
-* Make sure we do not have ending address as 1,2,3,4(Hang) or 9,a,b,c (DAC)
-*
-*** *********************************************************************/
-static u_int32_t
-em_fill_descriptors (u_int64_t address,
- u_int32_t length,
- PDESC_ARRAY desc_array)
-{
- /* Since issue is sensitive to length and address.*/
- /* Let us first check the address...*/
- u_int32_t safe_terminator;
- if (length <= 4) {
- desc_array->descriptor[0].address = address;
- desc_array->descriptor[0].length = length;
- desc_array->elements = 1;
- return desc_array->elements;
- }
- safe_terminator = (u_int32_t)((((u_int32_t)address & 0x7) + (length & 0xF)) & 0xF);
- /* if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then return */
- if (safe_terminator == 0 ||
- (safe_terminator > 4 &&
- safe_terminator < 9) ||
- (safe_terminator > 0xC &&
- safe_terminator <= 0xF)) {
- desc_array->descriptor[0].address = address;
- desc_array->descriptor[0].length = length;
- desc_array->elements = 1;
- return desc_array->elements;
- }
-
- desc_array->descriptor[0].address = address;
- desc_array->descriptor[0].length = length - 4;
- desc_array->descriptor[1].address = address + (length - 4);
- desc_array->descriptor[1].length = 4;
- desc_array->elements = 2;
- return desc_array->elements;
-}
-
-/**********************************************************************
- *
- * Update the board statistics counters.
- *
- **********************************************************************/
-static void
-em_update_stats_counters(struct adapter *adapter)
-{
- struct ifnet *ifp;
-
- if(adapter->hw.media_type == em_media_type_copper ||
- (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
- adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, SYMERRS);
- adapter->stats.sec += E1000_READ_REG(&adapter->hw, SEC);
- }
- adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, CRCERRS);
- adapter->stats.mpc += E1000_READ_REG(&adapter->hw, MPC);
- adapter->stats.scc += E1000_READ_REG(&adapter->hw, SCC);
- adapter->stats.ecol += E1000_READ_REG(&adapter->hw, ECOL);
-
- adapter->stats.mcc += E1000_READ_REG(&adapter->hw, MCC);
- adapter->stats.latecol += E1000_READ_REG(&adapter->hw, LATECOL);
- adapter->stats.colc += E1000_READ_REG(&adapter->hw, COLC);
- adapter->stats.dc += E1000_READ_REG(&adapter->hw, DC);
- adapter->stats.rlec += E1000_READ_REG(&adapter->hw, RLEC);
- adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, XONRXC);
- adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, XONTXC);
- adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, XOFFRXC);
- adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, XOFFTXC);
- adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, FCRUC);
- adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, PRC64);
- adapter->stats.prc127 += E1000_READ_REG(&adapter->hw, PRC127);
- adapter->stats.prc255 += E1000_READ_REG(&adapter->hw, PRC255);
- adapter->stats.prc511 += E1000_READ_REG(&adapter->hw, PRC511);
- adapter->stats.prc1023 += E1000_READ_REG(&adapter->hw, PRC1023);
- adapter->stats.prc1522 += E1000_READ_REG(&adapter->hw, PRC1522);
- adapter->stats.gprc += E1000_READ_REG(&adapter->hw, GPRC);
- adapter->stats.bprc += E1000_READ_REG(&adapter->hw, BPRC);
- adapter->stats.mprc += E1000_READ_REG(&adapter->hw, MPRC);
- adapter->stats.gptc += E1000_READ_REG(&adapter->hw, GPTC);
-
- /* For the 64-bit byte counters the low dword must be read first. */
- /* Both registers clear on the read of the high dword */
-
- adapter->stats.gorcl += E1000_READ_REG(&adapter->hw, GORCL);
- adapter->stats.gorch += E1000_READ_REG(&adapter->hw, GORCH);
- adapter->stats.gotcl += E1000_READ_REG(&adapter->hw, GOTCL);
- adapter->stats.gotch += E1000_READ_REG(&adapter->hw, GOTCH);
-
- adapter->stats.rnbc += E1000_READ_REG(&adapter->hw, RNBC);
- adapter->stats.ruc += E1000_READ_REG(&adapter->hw, RUC);
- adapter->stats.rfc += E1000_READ_REG(&adapter->hw, RFC);
- adapter->stats.roc += E1000_READ_REG(&adapter->hw, ROC);
- adapter->stats.rjc += E1000_READ_REG(&adapter->hw, RJC);
-
- adapter->stats.torl += E1000_READ_REG(&adapter->hw, TORL);
- adapter->stats.torh += E1000_READ_REG(&adapter->hw, TORH);
- adapter->stats.totl += E1000_READ_REG(&adapter->hw, TOTL);
- adapter->stats.toth += E1000_READ_REG(&adapter->hw, TOTH);
-
- adapter->stats.tpr += E1000_READ_REG(&adapter->hw, TPR);
- adapter->stats.tpt += E1000_READ_REG(&adapter->hw, TPT);
- adapter->stats.ptc64 += E1000_READ_REG(&adapter->hw, PTC64);
- adapter->stats.ptc127 += E1000_READ_REG(&adapter->hw, PTC127);
- adapter->stats.ptc255 += E1000_READ_REG(&adapter->hw, PTC255);
- adapter->stats.ptc511 += E1000_READ_REG(&adapter->hw, PTC511);
- adapter->stats.ptc1023 += E1000_READ_REG(&adapter->hw, PTC1023);
- adapter->stats.ptc1522 += E1000_READ_REG(&adapter->hw, PTC1522);
- adapter->stats.mptc += E1000_READ_REG(&adapter->hw, MPTC);
- adapter->stats.bptc += E1000_READ_REG(&adapter->hw, BPTC);
-
- if (adapter->hw.mac_type >= em_82543) {
- adapter->stats.algnerrc +=
- E1000_READ_REG(&adapter->hw, ALGNERRC);
- adapter->stats.rxerrc +=
- E1000_READ_REG(&adapter->hw, RXERRC);
- adapter->stats.tncrs +=
- E1000_READ_REG(&adapter->hw, TNCRS);
- adapter->stats.cexterr +=
- E1000_READ_REG(&adapter->hw, CEXTERR);
- adapter->stats.tsctc +=
- E1000_READ_REG(&adapter->hw, TSCTC);
- adapter->stats.tsctfc +=
- E1000_READ_REG(&adapter->hw, TSCTFC);
- }
- ifp = &adapter->arpcom.ac_if;
-
- /* Fill out the OS statistics structure */
- ifp->if_ibytes = adapter->stats.gorcl;
- ifp->if_obytes = adapter->stats.gotcl;
- ifp->if_imcasts = adapter->stats.mprc;
- ifp->if_collisions = adapter->stats.colc;
-
- /* Rx Errors */
- ifp->if_ierrors =
- adapter->dropped_pkts +
- adapter->stats.rxerrc +
- adapter->stats.crcerrs +
- adapter->stats.algnerrc +
- adapter->stats.rlec +
- adapter->stats.mpc + adapter->stats.cexterr;
-
- /* Tx Errors */
- ifp->if_oerrors = adapter->stats.ecol + adapter->stats.latecol;
-
-}
-
-#ifndef __rtems__
-/**********************************************************************
- *
- * This routine is called only when em_display_debug_stats is enabled.
- * This routine provides a way to take a look at important statistics
- * maintained by the driver and hardware.
- *
- **********************************************************************/
-static void
-em_print_debug_info(struct adapter *adapter)
-{
- int unit = adapter->unit;
- uint8_t *hw_addr = adapter->hw.hw_addr;
-
- printf("em%d: Adapter hardware address = %p \n", unit, hw_addr);
- printf("em%d:CTRL = 0x%x\n", unit,
- E1000_READ_REG(&adapter->hw, CTRL));
- printf("em%d:RCTL = 0x%x PS=(0x8402)\n", unit,
- E1000_READ_REG(&adapter->hw, RCTL));
- printf("em%d:tx_int_delay = %d, tx_abs_int_delay = %d\n", unit,
- E1000_READ_REG(&adapter->hw, TIDV),
- E1000_READ_REG(&adapter->hw, TADV));
- printf("em%d:rx_int_delay = %d, rx_abs_int_delay = %d\n", unit,
- E1000_READ_REG(&adapter->hw, RDTR),
- E1000_READ_REG(&adapter->hw, RADV));
- printf("em%d: fifo workaround = %lld, fifo_reset = %lld\n", unit,
- (long long)adapter->tx_fifo_wrk_cnt,
- (long long)adapter->tx_fifo_reset_cnt);
- printf("em%d: hw tdh = %d, hw tdt = %d\n", unit,
- E1000_READ_REG(&adapter->hw, TDH),
- E1000_READ_REG(&adapter->hw, TDT));
- printf("em%d: Num Tx descriptors avail = %d\n", unit,
- adapter->num_tx_desc_avail);
- printf("em%d: Tx Descriptors not avail1 = %ld\n", unit,
- adapter->no_tx_desc_avail1);
- printf("em%d: Tx Descriptors not avail2 = %ld\n", unit,
- adapter->no_tx_desc_avail2);
- printf("em%d: Std mbuf failed = %ld\n", unit,
- adapter->mbuf_alloc_failed);
- printf("em%d: Std mbuf cluster failed = %ld\n", unit,
- adapter->mbuf_cluster_failed);
- printf("em%d: Driver dropped packets = %ld\n", unit,
- adapter->dropped_pkts);
-
- return;
-}
-#endif
-
-static void
-em_print_hw_stats(struct adapter *adapter)
-{
- int unit = adapter->unit;
-
- printf("em%d: Excessive collisions = %lld\n", unit,
- (long long)adapter->stats.ecol);
- printf("em%d: Symbol errors = %lld\n", unit,
- (long long)adapter->stats.symerrs);
- printf("em%d: Sequence errors = %lld\n", unit,
- (long long)adapter->stats.sec);
- printf("em%d: Defer count = %lld\n", unit,
- (long long)adapter->stats.dc);
-
- printf("em%d: Missed Packets = %lld\n", unit,
- (long long)adapter->stats.mpc);
- printf("em%d: Receive No Buffers = %lld\n", unit,
- (long long)adapter->stats.rnbc);
- printf("em%d: Receive length errors = %lld\n", unit,
- (long long)adapter->stats.rlec);
- printf("em%d: Receive errors = %lld\n", unit,
- (long long)adapter->stats.rxerrc);
- printf("em%d: Crc errors = %lld\n", unit,
- (long long)adapter->stats.crcerrs);
- printf("em%d: Alignment errors = %lld\n", unit,
- (long long)adapter->stats.algnerrc);
- printf("em%d: Carrier extension errors = %lld\n", unit,
- (long long)adapter->stats.cexterr);
-
- printf("em%d: XON Rcvd = %lld\n", unit,
- (long long)adapter->stats.xonrxc);
- printf("em%d: XON Xmtd = %lld\n", unit,
- (long long)adapter->stats.xontxc);
- printf("em%d: XOFF Rcvd = %lld\n", unit,
- (long long)adapter->stats.xoffrxc);
- printf("em%d: XOFF Xmtd = %lld\n", unit,
- (long long)adapter->stats.xofftxc);
-
- printf("em%d: Good Packets Rcvd = %lld\n", unit,
- (long long)adapter->stats.gprc);
- printf("em%d: Good Packets Xmtd = %lld\n", unit,
- (long long)adapter->stats.gptc);
-
- return;
-}
-
-#ifndef __rtems__
-static int
-em_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
-{
- int error;
- int result;
- struct adapter *adapter;
-
- result = -1;
- error = sysctl_handle_int(oidp, &result, 0, req);
-
- if (error || !req->newptr)
- return (error);
-
- if (result == 1) {
- adapter = (struct adapter *)arg1;
- em_print_debug_info(adapter);
- }
-
- return error;
-}
-
-static int
-em_sysctl_stats(SYSCTL_HANDLER_ARGS)
-{
- int error;
- int result;
- struct adapter *adapter;
-
- result = -1;
- error = sysctl_handle_int(oidp, &result, 0, req);
-
- if (error || !req->newptr)
- return (error);
-
- if (result == 1) {
- adapter = (struct adapter *)arg1;
- em_print_hw_stats(adapter);
- }
-
- return error;
-}
-
-static int
-em_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
-{
- struct em_int_delay_info *info;
- struct adapter *adapter;
- u_int32_t regval;
- int error;
- int usecs;
- int ticks;
- int s;
-
- info = (struct em_int_delay_info *)arg1;
- adapter = info->adapter;
- usecs = info->value;
- error = sysctl_handle_int(oidp, &usecs, 0, req);
- if (error != 0 || req->newptr == NULL)
- return error;
- if (usecs < 0 || usecs > E1000_TICKS_TO_USECS(65535))
- return EINVAL;
- info->value = usecs;
- ticks = E1000_USECS_TO_TICKS(usecs);
-
- s = splimp();
- regval = E1000_READ_OFFSET(&adapter->hw, info->offset);
- regval = (regval & ~0xffff) | (ticks & 0xffff);
- /* Handle a few special cases. */
- switch (info->offset) {
- case E1000_RDTR:
- case E1000_82542_RDTR:
- regval |= E1000_RDT_FPDB;
- break;
- case E1000_TIDV:
- case E1000_82542_TIDV:
- if (ticks == 0) {
- adapter->txd_cmd &= ~E1000_TXD_CMD_IDE;
- /* Don't write 0 into the TIDV register. */
- regval++;
- } else
- adapter->txd_cmd |= E1000_TXD_CMD_IDE;
- break;
- }
- E1000_WRITE_OFFSET(&adapter->hw, info->offset, regval);
- splx(s);
- return 0;
-}
-
-static void
-em_add_int_delay_sysctl(struct adapter *adapter, const char *name,
- const char *description, struct em_int_delay_info *info,
- int offset, int value)
-{
- info->adapter = adapter;
- info->offset = offset;
- info->value = value;
- SYSCTL_ADD_PROC(device_get_sysctl_ctx(adapter->dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
- OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW,
- info, 0, em_sysctl_int_delay, "I", description);
-}
-#endif
-
-#ifdef __rtems__
-/* Initialize bare minimals so we can check the phy link status */
-int
-em_hw_early_init(device_t dev)
-{
-struct adapter *adapter = device_get_softc(dev);
- adapter->dev = dev;
- adapter->osdep.dev = dev;
- em_identify_hardware(adapter);
- return em_allocate_pci_resources(adapter);
-}
-#endif
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em.h b/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em.h
deleted file mode 100644
index 1dc09ce05f..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em.h
+++ /dev/null
@@ -1,493 +0,0 @@
-/**************************************************************************
-
-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:
-
- 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: /repoman/r/ncvs/src/sys/dev/em/if_em.h,v 1.31 2005/05/26 23:32:02 tackerman Exp $*/
-
-#ifndef _EM_H_DEFINED_
-#define _EM_H_DEFINED_
-
-
-#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>
-#ifndef __rtems__
-#include <sys/module.h>
-#endif
-#include <sys/sockio.h>
-#include <sys/sysctl.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#ifndef __rtems__
-
-#include <net/bpf.h>
-#include <net/if_types.h>
-#include <net/if_vlan_var.h>
-#else
-#include <net/if_types.h>
-#endif
-
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-
-#ifndef __rtems__
-#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>
-#else
-#include <netinet/if_ether.h>
-#include <bsp/pci.h>
-#endif
-
-#ifndef __rtems__
-#include <sys/endian.h>
-#include <sys/proc.h>
-#include "opt_bdg.h"
-
-
-#include <dev/em/if_em_hw.h>
-#else
-#include "if_em_hw.h"
-#endif
-
-/* Tunables */
-
-/*
- * EM_MAX_TXD: Maximum number of Transmit Descriptors
- * Valid Range: 80-256 for 82542 and 82543-based adapters
- * 80-4096 for others
- * Default Value: 256
- * This value is the number of transmit descriptors allocated by the driver.
- * Increasing this value allows the driver to queue more transmits. Each
- * descriptor is 16 bytes.
- */
-#define EM_MAX_TXD 256
-
-/*
- * EM_MAX_RXD - Maximum number of receive Descriptors
- * Valid Range: 80-256 for 82542 and 82543-based adapters
- * 80-4096 for others
- * Default Value: 256
- * This value is the number of receive descriptors allocated by the driver.
- * Increasing this value allows the driver to buffer more incoming packets.
- * Each descriptor is 16 bytes. A receive buffer is also allocated for each
- * descriptor. The maximum MTU size is 16110.
- *
- */
-#define EM_MAX_RXD 80
-
-/*
- * EM_TIDV - Transmit Interrupt Delay Value
- * Valid Range: 0-65535 (0=off)
- * Default Value: 64
- * This value delays the generation of transmit interrupts in units of
- * 1.024 microseconds. Transmit interrupt reduction can improve CPU
- * efficiency if properly tuned for specific network traffic. If the
- * system is reporting dropped transmits, this value may be set too high
- * causing the driver to run out of available transmit descriptors.
- */
-#define EM_TIDV 64
-
-/*
- * EM_TADV - Transmit Absolute Interrupt Delay Value (Not valid for 82542/82543/82544)
- * Valid Range: 0-65535 (0=off)
- * Default Value: 64
- * This value, in units of 1.024 microseconds, limits the delay in which a
- * transmit interrupt is generated. Useful only if EM_TIDV is non-zero,
- * this value ensures that an interrupt is generated after the initial
- * packet is sent on the wire within the set amount of time. Proper tuning,
- * along with EM_TIDV, may improve traffic throughput in specific
- * network conditions.
- */
-#define EM_TADV 64
-
-/*
- * EM_RDTR - Receive Interrupt Delay Timer (Packet Timer)
- * Valid Range: 0-65535 (0=off)
- * Default Value: 0
- * This value delays the generation of receive interrupts in units of 1.024
- * microseconds. Receive interrupt reduction can improve CPU efficiency if
- * properly tuned for specific network traffic. Increasing this value adds
- * extra latency to frame reception and can end up decreasing the throughput
- * of TCP traffic. If the system is reporting dropped receives, this value
- * may be set too high, causing the driver to run out of available receive
- * descriptors.
- *
- * CAUTION: When setting EM_RDTR to a value other than 0, adapters
- * may hang (stop transmitting) under certain network conditions.
- * If this occurs a WATCHDOG message is logged in the system event log.
- * In addition, the controller is automatically reset, restoring the
- * network connection. To eliminate the potential for the hang
- * ensure that EM_RDTR is set to 0.
- */
-#define EM_RDTR 0
-
-/*
- * Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544)
- * Valid Range: 0-65535 (0=off)
- * Default Value: 64
- * This value, in units of 1.024 microseconds, limits the delay in which a
- * receive interrupt is generated. Useful only if EM_RDTR is non-zero,
- * this value ensures that an interrupt is generated after the initial
- * packet is received within the set amount of time. Proper tuning,
- * along with EM_RDTR, may improve traffic throughput in specific network
- * conditions.
- */
-#define EM_RADV 64
-
-
-/*
- * This parameter controls the maximum no of times the driver will loop
- * in the isr.
- * Minimum Value = 1
- */
-#define EM_MAX_INTR 3
-
-/*
- * Inform the stack about transmit checksum offload capabilities.
- */
-#define EM_CHECKSUM_FEATURES (CSUM_TCP | CSUM_UDP)
-
-/*
- * This parameter controls the duration of transmit watchdog timer.
- */
-#define EM_TX_TIMEOUT 5 /* set to 5 seconds */
-
-/*
- * This parameter controls when the driver calls the routine to reclaim
- * transmit descriptors.
- */
-#ifndef __rtems__
-#define EM_TX_CLEANUP_THRESHOLD EM_MAX_TXD / 8
-#else
-#define EM_TX_CLEANUP_THRESHOLD (adapter->tx_cleanup_threshold)
-#endif
-
-/*
- * This parameter controls whether or not autonegotation is enabled.
- * 0 - Disable autonegotiation
- * 1 - Enable autonegotiation
- */
-#define DO_AUTO_NEG 1
-
-/*
- * This parameter control whether or not the driver will wait for
- * autonegotiation to complete.
- * 1 - Wait for autonegotiation to complete
- * 0 - Don't wait for autonegotiation to complete
- */
-#define WAIT_FOR_AUTO_NEG_DEFAULT 0
-
-/*
- * 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 */
-
-/* Tunables -- End */
-
-#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
- ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
- ADVERTISE_1000_FULL)
-
-#define EM_VENDOR_ID 0x8086
-#define EM_MMBA 0x0010 /* Mem base address */
-#define EM_ROUNDUP(size, unit) (((size) + (unit) - 1) & ~((unit) - 1))
-
-#define EM_JUMBO_PBA 0x00000028
-#define EM_DEFAULT_PBA 0x00000030
-#define EM_SMARTSPEED_DOWNSHIFT 3
-#define EM_SMARTSPEED_MAX 15
-
-
-#define MAX_NUM_MULTICAST_ADDRESSES 128
-#define PCI_ANY_ID (~0U)
-#define ETHER_ALIGN 2
-
-/* Defines for printing debug information */
-#define DEBUG_INIT 0
-#define DEBUG_IOCTL 0
-#define DEBUG_HW 0
-
-#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n")
-#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A)
-#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B)
-#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n")
-#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A)
-#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B)
-#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n")
-#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
-#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
-
-
-/* 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
-
-/* ******************************************************************************
- * vendor_info_array
- *
- * This array contains the list of Subvendor/Subdevice IDs on which the driver
- * should load.
- *
- * ******************************************************************************/
-typedef struct _em_vendor_info_t {
- unsigned int vendor_id;
- unsigned int device_id;
- unsigned int subvendor_id;
- unsigned int subdevice_id;
- unsigned int index;
-} em_vendor_info_t;
-
-
-struct em_buffer {
- struct mbuf *m_head;
-#ifndef __rtems__
- bus_dmamap_t map; /* bus_dma map for packet */
-#endif
-};
-
-/*
- * Bus dma allocation structure used by
- * em_dma_malloc and em_dma_free.
- */
-struct em_dma_alloc {
- bus_addr_t dma_paddr; /* 64bit in descriptors */
-#ifndef __rtems__
- caddr_t dma_vaddr;
- bus_dma_tag_t dma_tag;
- bus_dmamap_t dma_map;
- bus_dma_segment_t dma_seg;
- bus_size_t dma_size;
- int dma_nseg;
-#else
- caddr_t dma_vaddr;
- caddr_t malloc_base;
-#endif
-};
-
-typedef enum _XSUM_CONTEXT_T {
- OFFLOAD_NONE,
- OFFLOAD_TCP_IP,
- OFFLOAD_UDP_IP
-} XSUM_CONTEXT_T;
-
-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 */
-};
-
-/* For 82544 PCIX Workaround */
-typedef struct _ADDRESS_LENGTH_PAIR
-{
- u_int64_t address;
- u_int32_t length;
-} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
-
-typedef struct _DESCRIPTOR_PAIR
-{
- ADDRESS_LENGTH_PAIR descriptor[4];
- u_int32_t elements;
-} DESC_ARRAY, *PDESC_ARRAY;
-
-/* Our adapter structure */
-struct adapter {
- struct arpcom interface_data;
- struct adapter *next;
- struct adapter *prev;
- struct em_hw hw;
-
- /* FreeBSD operating-system-specific structures */
- struct em_osdep osdep;
-#ifndef __rtems__
- struct device *dev;
- struct resource *res_memory;
- struct resource *res_ioport;
- struct resource *res_interrupt;
- void *int_handler_tag;
- struct ifmedia media;
- struct callout timer;
- struct callout tx_fifo_timer;
- int io_rid;
- struct ifmedia media;
-#endif
- u_int8_t unit;
-#ifndef __rtems__
- struct mtx mtx;
- int em_insert_vlan_header;
-#else
- device_t dev;
- unsigned char irq_no;
- unsigned char b,d,f;
- rtems_id tid;
-#endif
-
- /* Info about the board itself */
-#ifndef __rtems__
- u_int32_t part_num;
-#else
- uint32_t part_num;
-#endif
- u_int8_t link_active;
- u_int16_t link_speed;
- u_int16_t link_duplex;
- u_int32_t smartspeed;
- struct em_int_delay_info tx_int_delay;
- struct em_int_delay_info tx_abs_int_delay;
- 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
- *
- * We have an array of num_tx_desc descriptors (handled
- * by the controller) paired with an array of tx_buffers
- * (at tx_buffer_area).
- * The index of the next available descriptor is next_avail_tx_desc.
- * 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;
- u_int32_t next_avail_tx_desc;
- u_int32_t oldest_used_tx_desc;
- volatile u_int16_t num_tx_desc_avail;
- u_int16_t num_tx_desc;
- u_int32_t txd_cmd;
- struct em_buffer *tx_buffer_area;
-#ifndef __rtems__
- bus_dma_tag_t txtag; /* dma tag for tx */
-#endif
-#ifdef __rtems__
- u_int16_t tx_cleanup_threshold;
-#endif
-
- /*
- * Receive definitions
- *
- * we have an array of num_rx_desc rx_desc (handled by the
- * controller), and paired with an array of rx_buffers
- * (at rx_buffer_area).
- * 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;
- u_int32_t next_rx_desc_to_check;
- u_int16_t num_rx_desc;
- u_int32_t rx_buffer_len;
- struct em_buffer *rx_buffer_area;
-#ifndef __rtems__
- bus_dma_tag_t rxtag;
-#endif
-
- /* Jumbo frame */
- 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;
- unsigned long no_tx_desc_avail2;
- unsigned long no_tx_map_avail;
- unsigned long no_tx_dma_setup;
-
- /* Used in for 82547 10Mb Half workaround */
- #define EM_PBA_BYTES_SHIFT 0xA
- #define EM_TX_HEAD_ADDR_SHIFT 7
- #define EM_PBA_TX_MASK 0xFFFF0000
- #define EM_FIFO_HDR 0x10
-
- #define EM_82547_PKT_THRESH 0x3e0
-
- u_int32_t tx_fifo_size;
- u_int32_t tx_fifo_head;
- u_int32_t tx_fifo_head_addr;
- u_int64_t tx_fifo_reset_cnt;
- u_int64_t tx_fifo_wrk_cnt;
- u_int32_t tx_head_addr;
-
- /* For 82544 PCIX Workaround */
- boolean_t pcix_82544;
- boolean_t in_detach;
-
- struct em_hw_stats stats;
-};
-
-#define EM_LOCK_INIT(_sc, _name) \
- mtx_init(&(_sc)->mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
-#define EM_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx)
-#define EM_LOCK(_sc) mtx_lock(&(_sc)->mtx)
-#define EM_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx)
-#define EM_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED)
-
-#ifdef __rtems__
-/* Initialize bare minimals so we can check the phy link status;
- * 'rtems_em_pci_setup()' must have been run on the device already!
- */
-int
-em_hw_early_init(device_t dev);
-#endif
-
-
-#endif /* _EM_H_DEFINED_ */
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_hw.c b/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_hw.c
deleted file mode 100644
index 0dcf349733..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_hw.c
+++ /dev/null
@@ -1,6636 +0,0 @@
-/*******************************************************************************
-
- 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:
-
- 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.
-
-*******************************************************************************/
-
-/* if_em_hw.c
- * Shared functions for accessing and configuring the MAC
- */
-
-#include <sys/cdefs.h>
-#ifdef __rtems__
-#include "rtemscompat_defs.h"
-#include "../porting/rtemscompat.h"
-#include "if_em_hw.h"
-#else
-__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/em/if_em_hw.c,v 1.16 2005/05/26 23:32:02 tackerman Exp $");
-
-#include <dev/em/if_em_hw.h>
-#endif
-
-static int32_t em_set_phy_type(struct em_hw *hw);
-static void em_phy_init_script(struct em_hw *hw);
-static int32_t em_setup_copper_link(struct em_hw *hw);
-static int32_t em_setup_fiber_serdes_link(struct em_hw *hw);
-static int32_t em_adjust_serdes_amplitude(struct em_hw *hw);
-static int32_t em_phy_force_speed_duplex(struct em_hw *hw);
-static int32_t em_config_mac_to_phy(struct em_hw *hw);
-static void em_raise_mdi_clk(struct em_hw *hw, uint32_t *ctrl);
-static void em_lower_mdi_clk(struct em_hw *hw, uint32_t *ctrl);
-static void em_shift_out_mdi_bits(struct em_hw *hw, uint32_t data,
- uint16_t count);
-static uint16_t em_shift_in_mdi_bits(struct em_hw *hw);
-static int32_t em_phy_reset_dsp(struct em_hw *hw);
-static int32_t em_write_eeprom_spi(struct em_hw *hw, uint16_t offset,
- uint16_t words, uint16_t *data);
-static int32_t em_write_eeprom_microwire(struct em_hw *hw,
- uint16_t offset, uint16_t words,
- uint16_t *data);
-static int32_t em_spi_eeprom_ready(struct em_hw *hw);
-static void em_raise_ee_clk(struct em_hw *hw, uint32_t *eecd);
-static void em_lower_ee_clk(struct em_hw *hw, uint32_t *eecd);
-static void em_shift_out_ee_bits(struct em_hw *hw, uint16_t data,
- uint16_t count);
-static int32_t em_write_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr,
- uint16_t phy_data);
-static int32_t em_read_phy_reg_ex(struct em_hw *hw,uint32_t reg_addr,
- uint16_t *phy_data);
-static uint16_t em_shift_in_ee_bits(struct em_hw *hw, uint16_t count);
-static int32_t em_acquire_eeprom(struct em_hw *hw);
-static void em_release_eeprom(struct em_hw *hw);
-static void em_standby_eeprom(struct em_hw *hw);
-static int32_t em_set_vco_speed(struct em_hw *hw);
-static int32_t em_polarity_reversal_workaround(struct em_hw *hw);
-static int32_t em_set_phy_mode(struct em_hw *hw);
-static int32_t em_host_if_read_cookie(struct em_hw *hw, uint8_t *buffer);
-static uint8_t em_calculate_mng_checksum(char *buffer, uint32_t length);
-
-/* IGP cable length table */
-static const
-uint16_t em_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
- { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
- 25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
- 90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
- 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
- 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
-
-static const
-uint16_t em_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
- { 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43,
- 22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58,
- 32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74,
- 43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90,
- 57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108,
- 73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124,
- 91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128,
- 108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
-
-
-/******************************************************************************
- * Set the phy type member in the hw struct.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_set_phy_type(struct em_hw *hw)
-{
- DEBUGFUNC("em_set_phy_type");
-
- if(hw->mac_type == em_undefined)
- return -E1000_ERR_PHY_TYPE;
-
- switch(hw->phy_id) {
- case M88E1000_E_PHY_ID:
- case M88E1000_I_PHY_ID:
- case M88E1011_I_PHY_ID:
- case M88E1111_I_PHY_ID:
- hw->phy_type = em_phy_m88;
- break;
- case IGP01E1000_I_PHY_ID:
- if(hw->mac_type == em_82541 ||
- hw->mac_type == em_82541_rev_2 ||
- hw->mac_type == em_82547 ||
- hw->mac_type == em_82547_rev_2) {
- hw->phy_type = em_phy_igp;
- break;
- }
- /* Fall Through */
- default:
- /* Should never have loaded on this device */
- hw->phy_type = em_phy_undefined;
- return -E1000_ERR_PHY_TYPE;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * IGP phy init script - initializes the GbE PHY
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void
-em_phy_init_script(struct em_hw *hw)
-{
- uint32_t ret_val;
- uint16_t phy_saved_data;
-
- DEBUGFUNC("em_phy_init_script");
-
- if(hw->phy_init_script) {
- msec_delay(20);
-
- /* Save off the current value of register 0x2F5B to be restored at
- * the end of this routine. */
- ret_val = em_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
-
- /* Disabled the PHY transmitter */
- em_write_phy_reg(hw, 0x2F5B, 0x0003);
-
- msec_delay(20);
-
- em_write_phy_reg(hw,0x0000,0x0140);
-
- msec_delay(5);
-
- switch(hw->mac_type) {
- case em_82541:
- case em_82547:
- em_write_phy_reg(hw, 0x1F95, 0x0001);
-
- em_write_phy_reg(hw, 0x1F71, 0xBD21);
-
- em_write_phy_reg(hw, 0x1F79, 0x0018);
-
- em_write_phy_reg(hw, 0x1F30, 0x1600);
-
- em_write_phy_reg(hw, 0x1F31, 0x0014);
-
- em_write_phy_reg(hw, 0x1F32, 0x161C);
-
- em_write_phy_reg(hw, 0x1F94, 0x0003);
-
- em_write_phy_reg(hw, 0x1F96, 0x003F);
-
- em_write_phy_reg(hw, 0x2010, 0x0008);
- break;
-
- case em_82541_rev_2:
- case em_82547_rev_2:
- em_write_phy_reg(hw, 0x1F73, 0x0099);
- break;
- default:
- break;
- }
-
- em_write_phy_reg(hw, 0x0000, 0x3300);
-
- msec_delay(20);
-
- /* Now enable the transmitter */
- em_write_phy_reg(hw, 0x2F5B, phy_saved_data);
-
- if(hw->mac_type == em_82547) {
- uint16_t fused, fine, coarse;
-
- /* Move to analog registers page */
- em_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
-
- if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
- em_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused);
-
- fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
- coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
-
- if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
- coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10;
- fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
- } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
- fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
-
- fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
- (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
- (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);
-
- em_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
- em_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
- IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
- }
- }
- }
-}
-
-/******************************************************************************
- * Set the mac type member in the hw struct.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_set_mac_type(struct em_hw *hw)
-{
- DEBUGFUNC("em_set_mac_type");
-
- switch (hw->device_id) {
- case E1000_DEV_ID_82542:
- switch (hw->revision_id) {
- case E1000_82542_2_0_REV_ID:
- hw->mac_type = em_82542_rev2_0;
- break;
- case E1000_82542_2_1_REV_ID:
- hw->mac_type = em_82542_rev2_1;
- break;
- default:
- /* Invalid 82542 revision ID */
- return -E1000_ERR_MAC_TYPE;
- }
- break;
- case E1000_DEV_ID_82543GC_FIBER:
- case E1000_DEV_ID_82543GC_COPPER:
- hw->mac_type = em_82543;
- break;
- case E1000_DEV_ID_82544EI_COPPER:
- case E1000_DEV_ID_82544EI_FIBER:
- case E1000_DEV_ID_82544GC_COPPER:
- case E1000_DEV_ID_82544GC_LOM:
- hw->mac_type = em_82544;
- break;
- case E1000_DEV_ID_82540EM:
- case E1000_DEV_ID_82540EM_LOM:
- case E1000_DEV_ID_82540EP:
- case E1000_DEV_ID_82540EP_LOM:
- case E1000_DEV_ID_82540EP_LP:
- hw->mac_type = em_82540;
- break;
- case E1000_DEV_ID_82545EM_COPPER:
- case E1000_DEV_ID_82545EM_FIBER:
- hw->mac_type = em_82545;
- break;
- case E1000_DEV_ID_82545GM_COPPER:
- case E1000_DEV_ID_82545GM_FIBER:
- case E1000_DEV_ID_82545GM_SERDES:
- hw->mac_type = em_82545_rev_3;
- break;
- case E1000_DEV_ID_82546EB_COPPER:
- case E1000_DEV_ID_82546EB_FIBER:
- case E1000_DEV_ID_82546EB_QUAD_COPPER:
- hw->mac_type = em_82546;
- break;
- case E1000_DEV_ID_82546GB_COPPER:
- case E1000_DEV_ID_82546GB_FIBER:
- case E1000_DEV_ID_82546GB_SERDES:
- case E1000_DEV_ID_82546GB_PCIE:
- case E1000_DEV_ID_82546GB_QUAD_COPPER:
- hw->mac_type = em_82546_rev_3;
- break;
- case E1000_DEV_ID_82541EI:
- case E1000_DEV_ID_82541ER_LOM:
- case E1000_DEV_ID_82541EI_MOBILE:
- hw->mac_type = em_82541;
- break;
- case E1000_DEV_ID_82541ER:
- case E1000_DEV_ID_82541GI:
- case E1000_DEV_ID_82541GI_LF:
- case E1000_DEV_ID_82541GI_MOBILE:
- hw->mac_type = em_82541_rev_2;
- break;
- case E1000_DEV_ID_82547EI:
- case E1000_DEV_ID_82547EI_MOBILE:
- hw->mac_type = em_82547;
- break;
- case E1000_DEV_ID_82547GI:
- hw->mac_type = em_82547_rev_2;
- break;
- case E1000_DEV_ID_82573E:
- case E1000_DEV_ID_82573E_IAMT:
- hw->mac_type = em_82573;
- break;
- default:
- /* Should never have loaded on this device */
- return -E1000_ERR_MAC_TYPE;
- }
-
- switch(hw->mac_type) {
- case em_82573:
- hw->eeprom_semaphore_present = TRUE;
- /* fall through */
- case em_82541:
- case em_82547:
- case em_82541_rev_2:
- case em_82547_rev_2:
- hw->asf_firmware_present = TRUE;
- break;
- default:
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- * Set media type and TBI compatibility.
- *
- * hw - Struct containing variables accessed by shared code
- * **************************************************************************/
-void
-em_set_media_type(struct em_hw *hw)
-{
- uint32_t status;
-
- DEBUGFUNC("em_set_media_type");
-
- if(hw->mac_type != em_82543) {
- /* tbi_compatibility is only valid on 82543 */
- hw->tbi_compatibility_en = FALSE;
- }
-
- switch (hw->device_id) {
- case E1000_DEV_ID_82545GM_SERDES:
- case E1000_DEV_ID_82546GB_SERDES:
- hw->media_type = em_media_type_internal_serdes;
- break;
- default:
- if(hw->mac_type >= em_82543) {
- status = E1000_READ_REG(hw, STATUS);
- if(status & E1000_STATUS_TBIMODE) {
- hw->media_type = em_media_type_fiber;
- /* tbi_compatibility not valid on fiber */
- hw->tbi_compatibility_en = FALSE;
- } else {
- hw->media_type = em_media_type_copper;
- }
- } else {
- /* This is an 82542 (fiber only) */
- hw->media_type = em_media_type_fiber;
- }
- }
-}
-
-/******************************************************************************
- * Reset the transmit and receive units; mask and clear all interrupts.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_reset_hw(struct em_hw *hw)
-{
- uint32_t ctrl;
- uint32_t ctrl_ext;
- uint32_t icr;
- uint32_t manc;
- uint32_t led_ctrl;
- uint32_t timeout;
- uint32_t extcnf_ctrl;
- int32_t ret_val;
-
- DEBUGFUNC("em_reset_hw");
-
- /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
- if(hw->mac_type == em_82542_rev2_0) {
- DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
- em_pci_clear_mwi(hw);
- }
-
- if(hw->bus_type == em_bus_type_pci_express) {
- /* Prevent the PCI-E bus from sticking if there is no TLP connection
- * on the last TLP read/write transaction when MAC is reset.
- */
- if(em_disable_pciex_master(hw) != E1000_SUCCESS) {
- DEBUGOUT("PCI-E Master disable polling has failed.\n");
- }
- }
-
- /* Clear interrupt mask to stop board from generating interrupts */
- DEBUGOUT("Masking off all interrupts\n");
- E1000_WRITE_REG(hw, IMC, 0xffffffff);
-
- /* Disable the Transmit and Receive units. Then delay to allow
- * any pending transactions to complete before we hit the MAC with
- * the global reset.
- */
- E1000_WRITE_REG(hw, RCTL, 0);
- E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
- E1000_WRITE_FLUSH(hw);
-
- /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
- hw->tbi_compatibility_on = FALSE;
-
- /* Delay to allow any outstanding PCI transactions to complete before
- * resetting the device
- */
- msec_delay(10);
-
- ctrl = E1000_READ_REG(hw, CTRL);
-
- /* Must reset the PHY before resetting the MAC */
- if((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) {
- E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
- msec_delay(5);
- }
-
- /* Must acquire the MDIO ownership before MAC reset.
- * Ownership defaults to firmware after a reset. */
- if(hw->mac_type == em_82573) {
- timeout = 10;
-
- extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- do {
- E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
- extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
-
- if(extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
- break;
- else
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- msec_delay(2);
- timeout--;
- } while(timeout);
- }
-
- /* Issue a global reset to the MAC. This will reset the chip's
- * transmit, receive, DMA, and link units. It will not effect
- * the current PCI configuration. The global reset bit is self-
- * clearing, and should clear within a microsecond.
- */
- DEBUGOUT("Issuing a global reset to MAC\n");
-
- switch(hw->mac_type) {
- case em_82544:
- case em_82540:
- case em_82545:
-#ifndef __arm__
- case em_82546:
-#endif
- case em_82541:
- case em_82541_rev_2:
- /* These controllers can't ack the 64-bit write when issuing the
- * reset, so use IO-mapping as a workaround to issue the reset */
- E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
- break;
- case em_82545_rev_3:
- case em_82546_rev_3:
- /* Reset is performed on a shadow of the control register */
- E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
- break;
- default:
- E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
- break;
- }
-
- /* After MAC reset, force reload of EEPROM to restore power-on settings to
- * device. Later controllers reload the EEPROM automatically, so just wait
- * for reload to complete.
- */
- switch(hw->mac_type) {
- case em_82542_rev2_0:
- case em_82542_rev2_1:
- case em_82543:
- case em_82544:
- /* Wait for reset to complete */
- usec_delay(10);
- ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH(hw);
- /* Wait for EEPROM reload */
- msec_delay(2);
- break;
- case em_82541:
- case em_82541_rev_2:
- case em_82547:
- case em_82547_rev_2:
- /* Wait for EEPROM reload */
- msec_delay(20);
- break;
- case em_82573:
- usec_delay(10);
- ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH(hw);
- /* fall through */
- ret_val = em_get_auto_rd_done(hw);
- if(ret_val)
- /* We don't want to continue accessing MAC registers. */
- return ret_val;
- break;
- default:
- /* Wait for EEPROM reload (it happens automatically) */
- msec_delay(5);
- break;
- }
-
- /* Disable HW ARPs on ASF enabled adapters */
- if(hw->mac_type >= em_82540 && hw->mac_type <= em_82547_rev_2) {
- manc = E1000_READ_REG(hw, MANC);
- manc &= ~(E1000_MANC_ARP_EN);
- E1000_WRITE_REG(hw, MANC, manc);
- }
-
- if((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) {
- em_phy_init_script(hw);
-
- /* Configure activity LED after PHY reset */
- led_ctrl = E1000_READ_REG(hw, LEDCTL);
- led_ctrl &= IGP_ACTIVITY_LED_MASK;
- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
- E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
- }
-
- /* Clear interrupt mask to stop board from generating interrupts */
- DEBUGOUT("Masking off all interrupts\n");
- E1000_WRITE_REG(hw, IMC, 0xffffffff);
-
- /* Clear any pending interrupt events. */
- icr = E1000_READ_REG(hw, ICR);
-
- /* If MWI was previously enabled, reenable it. */
- if(hw->mac_type == em_82542_rev2_0) {
- if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
- em_pci_set_mwi(hw);
- }
-#ifdef __rtems__
- msec_delay(100);
-#endif
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Performs basic configuration of the adapter.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Assumes that the controller has previously been reset and is in a
- * post-reset uninitialized state. Initializes the receive address registers,
- * multicast table, and VLAN filter table. Calls routines to setup link
- * configuration and flow control settings. Clears all on-chip counters. Leaves
- * the transmit and receive units disabled and uninitialized.
- *****************************************************************************/
-int32_t
-em_init_hw(struct em_hw *hw)
-{
- uint32_t ctrl;
- uint32_t i;
- int32_t ret_val;
- uint16_t pcix_cmd_word;
- uint16_t pcix_stat_hi_word;
- uint16_t cmd_mmrbc;
- uint16_t stat_mmrbc;
- uint32_t mta_size;
-
- DEBUGFUNC("em_init_hw");
-
- /* Initialize Identification LED */
- ret_val = em_id_led_init(hw);
- if(ret_val) {
- DEBUGOUT("Error Initializing Identification LED\n");
- return ret_val;
- }
-
- /* Set the media type and TBI compatibility */
- em_set_media_type(hw);
-
- /* Disabling VLAN filtering. */
- DEBUGOUT("Initializing the IEEE VLAN\n");
- if (hw->mac_type < em_82545_rev_3)
- E1000_WRITE_REG(hw, VET, 0);
- em_clear_vfta(hw);
-
- /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
- if(hw->mac_type == em_82542_rev2_0) {
- DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
- em_pci_clear_mwi(hw);
- E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
- E1000_WRITE_FLUSH(hw);
- msec_delay(5);
- }
-
- /* Setup the receive address. This involves initializing all of the Receive
- * Address Registers (RARs 0 - 15).
- */
- em_init_rx_addrs(hw);
-
- /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
- if(hw->mac_type == em_82542_rev2_0) {
- E1000_WRITE_REG(hw, RCTL, 0);
- E1000_WRITE_FLUSH(hw);
- msec_delay(1);
- if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
- em_pci_set_mwi(hw);
- }
-
- /* Zero out the Multicast HASH table */
- DEBUGOUT("Zeroing the MTA\n");
- mta_size = E1000_MC_TBL_SIZE;
- for(i = 0; i < mta_size; i++)
- E1000_WRITE_REG_ARRAY(hw, 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. Valid only on
- * 82542 and 82543 silicon.
- */
- if(hw->dma_fairness && hw->mac_type <= em_82543) {
- ctrl = E1000_READ_REG(hw, CTRL);
- E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
- }
-
- switch(hw->mac_type) {
- case em_82545_rev_3:
- case em_82546_rev_3:
- break;
- default:
- /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
- if(hw->bus_type == em_bus_type_pcix) {
- em_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
- em_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI,
- &pcix_stat_hi_word);
- cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
- PCIX_COMMAND_MMRBC_SHIFT;
- stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
- PCIX_STATUS_HI_MMRBC_SHIFT;
- if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
- stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
- if(cmd_mmrbc > stat_mmrbc) {
- pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
- pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
- em_write_pci_cfg(hw, PCIX_COMMAND_REGISTER,
- &pcix_cmd_word);
- }
- }
- break;
- }
-
- /* Call a subroutine to configure the link and setup flow control. */
- ret_val = em_setup_link(hw);
-
- /* Set the transmit descriptor write-back policy */
- if(hw->mac_type > em_82544) {
- ctrl = E1000_READ_REG(hw, TXDCTL);
- ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
- switch (hw->mac_type) {
- default:
- break;
- case em_82573:
- ctrl |= E1000_TXDCTL_COUNT_DESC;
- break;
- }
- E1000_WRITE_REG(hw, TXDCTL, ctrl);
- }
-
- if (hw->mac_type == em_82573) {
- em_enable_tx_pkt_filtering(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.
- */
- em_clear_hw_cntrs(hw);
-
- return ret_val;
-}
-
-/******************************************************************************
- * Adjust SERDES output amplitude based on EEPROM setting.
- *
- * hw - Struct containing variables accessed by shared code.
- *****************************************************************************/
-static int32_t
-em_adjust_serdes_amplitude(struct em_hw *hw)
-{
- uint16_t eeprom_data;
- int32_t ret_val;
-
- DEBUGFUNC("em_adjust_serdes_amplitude");
-
- if(hw->media_type != em_media_type_internal_serdes)
- return E1000_SUCCESS;
-
- switch(hw->mac_type) {
- case em_82545_rev_3:
- case em_82546_rev_3:
- break;
- default:
- return E1000_SUCCESS;
- }
-
- ret_val = em_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1, &eeprom_data);
- if (ret_val) {
- return ret_val;
- }
-
- if(eeprom_data != EEPROM_RESERVED_WORD) {
- /* Adjust SERDES output amplitude only. */
- eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
- if(ret_val)
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Configures flow control and link settings.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Determines which flow control settings to use. Calls the apropriate media-
- * specific link configuration function. Configures the flow control settings.
- * 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.
- *****************************************************************************/
-int32_t
-em_setup_link(struct em_hw *hw)
-{
- uint32_t ctrl_ext;
- int32_t ret_val;
- uint16_t eeprom_data;
-
- DEBUGFUNC("em_setup_link");
-
- /* Read and store word 0x0F of the EEPROM. This word contains bits
- * that determine the hardware's default PAUSE (flow control) mode,
- * a bit that determines whether the HW defaults to enabling or
- * disabling auto-negotiation, and the direction of the
- * SW defined pins. If there is no SW over-ride of the flow
- * control setting, then the variable hw->fc will
- * be initialized based on a value in the EEPROM.
- */
- if(em_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
-
- if(hw->fc == em_fc_default) {
- if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
- hw->fc = em_fc_none;
- else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
- EEPROM_WORD0F_ASM_DIR)
- hw->fc = em_fc_tx_pause;
- else
- hw->fc = em_fc_full;
- }
-
- /* 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.
- */
- if(hw->mac_type == em_82542_rev2_0)
- hw->fc &= (~em_fc_tx_pause);
-
- if((hw->mac_type < em_82543) && (hw->report_tx_early == 1))
- hw->fc &= (~em_fc_rx_pause);
-
- hw->original_fc = hw->fc;
-
- DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc);
-
- /* Take the 4 bits from EEPROM word 0x0F that determine the initial
- * polarity value for the SW controlled pins, and setup the
- * Extended Device Control reg with that info.
- * This is needed because one of the SW controlled pins is used for
- * signal detection. So this should be done before em_setup_pcs_link()
- * or em_phy_setup() is called.
- */
- if(hw->mac_type == em_82543) {
- ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
- SWDPIO__EXT_SHIFT);
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
- }
-
- /* Call the necessary subroutine to configure the link. */
- ret_val = (hw->media_type == em_media_type_copper) ?
- em_setup_copper_link(hw) :
- em_setup_fiber_serdes_link(hw);
-
- /* 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 the Flow Control address, type and timer regs\n");
-
- E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
- E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
- E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
-
- E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
-
- /* Set the flow control receive threshold registers. Normally,
- * these registers will be set to a default threshold that may be
- * adjusted later by the driver's runtime code. However, if the
- * ability to transmit pause frames in not enabled, then these
- * registers will be set to 0.
- */
- if(!(hw->fc & em_fc_tx_pause)) {
- E1000_WRITE_REG(hw, FCRTL, 0);
- E1000_WRITE_REG(hw, FCRTH, 0);
- } else {
- /* We need to set up the Receive Threshold high and low water marks
- * as well as (optionally) enabling the transmission of XON frames.
- */
- if(hw->fc_send_xon) {
- E1000_WRITE_REG(hw, FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
- E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
- } else {
- E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water);
- E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
- }
- }
- return ret_val;
-}
-
-/******************************************************************************
- * Sets up link for a fiber based or serdes based adapter
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Manipulates Physical Coding Sublayer functions in order to configure
- * link. Assumes the hardware has been previously reset and the transmitter
- * and receiver are not enabled.
- *****************************************************************************/
-static int32_t
-em_setup_fiber_serdes_link(struct em_hw *hw)
-{
- uint32_t ctrl;
- uint32_t status;
- uint32_t txcw = 0;
- uint32_t i;
- uint32_t signal = 0;
- int32_t ret_val;
-
- DEBUGFUNC("em_setup_fiber_serdes_link");
-
- /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
- * set when the optics detect a signal. On older adapters, it will be
- * cleared when there is a signal. This applies to fiber media only.
- * If we're on serdes media, adjust the output amplitude to value set in
- * the EEPROM.
- */
- ctrl = E1000_READ_REG(hw, CTRL);
- if(hw->media_type == em_media_type_fiber)
- signal = (hw->mac_type > em_82544) ? E1000_CTRL_SWDPIN1 : 0;
-
- ret_val = em_adjust_serdes_amplitude(hw);
- if(ret_val)
- return ret_val;
-
- /* Take the link out of reset */
- ctrl &= ~(E1000_CTRL_LRST);
-
- /* Adjust VCO speed to improve BER performance */
- ret_val = em_set_vco_speed(hw);
- if(ret_val)
- return ret_val;
-
- em_config_collision_dist(hw);
-
- /* Check for a software override of the flow control settings, and setup
- * the device accordingly. If auto-negotiation is enabled, then software
- * will have to set the "PAUSE" bits to the correct value in the Tranmsit
- * Config Word Register (TXCW) and re-start auto-negotiation. However, if
- * auto-negotiation is disabled, then software will have to manually
- * configure the two flow control enable bits in the CTRL register.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames, but
- * not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but we do
- * not support receiving pause frames).
- * 3: Both Rx and TX flow control (symmetric) are enabled.
- */
- switch (hw->fc) {
- case em_fc_none:
- /* Flow control is completely disabled by a software over-ride. */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
- break;
- case em_fc_rx_pause:
- /* RX Flow control is enabled and TX Flow control is disabled by a
- * software over-ride. Since there really isn't a way to advertise
- * that we are capable of RX Pause ONLY, we will advertise that we
- * support both symmetric and asymmetric RX PAUSE. Later, we will
- * disable the adapter's ability to send PAUSE frames.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
- break;
- case em_fc_tx_pause:
- /* TX Flow control is enabled, and RX Flow control is disabled, by a
- * software over-ride.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
- break;
- case em_fc_full:
- /* Flow control (both RX and TX) is enabled by a software over-ride. */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
- break;
- default:
- DEBUGOUT("Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- break;
- }
-
- /* Since auto-negotiation is enabled, take the link out of reset (the link
- * will be in reset, because we previously reset the chip). This will
- * restart auto-negotiation. If auto-neogtiation is successful then the
- * link-up status bit will be set and the flow control enable bits (RFCE
- * and TFCE) will be set according to their negotiated value.
- */
- DEBUGOUT("Auto-negotiation enabled\n");
-
- E1000_WRITE_REG(hw, TXCW, txcw);
- E1000_WRITE_REG(hw, CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
-
- hw->txcw = txcw;
- msec_delay(1);
-
- /* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
- * indication in the Device Status Register. Time-out if a link isn't
- * seen in 500 milliseconds seconds (Auto-negotiation should complete in
- * less than 500 milliseconds even if the other end is doing it in SW).
- * For internal serdes, we just assume a signal is present, then poll.
- */
- if(hw->media_type == em_media_type_internal_serdes ||
- (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
- DEBUGOUT("Looking for Link\n");
- for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
- msec_delay(10);
- status = E1000_READ_REG(hw, STATUS);
- if(status & E1000_STATUS_LU) break;
- }
- if(i == (LINK_UP_TIMEOUT / 10)) {
- DEBUGOUT("Never got a valid link from auto-neg!!!\n");
- hw->autoneg_failed = 1;
- /* AutoNeg failed to achieve a link, so we'll call
- * em_check_for_link. This routine will force the link up if
- * we detect a signal. This will allow us to communicate with
- * non-autonegotiating link partners.
- */
- ret_val = em_check_for_link(hw);
- if(ret_val) {
- DEBUGOUT("Error while checking for link\n");
- return ret_val;
- }
- hw->autoneg_failed = 0;
- } else {
- hw->autoneg_failed = 0;
- DEBUGOUT("Valid Link Found\n");
- }
- } else {
- DEBUGOUT("No Signal Detected\n");
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Make sure we have a valid PHY and change PHY mode before link setup.
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static int32_t
-em_copper_link_preconfig(struct em_hw *hw)
-{
- uint32_t ctrl;
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_copper_link_preconfig");
-
- ctrl = E1000_READ_REG(hw, CTRL);
- /* With 82543, we need to force speed and duplex on the MAC equal to what
- * the PHY speed and duplex configuration is. In addition, we need to
- * perform a hardware reset on the PHY to take it out of reset.
- */
- if(hw->mac_type > em_82543) {
- ctrl |= E1000_CTRL_SLU;
- ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- E1000_WRITE_REG(hw, CTRL, ctrl);
- } else {
- ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
- E1000_WRITE_REG(hw, CTRL, ctrl);
- ret_val = em_phy_hw_reset(hw);
- if(ret_val)
- return ret_val;
- }
-
- /* Make sure we have a valid PHY */
- ret_val = em_detect_gig_phy(hw);
- if(ret_val) {
- DEBUGOUT("Error, did not detect valid phy.\n");
- return ret_val;
- }
- DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
-
- /* Set PHY to class A mode (if necessary) */
- ret_val = em_set_phy_mode(hw);
- if(ret_val)
- return ret_val;
-
- if((hw->mac_type == em_82545_rev_3) ||
- (hw->mac_type == em_82546_rev_3)) {
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- phy_data |= 0x00000008;
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- }
-
- if(hw->mac_type <= em_82543 ||
- hw->mac_type == em_82541 || hw->mac_type == em_82547 ||
- hw->mac_type == em_82541_rev_2 || hw->mac_type == em_82547_rev_2)
- hw->phy_reset_disable = FALSE;
-
- return E1000_SUCCESS;
-}
-
-
-/********************************************************************
-* Copper link setup for em_phy_igp series.
-*
-* hw - Struct containing variables accessed by shared code
-*********************************************************************/
-static int32_t
-em_copper_link_igp_setup(struct em_hw *hw)
-{
- uint32_t led_ctrl;
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_copper_link_igp_setup");
-
- if (hw->phy_reset_disable)
- return E1000_SUCCESS;
-
- ret_val = em_phy_reset(hw);
- if (ret_val) {
- DEBUGOUT("Error Resetting the PHY\n");
- return ret_val;
- }
-
- /* Wait 10ms for MAC to configure PHY from eeprom settings */
- msec_delay(15);
-
- /* Configure activity LED after PHY reset */
- led_ctrl = E1000_READ_REG(hw, LEDCTL);
- led_ctrl &= IGP_ACTIVITY_LED_MASK;
- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
- E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
-
- /* disable lplu d3 during driver init */
- ret_val = em_set_d3_lplu_state(hw, FALSE);
- if (ret_val) {
- DEBUGOUT("Error Disabling LPLU D3\n");
- return ret_val;
- }
-
- /* disable lplu d0 during driver init */
- ret_val = em_set_d0_lplu_state(hw, FALSE);
- if (ret_val) {
- DEBUGOUT("Error Disabling LPLU D0\n");
- return ret_val;
- }
- /* Configure mdi-mdix settings */
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- if ((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) {
- hw->dsp_config_state = em_dsp_config_disabled;
- /* Force MDI for earlier revs of the IGP PHY */
- phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | IGP01E1000_PSCR_FORCE_MDI_MDIX);
- hw->mdix = 1;
-
- } else {
- hw->dsp_config_state = em_dsp_config_enabled;
- phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
-
- switch (hw->mdix) {
- case 1:
- phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
- break;
- case 2:
- phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
- break;
- case 0:
- default:
- phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
- break;
- }
- }
- ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
- if(ret_val)
- return ret_val;
-
- /* set auto-master slave resolution settings */
- if(hw->autoneg) {
- em_ms_type phy_ms_setting = hw->master_slave;
-
- if(hw->ffe_config_state == em_ffe_config_active)
- hw->ffe_config_state = em_ffe_config_enabled;
-
- if(hw->dsp_config_state == em_dsp_config_activated)
- hw->dsp_config_state = em_dsp_config_enabled;
-
- /* when autonegotiation advertisment is only 1000Mbps then we
- * should disable SmartSpeed and enable Auto MasterSlave
- * resolution as hardware default. */
- if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
- /* Disable SmartSpeed */
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
- if(ret_val)
- return ret_val;
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = em_write_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if(ret_val)
- return ret_val;
- /* Set auto Master/Slave resolution process */
- ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
- phy_data &= ~CR_1000T_MS_ENABLE;
- ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
- if(ret_val)
- return ret_val;
- }
-
- ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- /* load defaults for future use */
- hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
- ((phy_data & CR_1000T_MS_VALUE) ?
- em_ms_force_master :
- em_ms_force_slave) :
- em_ms_auto;
-
- switch (phy_ms_setting) {
- case em_ms_force_master:
- phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
- break;
- case em_ms_force_slave:
- phy_data |= CR_1000T_MS_ENABLE;
- phy_data &= ~(CR_1000T_MS_VALUE);
- break;
- case em_ms_auto:
- phy_data &= ~CR_1000T_MS_ENABLE;
- default:
- break;
- }
- ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
- if(ret_val)
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-
-/********************************************************************
-* Copper link setup for em_phy_m88 series.
-*
-* hw - Struct containing variables accessed by shared code
-*********************************************************************/
-static int32_t
-em_copper_link_mgp_setup(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_copper_link_mgp_setup");
-
- if(hw->phy_reset_disable)
- return E1000_SUCCESS;
-
- /* Enable CRS on TX. This must be set for half-duplex operation. */
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-
- /* Options:
- * MDI/MDI-X = 0 (default)
- * 0 - Auto for all speeds
- * 1 - MDI mode
- * 2 - MDI-X mode
- * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
- */
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-
- switch (hw->mdix) {
- case 1:
- phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
- break;
- case 2:
- phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
- break;
- case 3:
- phy_data |= M88E1000_PSCR_AUTO_X_1000T;
- break;
- case 0:
- default:
- phy_data |= M88E1000_PSCR_AUTO_X_MODE;
- break;
- }
-
- /* Options:
- * disable_polarity_correction = 0 (default)
- * Automatic Correction for Reversed Cable Polarity
- * 0 - Disabled
- * 1 - Enabled
- */
- phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
- if(hw->disable_polarity_correction == 1)
- phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if(ret_val)
- return ret_val;
-
- /* Force TX_CLK in the Extended PHY Specific Control Register
- * to 25MHz clock.
- */
- ret_val = em_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data |= M88E1000_EPSCR_TX_CLK_25;
-
- if (hw->phy_revision < M88E1011_I_REV_4) {
- /* Configure Master and Slave downshift values */
- phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
- M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
- phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
- M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
- ret_val = em_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
- if(ret_val)
- return ret_val;
- }
-
- /* SW Reset the PHY so all changes take effect */
- ret_val = em_phy_reset(hw);
- if(ret_val) {
- DEBUGOUT("Error Resetting the PHY\n");
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/********************************************************************
-* Setup auto-negotiation and flow control advertisements,
-* and then perform auto-negotiation.
-*
-* hw - Struct containing variables accessed by shared code
-*********************************************************************/
-static int32_t
-em_copper_link_autoneg(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_copper_link_autoneg");
-
- /* Perform some bounds checking on the hw->autoneg_advertised
- * parameter. If this variable is zero, then set it to the default.
- */
- hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
-
- /* If autoneg_advertised is zero, we assume it was not defaulted
- * by the calling code so we set to advertise full capability.
- */
- if(hw->autoneg_advertised == 0)
- hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
-
- DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
- ret_val = em_phy_setup_autoneg(hw);
- if(ret_val) {
- DEBUGOUT("Error Setting up Auto-Negotiation\n");
- return ret_val;
- }
- DEBUGOUT("Restarting Auto-Neg\n");
-
- /* Restart auto-negotiation by setting the Auto Neg Enable bit and
- * the Auto Neg Restart bit in the PHY control register.
- */
- ret_val = em_read_phy_reg(hw, PHY_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
- ret_val = em_write_phy_reg(hw, PHY_CTRL, phy_data);
- if(ret_val)
- return ret_val;
-
- /* Does the user want to wait for Auto-Neg to complete here, or
- * check at a later time (for example, callback routine).
- */
- if(hw->wait_autoneg_complete) {
- ret_val = em_wait_autoneg(hw);
- if(ret_val) {
- DEBUGOUT("Error while waiting for autoneg to complete\n");
- return ret_val;
- }
- }
-
- hw->get_link_status = TRUE;
-
- return E1000_SUCCESS;
-}
-
-
-/******************************************************************************
-* Config the MAC and the PHY after link is up.
-* 1) Set up the MAC to the current PHY speed/duplex
-* if we are on 82543. If we
-* are on newer silicon, we only need to configure
-* collision distance in the Transmit Control Register.
-* 2) Set up flow control on the MAC to that established with
-* the link partner.
-* 3) Config DSP to improve Gigabit link quality for some PHY revisions.
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static int32_t
-em_copper_link_postconfig(struct em_hw *hw)
-{
- int32_t ret_val;
- DEBUGFUNC("em_copper_link_postconfig");
-
- if(hw->mac_type >= em_82544) {
- em_config_collision_dist(hw);
- } else {
- ret_val = em_config_mac_to_phy(hw);
- if(ret_val) {
- DEBUGOUT("Error configuring MAC to PHY settings\n");
- return ret_val;
- }
- }
- ret_val = em_config_fc_after_link_up(hw);
- if(ret_val) {
- DEBUGOUT("Error Configuring Flow Control\n");
- return ret_val;
- }
-
- /* Config DSP to improve Giga link quality */
- if(hw->phy_type == em_phy_igp) {
- ret_val = em_config_dsp_after_link_change(hw, TRUE);
- if(ret_val) {
- DEBUGOUT("Error Configuring DSP after link up\n");
- return ret_val;
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Detects which PHY is present and setup the speed and duplex
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static int32_t
-em_setup_copper_link(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t i;
- uint16_t phy_data;
-
- DEBUGFUNC("em_setup_copper_link");
-
- /* Check if it is a valid PHY and set PHY mode if necessary. */
- ret_val = em_copper_link_preconfig(hw);
- if(ret_val)
- return ret_val;
-
- if (hw->phy_type == em_phy_igp ||
- hw->phy_type == em_phy_igp_2) {
- ret_val = em_copper_link_igp_setup(hw);
- if(ret_val)
- return ret_val;
- } else if (hw->phy_type == em_phy_m88) {
- ret_val = em_copper_link_mgp_setup(hw);
- if(ret_val)
- return ret_val;
- }
-
- if(hw->autoneg) {
- /* Setup autoneg and flow control advertisement
- * and perform autonegotiation */
- ret_val = em_copper_link_autoneg(hw);
- if(ret_val)
- return ret_val;
- } else {
- /* PHY will be set to 10H, 10F, 100H,or 100F
- * depending on value from forced_speed_duplex. */
- DEBUGOUT("Forcing speed and duplex\n");
- ret_val = em_phy_force_speed_duplex(hw);
- if(ret_val) {
- DEBUGOUT("Error Forcing Speed and Duplex\n");
- return ret_val;
- }
- }
-
- /* Check link status. Wait up to 100 microseconds for link to become
- * valid.
- */
- for(i = 0; i < 10; i++) {
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
-
- if(phy_data & MII_SR_LINK_STATUS) {
- /* Config the MAC and PHY after link is up */
- ret_val = em_copper_link_postconfig(hw);
- if(ret_val)
- return ret_val;
-
- DEBUGOUT("Valid link established!!!\n");
- return E1000_SUCCESS;
- }
- usec_delay(10);
- }
-
- DEBUGOUT("Unable to establish link!!!\n");
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Configures PHY autoneg and flow control advertisement settings
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-int32_t
-em_phy_setup_autoneg(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t mii_autoneg_adv_reg;
- uint16_t mii_1000t_ctrl_reg;
-
- DEBUGFUNC("em_phy_setup_autoneg");
-
- /* Read the MII Auto-Neg Advertisement Register (Address 4). */
- ret_val = em_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
- if(ret_val)
- return ret_val;
-
- /* Read the MII 1000Base-T Control Register (Address 9). */
- ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
- if(ret_val)
- return ret_val;
-
- /* Need to parse both autoneg_advertised and fc and set up
- * the appropriate PHY registers. First we will parse for
- * autoneg_advertised software override. Since we can advertise
- * a plethora of combinations, we need to check each bit
- * individually.
- */
-
- /* First we clear all the 10/100 mb speed bits in the Auto-Neg
- * Advertisement Register (Address 4) and the 1000 mb speed bits in
- * the 1000Base-T Control Register (Address 9).
- */
- mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
- mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
-
- DEBUGOUT1("autoneg_advertised %x\n", hw->autoneg_advertised);
-
- /* Do we want to advertise 10 Mb Half Duplex? */
- if(hw->autoneg_advertised & ADVERTISE_10_HALF) {
- DEBUGOUT("Advertise 10mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
- }
-
- /* Do we want to advertise 10 Mb Full Duplex? */
- if(hw->autoneg_advertised & ADVERTISE_10_FULL) {
- DEBUGOUT("Advertise 10mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Half Duplex? */
- if(hw->autoneg_advertised & ADVERTISE_100_HALF) {
- DEBUGOUT("Advertise 100mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Full Duplex? */
- if(hw->autoneg_advertised & ADVERTISE_100_FULL) {
- DEBUGOUT("Advertise 100mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
- }
-
- /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
- if(hw->autoneg_advertised & ADVERTISE_1000_HALF) {
- DEBUGOUT("Advertise 1000mb Half duplex requested, request denied!\n");
- }
-
- /* Do we want to advertise 1000 Mb Full Duplex? */
- if(hw->autoneg_advertised & ADVERTISE_1000_FULL) {
- DEBUGOUT("Advertise 1000mb Full duplex\n");
- mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
- }
-
- /* Check for a software override of the flow control settings, and
- * setup the PHY advertisement registers accordingly. If
- * auto-negotiation is enabled, then software will have to set the
- * "PAUSE" bits to the correct value in the Auto-Negotiation
- * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames
- * but we do not support receiving pause frames).
- * 3: Both Rx and TX flow control (symmetric) are enabled.
- * other: No software override. The flow control configuration
- * in the EEPROM is used.
- */
- switch (hw->fc) {
- case em_fc_none: /* 0 */
- /* Flow control (RX & TX) is completely disabled by a
- * software over-ride.
- */
- mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- case em_fc_rx_pause: /* 1 */
- /* RX Flow control is enabled, and TX Flow control is
- * disabled, by a software over-ride.
- */
- /* Since there really isn't a way to advertise that we are
- * capable of RX Pause ONLY, we will advertise that we
- * support both symmetric and asymmetric RX PAUSE. Later
- * (in em_config_fc_after_link_up) we will disable the
- *hw's ability to send PAUSE frames.
- */
- mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- case em_fc_tx_pause: /* 2 */
- /* TX Flow control is enabled, and RX Flow control is
- * disabled, by a software over-ride.
- */
- mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
- mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
- break;
- case em_fc_full: /* 3 */
- /* Flow control (both RX and TX) is enabled by a software
- * over-ride.
- */
- mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- default:
- DEBUGOUT("Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = em_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
- if(ret_val)
- return ret_val;
-
- DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
-
- ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
- if(ret_val)
- return ret_val;
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Force PHY speed and duplex settings to hw->forced_speed_duplex
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static int32_t
-em_phy_force_speed_duplex(struct em_hw *hw)
-{
- uint32_t ctrl;
- int32_t ret_val;
- uint16_t mii_ctrl_reg;
- uint16_t mii_status_reg;
- uint16_t phy_data;
- uint16_t i;
-
- DEBUGFUNC("em_phy_force_speed_duplex");
-
- /* Turn off Flow control if we are forcing speed and duplex. */
- hw->fc = em_fc_none;
-
- DEBUGOUT1("hw->fc = %d\n", hw->fc);
-
- /* Read the Device Control Register. */
- ctrl = E1000_READ_REG(hw, CTRL);
-
- /* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
- ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- ctrl &= ~(DEVICE_SPEED_MASK);
-
- /* Clear the Auto Speed Detect Enable bit. */
- ctrl &= ~E1000_CTRL_ASDE;
-
- /* Read the MII Control Register. */
- ret_val = em_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
- if(ret_val)
- return ret_val;
-
- /* We need to disable autoneg in order to force link and duplex. */
-
- mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;
-
- /* Are we forcing Full or Half Duplex? */
- if(hw->forced_speed_duplex == em_100_full ||
- hw->forced_speed_duplex == em_10_full) {
- /* We want to force full duplex so we SET the full duplex bits in the
- * Device and MII Control Registers.
- */
- ctrl |= E1000_CTRL_FD;
- mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
- DEBUGOUT("Full Duplex\n");
- } else {
- /* We want to force half duplex so we CLEAR the full duplex bits in
- * the Device and MII Control Registers.
- */
- ctrl &= ~E1000_CTRL_FD;
- mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX;
- DEBUGOUT("Half Duplex\n");
- }
-
- /* Are we forcing 100Mbps??? */
- if(hw->forced_speed_duplex == em_100_full ||
- hw->forced_speed_duplex == em_100_half) {
- /* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
- ctrl |= E1000_CTRL_SPD_100;
- mii_ctrl_reg |= MII_CR_SPEED_100;
- mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
- DEBUGOUT("Forcing 100mb ");
- } else {
- /* Set the 10Mb bit and turn off the 1000Mb and 100Mb bits. */
- ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
- mii_ctrl_reg |= MII_CR_SPEED_10;
- mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
- DEBUGOUT("Forcing 10mb ");
- }
-
- em_config_collision_dist(hw);
-
- /* Write the configured values back to the Device Control Reg. */
- E1000_WRITE_REG(hw, CTRL, ctrl);
-
- if (hw->phy_type == em_phy_m88) {
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
- * forced whenever speed are duplex are forced.
- */
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if(ret_val)
- return ret_val;
-
- DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
-
- /* Need to reset the PHY or these changes will be ignored */
- mii_ctrl_reg |= MII_CR_RESET;
- } else {
- /* Clear Auto-Crossover to force MDI manually. IGP requires MDI
- * forced whenever speed or duplex are forced.
- */
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
- phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
-
- ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
- if(ret_val)
- return ret_val;
- }
-
- /* Write back the modified PHY MII control register. */
- ret_val = em_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg);
- if(ret_val)
- return ret_val;
-
- usec_delay(1);
-
- /* The wait_autoneg_complete flag may be a little misleading here.
- * Since we are forcing speed and duplex, Auto-Neg is not enabled.
- * But we do want to delay for a period while forcing only so we
- * don't generate false No Link messages. So we will wait here
- * only if the user has set wait_autoneg_complete to 1, which is
- * the default.
- */
- if(hw->wait_autoneg_complete) {
- /* We will wait for autoneg to complete. */
- DEBUGOUT("Waiting for forced speed/duplex link.\n");
- mii_status_reg = 0;
-
- /* We will wait for autoneg to complete or 4.5 seconds to expire. */
- for(i = PHY_FORCE_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Auto-Neg Complete bit
- * to be set.
- */
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
-
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
-
- if(mii_status_reg & MII_SR_LINK_STATUS) break;
- msec_delay(100);
- }
- if((i == 0) &&
- (hw->phy_type == em_phy_m88)) {
- /* We didn't get link. Reset the DSP and wait again for link. */
- ret_val = em_phy_reset_dsp(hw);
- if(ret_val) {
- DEBUGOUT("Error Resetting PHY DSP\n");
- return ret_val;
- }
- }
- /* This loop will early-out if the link condition has been met. */
- for(i = PHY_FORCE_TIME; i > 0; i--) {
- if(mii_status_reg & MII_SR_LINK_STATUS) break;
- msec_delay(100);
- /* Read the MII Status Register and wait for Auto-Neg Complete bit
- * to be set.
- */
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
-
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
- }
- }
-
- if (hw->phy_type == em_phy_m88) {
- /* Because we reset the PHY above, we need to re-force TX_CLK in the
- * Extended PHY Specific Control Register to 25MHz clock. This value
- * defaults back to a 2.5MHz clock when the PHY is reset.
- */
- ret_val = em_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data |= M88E1000_EPSCR_TX_CLK_25;
- ret_val = em_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
- if(ret_val)
- return ret_val;
-
- /* In addition, because of the s/w reset above, we need to enable CRS on
- * TX. This must be set for both full and half duplex operation.
- */
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if(ret_val)
- return ret_val;
-
- if((hw->mac_type == em_82544 || hw->mac_type == em_82543) &&
- (!hw->autoneg) &&
- (hw->forced_speed_duplex == em_10_full ||
- hw->forced_speed_duplex == em_10_half)) {
- ret_val = em_polarity_reversal_workaround(hw);
- if(ret_val)
- return ret_val;
- }
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Sets the collision distance in the Transmit Control register
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Link should have been established previously. Reads the speed and duplex
-* information from the Device Status register.
-******************************************************************************/
-void
-em_config_collision_dist(struct em_hw *hw)
-{
- uint32_t tctl;
-
- DEBUGFUNC("em_config_collision_dist");
-
- tctl = E1000_READ_REG(hw, TCTL);
-
- tctl &= ~E1000_TCTL_COLD;
- tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
-
- E1000_WRITE_REG(hw, TCTL, tctl);
- E1000_WRITE_FLUSH(hw);
-}
-
-/******************************************************************************
-* Sets MAC speed and duplex settings to reflect the those in the PHY
-*
-* hw - Struct containing variables accessed by shared code
-* mii_reg - data to write to the MII control register
-*
-* The contents of the PHY register containing the needed information need to
-* be passed in.
-******************************************************************************/
-static int32_t
-em_config_mac_to_phy(struct em_hw *hw)
-{
- uint32_t ctrl;
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_config_mac_to_phy");
-
- /* 82544 or newer MAC, Auto Speed Detection takes care of
- * MAC speed/duplex configuration.*/
- if (hw->mac_type >= em_82544)
- return E1000_SUCCESS;
-
- /* Read the Device Control Register and set the bits to Force Speed
- * and Duplex.
- */
- ctrl = E1000_READ_REG(hw, CTRL);
- ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
-
- /* Set up duplex in the Device Control and Transmit Control
- * registers depending on negotiated values.
- */
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
-
- if(phy_data & M88E1000_PSSR_DPLX)
- ctrl |= E1000_CTRL_FD;
- else
- ctrl &= ~E1000_CTRL_FD;
-
- em_config_collision_dist(hw);
-
- /* Set up speed in the Device Control register depending on
- * negotiated values.
- */
- if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
- ctrl |= E1000_CTRL_SPD_1000;
- else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
- ctrl |= E1000_CTRL_SPD_100;
-
- /* Write the configured values back to the Device Control Reg. */
- E1000_WRITE_REG(hw, CTRL, ctrl);
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Forces the MAC's flow control settings.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Sets the TFCE and RFCE bits in the device control register to reflect
- * the adapter settings. TFCE and RFCE need to be explicitly set by
- * software when a Copper PHY is used because autonegotiation is managed
- * by the PHY rather than the MAC. Software must also configure these
- * bits when link is forced on a fiber connection.
- *****************************************************************************/
-int32_t
-em_force_mac_fc(struct em_hw *hw)
-{
- uint32_t ctrl;
-
- DEBUGFUNC("em_force_mac_fc");
-
- /* Get the current configuration of the Device Control Register */
- ctrl = E1000_READ_REG(hw, CTRL);
-
- /* Because we didn't get link via the internal auto-negotiation
- * mechanism (we either forced link or we got link via PHY
- * auto-neg), we have to manually enable/disable transmit an
- * receive flow control.
- *
- * The "Case" statement below enables/disable flow control
- * according to the "hw->fc" parameter.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause
- * frames but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames
- * frames but we do not receive pause frames).
- * 3: Both Rx and TX flow control (symmetric) is enabled.
- * other: No other values should be possible at this point.
- */
-
- switch (hw->fc) {
- case em_fc_none:
- ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
- break;
- case em_fc_rx_pause:
- ctrl &= (~E1000_CTRL_TFCE);
- ctrl |= E1000_CTRL_RFCE;
- break;
- case em_fc_tx_pause:
- ctrl &= (~E1000_CTRL_RFCE);
- ctrl |= E1000_CTRL_TFCE;
- break;
- case em_fc_full:
- ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
- break;
- default:
- DEBUGOUT("Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- }
-
- /* Disable TX Flow Control for 82542 (rev 2.0) */
- if(hw->mac_type == em_82542_rev2_0)
- ctrl &= (~E1000_CTRL_TFCE);
-
- E1000_WRITE_REG(hw, CTRL, ctrl);
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Configures flow control settings after link is established
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Should be called immediately after a valid link has been established.
- * Forces MAC flow control settings if link was forced. When in MII/GMII mode
- * and autonegotiation is enabled, the MAC flow control settings will be set
- * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
- * and RFCE bits will be automaticaly set to the negotiated flow control mode.
- *****************************************************************************/
-int32_t
-em_config_fc_after_link_up(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t mii_status_reg;
- uint16_t mii_nway_adv_reg;
- uint16_t mii_nway_lp_ability_reg;
- uint16_t speed;
- uint16_t duplex;
-
- DEBUGFUNC("em_config_fc_after_link_up");
-
- /* Check for the case where we have fiber media and auto-neg failed
- * so we had to force link. In this case, we need to force the
- * configuration of the MAC to match the "fc" parameter.
- */
- if(((hw->media_type == em_media_type_fiber) && (hw->autoneg_failed)) ||
- ((hw->media_type == em_media_type_internal_serdes) && (hw->autoneg_failed)) ||
- ((hw->media_type == em_media_type_copper) && (!hw->autoneg))) {
- ret_val = em_force_mac_fc(hw);
- if(ret_val) {
- DEBUGOUT("Error forcing flow control settings\n");
- return ret_val;
- }
- }
-
- /* Check for the case where we have copper media and auto-neg is
- * enabled. In this case, we need to check and see if Auto-Neg
- * has completed, and if so, how the PHY and link partner has
- * flow control configured.
- */
- if((hw->media_type == em_media_type_copper) && hw->autoneg) {
- /* Read the MII Status Register and check to see if AutoNeg
- * has completed. We read this twice because this reg has
- * some "sticky" (latched) bits.
- */
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
-
- if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
- /* The AutoNeg process has completed, so we now need to
- * read both the Auto Negotiation Advertisement Register
- * (Address 4) and the Auto_Negotiation Base Page Ability
- * Register (Address 5) to determine how flow control was
- * negotiated.
- */
- ret_val = em_read_phy_reg(hw, PHY_AUTONEG_ADV,
- &mii_nway_adv_reg);
- if(ret_val)
- return ret_val;
- ret_val = em_read_phy_reg(hw, PHY_LP_ABILITY,
- &mii_nway_lp_ability_reg);
- if(ret_val)
- return ret_val;
-
- /* Two bits in the Auto Negotiation Advertisement Register
- * (Address 4) and two bits in the Auto Negotiation Base
- * Page Ability Register (Address 5) determine flow control
- * for both the PHY and the link partner. The following
- * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
- * 1999, describes these PAUSE resolution bits and how flow
- * control is determined based upon these settings.
- * NOTE: DC = Don't Care
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
- *-------|---------|-------|---------|--------------------
- * 0 | 0 | DC | DC | em_fc_none
- * 0 | 1 | 0 | DC | em_fc_none
- * 0 | 1 | 1 | 0 | em_fc_none
- * 0 | 1 | 1 | 1 | em_fc_tx_pause
- * 1 | 0 | 0 | DC | em_fc_none
- * 1 | DC | 1 | DC | em_fc_full
- * 1 | 1 | 0 | 0 | em_fc_none
- * 1 | 1 | 0 | 1 | em_fc_rx_pause
- *
- */
- /* Are both PAUSE bits set to 1? If so, this implies
- * Symmetric Flow Control is enabled at both ends. The
- * ASM_DIR bits are irrelevant per the spec.
- *
- * For Symmetric Flow Control:
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | DC | 1 | DC | em_fc_full
- *
- */
- if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
- /* Now we need to check if the user selected RX ONLY
- * of pause frames. In this case, we had to advertise
- * FULL flow control because we could not advertise RX
- * ONLY. Hence, we must now check to see if we need to
- * turn OFF the TRANSMISSION of PAUSE frames.
- */
- if(hw->original_fc == em_fc_full) {
- hw->fc = em_fc_full;
- DEBUGOUT("Flow Control = FULL.\r\n");
- } else {
- hw->fc = em_fc_rx_pause;
- DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
- }
- }
- /* For receiving PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 0 | 1 | 1 | 1 | em_fc_tx_pause
- *
- */
- else if(!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = em_fc_tx_pause;
- DEBUGOUT("Flow Control = TX PAUSE frames only.\r\n");
- }
- /* For transmitting PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | 1 | 0 | 1 | em_fc_rx_pause
- *
- */
- else if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
- !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = em_fc_rx_pause;
- DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
- }
- /* Per the IEEE spec, at this point flow control should be
- * disabled. However, we want to consider that we could
- * be connected to a legacy switch that doesn't advertise
- * desired flow control, but can be forced on the link
- * partner. So if we advertised no flow control, that is
- * what we will resolve to. If we advertised some kind of
- * receive capability (Rx Pause Only or Full Flow Control)
- * and the link partner advertised none, we will configure
- * ourselves to enable Rx Flow Control only. We can do
- * this safely for two reasons: If the link partner really
- * didn't want flow control enabled, and we enable Rx, no
- * harm done since we won't be receiving any PAUSE frames
- * anyway. If the intent on the link partner was to have
- * flow control enabled, then by us enabling RX only, we
- * can at least receive pause frames and process them.
- * This is a good idea because in most cases, since we are
- * predominantly a server NIC, more times than not we will
- * be asked to delay transmission of packets than asking
- * our link partner to pause transmission of frames.
- */
- else if((hw->original_fc == em_fc_none ||
- hw->original_fc == em_fc_tx_pause) ||
- hw->fc_strict_ieee) {
- hw->fc = em_fc_none;
- DEBUGOUT("Flow Control = NONE.\r\n");
- } else {
- hw->fc = em_fc_rx_pause;
- DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
- }
-
- /* Now we need to do one last check... If we auto-
- * negotiated to HALF DUPLEX, flow control should not be
- * enabled per IEEE 802.3 spec.
- */
- ret_val = em_get_speed_and_duplex(hw, &speed, &duplex);
- if(ret_val) {
- DEBUGOUT("Error getting link speed and duplex\n");
- return ret_val;
- }
-
- if(duplex == HALF_DUPLEX)
- hw->fc = em_fc_none;
-
- /* Now we call a subroutine to actually force the MAC
- * controller to use the correct flow control settings.
- */
- ret_val = em_force_mac_fc(hw);
- if(ret_val) {
- DEBUGOUT("Error forcing flow control settings\n");
- return ret_val;
- }
- } else {
- DEBUGOUT("Copper PHY and Auto Neg has not completed.\r\n");
- }
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Checks to see if the link status of the hardware has changed.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Called by any function that needs to check the link status of the adapter.
- *****************************************************************************/
-int32_t
-em_check_for_link(struct em_hw *hw)
-{
- uint32_t rxcw = 0;
- uint32_t ctrl;
- uint32_t status;
- uint32_t rctl;
- uint32_t icr;
- uint32_t signal = 0;
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_check_for_link");
-
- ctrl = E1000_READ_REG(hw, CTRL);
- status = E1000_READ_REG(hw, STATUS);
-
- /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
- * set when the optics detect a signal. On older adapters, it will be
- * cleared when there is a signal. This applies to fiber media only.
- */
- if((hw->media_type == em_media_type_fiber) ||
- (hw->media_type == em_media_type_internal_serdes)) {
- rxcw = E1000_READ_REG(hw, RXCW);
-
- if(hw->media_type == em_media_type_fiber) {
- signal = (hw->mac_type > em_82544) ? E1000_CTRL_SWDPIN1 : 0;
- if(status & E1000_STATUS_LU)
- hw->get_link_status = FALSE;
- }
- }
-
- /* If we have a copper PHY then we only want to go out to the PHY
- * registers to see if Auto-Neg has completed and/or if our link
- * status has changed. The get_link_status flag will be set if we
- * receive a Link Status Change interrupt or we have Rx Sequence
- * Errors.
- */
- if((hw->media_type == em_media_type_copper) && hw->get_link_status) {
- /* First we want to see if the MII Status Register reports
- * link. If so, then we want to get the current speed/duplex
- * of the PHY.
- * Read the register twice since the link bit is sticky.
- */
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
-
- if(phy_data & MII_SR_LINK_STATUS) {
- hw->get_link_status = FALSE;
- /* Check if there was DownShift, must be checked immediately after
- * link-up */
- em_check_downshift(hw);
-
- /* If we are on 82544 or 82543 silicon and speed/duplex
- * are forced to 10H or 10F, then we will implement the polarity
- * reversal workaround. We disable interrupts first, and upon
- * returning, place the devices interrupt state to its previous
- * value except for the link status change interrupt which will
- * happen due to the execution of this workaround.
- */
-
- if((hw->mac_type == em_82544 || hw->mac_type == em_82543) &&
- (!hw->autoneg) &&
- (hw->forced_speed_duplex == em_10_full ||
- hw->forced_speed_duplex == em_10_half)) {
- E1000_WRITE_REG(hw, IMC, 0xffffffff);
- ret_val = em_polarity_reversal_workaround(hw);
- icr = E1000_READ_REG(hw, ICR);
- E1000_WRITE_REG(hw, ICS, (icr & ~E1000_ICS_LSC));
- E1000_WRITE_REG(hw, IMS, IMS_ENABLE_MASK);
- }
-
- } else {
- /* No link detected */
- em_config_dsp_after_link_change(hw, FALSE);
- return 0;
- }
-
- /* If we are forcing speed/duplex, then we simply return since
- * we have already determined whether we have link or not.
- */
- if(!hw->autoneg) return -E1000_ERR_CONFIG;
-
- /* optimize the dsp settings for the igp phy */
- em_config_dsp_after_link_change(hw, TRUE);
-
- /* We have a M88E1000 PHY and Auto-Neg is enabled. If we
- * have Si on board that is 82544 or newer, Auto
- * Speed Detection takes care of MAC speed/duplex
- * configuration. So we only need to configure Collision
- * Distance in the MAC. Otherwise, we need to force
- * speed/duplex on the MAC to the current PHY speed/duplex
- * settings.
- */
- if(hw->mac_type >= em_82544)
- em_config_collision_dist(hw);
- else {
- ret_val = em_config_mac_to_phy(hw);
- if(ret_val) {
- DEBUGOUT("Error configuring MAC to PHY settings\n");
- return ret_val;
- }
- }
-
- /* Configure Flow Control now that Auto-Neg has completed. First, we
- * need to restore the desired flow control settings because we may
- * have had to re-autoneg with a different link partner.
- */
- ret_val = em_config_fc_after_link_up(hw);
- if(ret_val) {
- DEBUGOUT("Error configuring flow control\n");
- return ret_val;
- }
-
- /* At this point we know that we are on copper and we have
- * auto-negotiated link. These are conditions for checking the link
- * partner capability register. We use the link speed to determine if
- * TBI compatibility needs to be turned on or off. If the link is not
- * at gigabit speed, then TBI compatibility is not needed. If we are
- * at gigabit speed, we turn on TBI compatibility.
- */
- if(hw->tbi_compatibility_en) {
- uint16_t speed, duplex;
- em_get_speed_and_duplex(hw, &speed, &duplex);
- if(speed != SPEED_1000) {
- /* If link speed is not set to gigabit speed, we do not need
- * to enable TBI compatibility.
- */
- if(hw->tbi_compatibility_on) {
- /* If we previously were in the mode, turn it off. */
- rctl = E1000_READ_REG(hw, RCTL);
- rctl &= ~E1000_RCTL_SBP;
- E1000_WRITE_REG(hw, RCTL, rctl);
- hw->tbi_compatibility_on = FALSE;
- }
- } else {
- /* If TBI compatibility is was previously off, turn it on. For
- * compatibility with a TBI link partner, we will store bad
- * packets. Some frames have an additional byte on the end and
- * will look like CRC errors to to the hardware.
- */
- if(!hw->tbi_compatibility_on) {
- hw->tbi_compatibility_on = TRUE;
- rctl = E1000_READ_REG(hw, RCTL);
- rctl |= E1000_RCTL_SBP;
- E1000_WRITE_REG(hw, RCTL, rctl);
- }
- }
- }
- }
- /* If we don't have link (auto-negotiation failed or link partner cannot
- * auto-negotiate), the cable is plugged in (we have signal), and our
- * link partner is not trying to auto-negotiate with us (we are receiving
- * idles or data), we need to force link up. We also need to give
- * auto-negotiation time to complete, in case the cable was just plugged
- * in. The autoneg_failed flag does this.
- */
- else if((((hw->media_type == em_media_type_fiber) &&
- ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
- (hw->media_type == em_media_type_internal_serdes)) &&
- (!(status & E1000_STATUS_LU)) &&
- (!(rxcw & E1000_RXCW_C))) {
- if(hw->autoneg_failed == 0) {
- hw->autoneg_failed = 1;
- return 0;
- }
- DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");
-
- /* Disable auto-negotiation in the TXCW register */
- E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));
-
- /* Force link-up and also force full-duplex. */
- ctrl = E1000_READ_REG(hw, CTRL);
- ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
- E1000_WRITE_REG(hw, CTRL, ctrl);
-
- /* Configure Flow Control after forcing link up. */
- ret_val = em_config_fc_after_link_up(hw);
- if(ret_val) {
- DEBUGOUT("Error configuring flow control\n");
- return ret_val;
- }
- }
- /* If we are forcing link and we are receiving /C/ ordered sets, re-enable
- * auto-negotiation in the TXCW register and disable forced link in the
- * Device Control register in an attempt to auto-negotiate with our link
- * partner.
- */
- else if(((hw->media_type == em_media_type_fiber) ||
- (hw->media_type == em_media_type_internal_serdes)) &&
- (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
- DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
- E1000_WRITE_REG(hw, TXCW, hw->txcw);
- E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
-
- hw->serdes_link_down = FALSE;
- }
- /* If we force link for non-auto-negotiation switch, check link status
- * based on MAC synchronization for internal serdes media type.
- */
- else if((hw->media_type == em_media_type_internal_serdes) &&
- !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
- /* SYNCH bit and IV bit are sticky. */
- usec_delay(10);
- if(E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) {
- if(!(rxcw & E1000_RXCW_IV)) {
- hw->serdes_link_down = FALSE;
- DEBUGOUT("SERDES: Link is up.\n");
- }
- } else {
- hw->serdes_link_down = TRUE;
- DEBUGOUT("SERDES: Link is down.\n");
- }
- }
- if((hw->media_type == em_media_type_internal_serdes) &&
- (E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
- hw->serdes_link_down = !(E1000_STATUS_LU & E1000_READ_REG(hw, STATUS));
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Detects the current speed and duplex settings of the hardware.
- *
- * hw - Struct containing variables accessed by shared code
- * speed - Speed of the connection
- * duplex - Duplex setting of the connection
- *****************************************************************************/
-int32_t
-em_get_speed_and_duplex(struct em_hw *hw,
- uint16_t *speed,
- uint16_t *duplex)
-{
- uint32_t status;
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_get_speed_and_duplex");
-
- if(hw->mac_type >= em_82543) {
- status = E1000_READ_REG(hw, STATUS);
- if(status & E1000_STATUS_SPEED_1000) {
- *speed = SPEED_1000;
- DEBUGOUT("1000 Mbs, ");
- } else if(status & E1000_STATUS_SPEED_100) {
- *speed = SPEED_100;
- DEBUGOUT("100 Mbs, ");
- } else {
- *speed = SPEED_10;
- DEBUGOUT("10 Mbs, ");
- }
-
- if(status & E1000_STATUS_FD) {
- *duplex = FULL_DUPLEX;
- DEBUGOUT("Full Duplex\r\n");
- } else {
- *duplex = HALF_DUPLEX;
- DEBUGOUT(" Half Duplex\r\n");
- }
- } else {
- DEBUGOUT("1000 Mbs, Full Duplex\r\n");
- *speed = SPEED_1000;
- *duplex = FULL_DUPLEX;
- }
-
- /* IGP01 PHY may advertise full duplex operation after speed downgrade even
- * if it is operating at half duplex. Here we set the duplex settings to
- * match the duplex in the link partner's capabilities.
- */
- if(hw->phy_type == em_phy_igp && hw->speed_downgraded) {
- ret_val = em_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
- if(ret_val)
- return ret_val;
-
- if(!(phy_data & NWAY_ER_LP_NWAY_CAPS))
- *duplex = HALF_DUPLEX;
- else {
- ret_val = em_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
- if(ret_val)
- return ret_val;
- if((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
- (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
- *duplex = HALF_DUPLEX;
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Blocks until autoneg completes or times out (~4.5 seconds)
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-int32_t
-em_wait_autoneg(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t i;
- uint16_t phy_data;
-
- DEBUGFUNC("em_wait_autoneg");
- DEBUGOUT("Waiting for Auto-Neg to complete.\n");
-
- /* We will wait for autoneg to complete or 4.5 seconds to expire. */
- for(i = PHY_AUTO_NEG_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Auto-Neg
- * Complete bit to be set.
- */
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
- if(phy_data & MII_SR_AUTONEG_COMPLETE) {
- return E1000_SUCCESS;
- }
- msec_delay(100);
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Raises the Management Data Clock
-*
-* hw - Struct containing variables accessed by shared code
-* ctrl - Device control register's current value
-******************************************************************************/
-static void
-em_raise_mdi_clk(struct em_hw *hw,
- uint32_t *ctrl)
-{
- /* Raise the clock input to the Management Data Clock (by setting the MDC
- * bit), and then delay 10 microseconds.
- */
- E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
- E1000_WRITE_FLUSH(hw);
- usec_delay(10);
-}
-
-/******************************************************************************
-* Lowers the Management Data Clock
-*
-* hw - Struct containing variables accessed by shared code
-* ctrl - Device control register's current value
-******************************************************************************/
-static void
-em_lower_mdi_clk(struct em_hw *hw,
- uint32_t *ctrl)
-{
- /* Lower the clock input to the Management Data Clock (by clearing the MDC
- * bit), and then delay 10 microseconds.
- */
- E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
- E1000_WRITE_FLUSH(hw);
- usec_delay(10);
-}
-
-/******************************************************************************
-* Shifts data bits out to the PHY
-*
-* hw - Struct containing variables accessed by shared code
-* data - Data to send out to the PHY
-* count - Number of bits to shift out
-*
-* Bits are shifted out in MSB to LSB order.
-******************************************************************************/
-static void
-em_shift_out_mdi_bits(struct em_hw *hw,
- uint32_t data,
- uint16_t count)
-{
- uint32_t ctrl;
- uint32_t mask;
-
- /* We need to shift "count" number of bits out to the PHY. So, the value
- * in the "data" parameter will be shifted out to the PHY one bit at a
- * time. In order to do this, "data" must be broken down into bits.
- */
- mask = 0x01;
- mask <<= (count - 1);
-
- ctrl = E1000_READ_REG(hw, CTRL);
-
- /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
- ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
-
- while(mask) {
- /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
- * then raising and lowering the Management Data Clock. A "0" is
- * shifted out to the PHY by setting the MDIO bit to "0" and then
- * raising and lowering the clock.
- */
- if(data & mask) ctrl |= E1000_CTRL_MDIO;
- else ctrl &= ~E1000_CTRL_MDIO;
-
- E1000_WRITE_REG(hw, CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
-
- usec_delay(10);
-
- em_raise_mdi_clk(hw, &ctrl);
- em_lower_mdi_clk(hw, &ctrl);
-
- mask = mask >> 1;
- }
-}
-
-/******************************************************************************
-* Shifts data bits in from the PHY
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Bits are shifted in in MSB to LSB order.
-******************************************************************************/
-static uint16_t
-em_shift_in_mdi_bits(struct em_hw *hw)
-{
- uint32_t ctrl;
- uint16_t data = 0;
- uint8_t i;
-
- /* In order to read a register from the PHY, we need to shift in a total
- * of 18 bits from the PHY. The first two bit (turnaround) times are used
- * to avoid contention on the MDIO pin when a read operation is performed.
- * These two bits are ignored by us and thrown away. Bits are "shifted in"
- * by raising the input to the Management Data Clock (setting the MDC bit),
- * and then reading the value of the MDIO bit.
- */
- ctrl = E1000_READ_REG(hw, CTRL);
-
- /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
- ctrl &= ~E1000_CTRL_MDIO_DIR;
- ctrl &= ~E1000_CTRL_MDIO;
-
- E1000_WRITE_REG(hw, CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
-
- /* Raise and Lower the clock before reading in the data. This accounts for
- * the turnaround bits. The first clock occurred when we clocked out the
- * last bit of the Register Address.
- */
- em_raise_mdi_clk(hw, &ctrl);
- em_lower_mdi_clk(hw, &ctrl);
-
- for(data = 0, i = 0; i < 16; i++) {
- data = data << 1;
- em_raise_mdi_clk(hw, &ctrl);
- ctrl = E1000_READ_REG(hw, CTRL);
- /* Check to see if we shifted in a "1". */
- if(ctrl & E1000_CTRL_MDIO) data |= 1;
- em_lower_mdi_clk(hw, &ctrl);
- }
-
- em_raise_mdi_clk(hw, &ctrl);
- em_lower_mdi_clk(hw, &ctrl);
-
- return data;
-}
-
-/*****************************************************************************
-* Reads the value from a PHY register, if the value is on a specific non zero
-* page, sets the page first.
-* hw - Struct containing variables accessed by shared code
-* reg_addr - address of the PHY register to read
-******************************************************************************/
-int32_t
-em_read_phy_reg(struct em_hw *hw,
- uint32_t reg_addr,
- uint16_t *phy_data)
-{
- uint32_t ret_val;
-
- DEBUGFUNC("em_read_phy_reg");
-
- if((hw->phy_type == em_phy_igp ||
- hw->phy_type == em_phy_igp_2) &&
- (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
- ret_val = em_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
- (uint16_t)reg_addr);
- if(ret_val) {
- return ret_val;
- }
- }
-
- ret_val = em_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
- phy_data);
-
- return ret_val;
-}
-
-int32_t
-em_read_phy_reg_ex(struct em_hw *hw,
- uint32_t reg_addr,
- uint16_t *phy_data)
-{
- uint32_t i;
- uint32_t mdic = 0;
- const uint32_t phy_addr = 1;
-
- DEBUGFUNC("em_read_phy_reg_ex");
-
- if(reg_addr > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
- return -E1000_ERR_PARAM;
- }
-
- if(hw->mac_type > em_82543) {
- /* Set up Op-code, Phy Address, and register address in the MDI
- * Control register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
- (phy_addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_READ));
-
- E1000_WRITE_REG(hw, MDIC, mdic);
-
- /* Poll the ready bit to see if the MDI read completed */
- for(i = 0; i < 64; i++) {
- usec_delay(50);
- mdic = E1000_READ_REG(hw, MDIC);
- if(mdic & E1000_MDIC_READY) break;
- }
- if(!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Read did not complete\n");
- return -E1000_ERR_PHY;
- }
- if(mdic & E1000_MDIC_ERROR) {
- DEBUGOUT("MDI Error\n");
- return -E1000_ERR_PHY;
- }
- *phy_data = (uint16_t) mdic;
- } else {
- /* We must first send a preamble through the MDIO pin to signal the
- * beginning of an MII instruction. This is done by sending 32
- * consecutive "1" bits.
- */
- em_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
-
- /* Now combine the next few fields that are required for a read
- * operation. We use this method instead of calling the
- * em_shift_out_mdi_bits routine five different times. The format of
- * a MII read instruction consists of a shift out of 14 bits and is
- * defined as follows:
- * <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
- * followed by a shift in of 18 bits. This first two bits shifted in
- * are TurnAround bits used to avoid contention on the MDIO pin when a
- * READ operation is performed. These two bits are thrown away
- * followed by a shift in of 16 bits which contains the desired data.
- */
- mdic = ((reg_addr) | (phy_addr << 5) |
- (PHY_OP_READ << 10) | (PHY_SOF << 12));
-
- em_shift_out_mdi_bits(hw, mdic, 14);
-
- /* Now that we've shifted out the read command to the MII, we need to
- * "shift in" the 16-bit value (18 total bits) of the requested PHY
- * register address.
- */
- *phy_data = em_shift_in_mdi_bits(hw);
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Writes a value to a PHY register
-*
-* hw - Struct containing variables accessed by shared code
-* reg_addr - address of the PHY register to write
-* data - data to write to the PHY
-******************************************************************************/
-int32_t
-em_write_phy_reg(struct em_hw *hw,
- uint32_t reg_addr,
- uint16_t phy_data)
-{
- uint32_t ret_val;
-
- DEBUGFUNC("em_write_phy_reg");
-
- if((hw->phy_type == em_phy_igp ||
- hw->phy_type == em_phy_igp_2) &&
- (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
- ret_val = em_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
- (uint16_t)reg_addr);
- if(ret_val) {
- return ret_val;
- }
- }
-
- ret_val = em_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
- phy_data);
-
- return ret_val;
-}
-
-int32_t
-em_write_phy_reg_ex(struct em_hw *hw,
- uint32_t reg_addr,
- uint16_t phy_data)
-{
- uint32_t i;
- uint32_t mdic = 0;
- const uint32_t phy_addr = 1;
-
- DEBUGFUNC("em_write_phy_reg_ex");
-
- if(reg_addr > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
- return -E1000_ERR_PARAM;
- }
-
- if(hw->mac_type > em_82543) {
- /* Set up Op-code, Phy Address, register address, and data intended
- * for the PHY register in the MDI Control register. The MAC will take
- * care of interfacing with the PHY to send the desired data.
- */
- mdic = (((uint32_t) phy_data) |
- (reg_addr << E1000_MDIC_REG_SHIFT) |
- (phy_addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_WRITE));
-
- E1000_WRITE_REG(hw, MDIC, mdic);
-
- /* Poll the ready bit to see if the MDI read completed */
- for(i = 0; i < 640; i++) {
- usec_delay(5);
- mdic = E1000_READ_REG(hw, MDIC);
- if(mdic & E1000_MDIC_READY) break;
- }
- if(!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Write did not complete\n");
- return -E1000_ERR_PHY;
- }
- } else {
- /* We'll need to use the SW defined pins to shift the write command
- * out to the PHY. We first send a preamble to the PHY to signal the
- * beginning of the MII instruction. This is done by sending 32
- * consecutive "1" bits.
- */
- em_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
-
- /* Now combine the remaining required fields that will indicate a
- * write operation. We use this method instead of calling the
- * em_shift_out_mdi_bits routine for each field in the command. The
- * format of a MII write instruction is as follows:
- * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
- */
- mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
- (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
- mdic <<= 16;
- mdic |= (uint32_t) phy_data;
-
- em_shift_out_mdi_bits(hw, mdic, 32);
- }
-
- return E1000_SUCCESS;
-}
-
-
-/******************************************************************************
-* Returns the PHY to the power-on reset state
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-int32_t
-em_phy_hw_reset(struct em_hw *hw)
-{
- uint32_t ctrl, ctrl_ext;
- uint32_t led_ctrl;
- int32_t ret_val;
-
- DEBUGFUNC("em_phy_hw_reset");
-
- /* In the case of the phy reset being blocked, it's not an error, we
- * simply return success without performing the reset. */
- ret_val = em_check_phy_reset_block(hw);
- if (ret_val)
- return E1000_SUCCESS;
-
- DEBUGOUT("Resetting Phy...\n");
-
- if(hw->mac_type > em_82543) {
- /* Read the device control register and assert the E1000_CTRL_PHY_RST
- * bit. Then, take it out of reset.
- */
- ctrl = E1000_READ_REG(hw, CTRL);
- E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
- E1000_WRITE_FLUSH(hw);
- msec_delay(10);
- E1000_WRITE_REG(hw, CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
- } else {
- /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
- * bit to put the PHY into reset. Then, take it out of reset.
- */
- ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
- ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH(hw);
- msec_delay(10);
- ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH(hw);
- }
- usec_delay(150);
-
- if((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) {
- /* Configure activity LED after PHY reset */
- led_ctrl = E1000_READ_REG(hw, LEDCTL);
- led_ctrl &= IGP_ACTIVITY_LED_MASK;
- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
- E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
- }
-
- /* Wait for FW to finish PHY configuration. */
- ret_val = em_get_phy_cfg_done(hw);
-
- return ret_val;
-}
-
-/******************************************************************************
-* Resets the PHY
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Sets bit 15 of the MII Control regiser
-******************************************************************************/
-int32_t
-em_phy_reset(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_phy_reset");
-
- /* In the case of the phy reset being blocked, it's not an error, we
- * simply return success without performing the reset. */
- ret_val = em_check_phy_reset_block(hw);
- if (ret_val)
- return E1000_SUCCESS;
-
- switch (hw->mac_type) {
- case em_82541_rev_2:
- ret_val = em_phy_hw_reset(hw);
- if(ret_val)
- return ret_val;
- break;
- default:
- ret_val = em_read_phy_reg(hw, PHY_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data |= MII_CR_RESET;
- ret_val = em_write_phy_reg(hw, PHY_CTRL, phy_data);
- if(ret_val)
- return ret_val;
-
- usec_delay(1);
- break;
- }
-
- if(hw->phy_type == em_phy_igp || hw->phy_type == em_phy_igp_2)
- em_phy_init_script(hw);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Probes the expected PHY address for known PHY IDs
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-int32_t
-em_detect_gig_phy(struct em_hw *hw)
-{
- int32_t phy_init_status, ret_val;
- uint16_t phy_id_high, phy_id_low;
- boolean_t match = FALSE;
-
- DEBUGFUNC("em_detect_gig_phy");
-
- /* Read the PHY ID Registers to identify which PHY is onboard. */
- ret_val = em_read_phy_reg(hw, PHY_ID1, &phy_id_high);
- if(ret_val)
- return ret_val;
-
- hw->phy_id = (uint32_t) (phy_id_high << 16);
- usec_delay(20);
- ret_val = em_read_phy_reg(hw, PHY_ID2, &phy_id_low);
- if(ret_val)
- return ret_val;
-
- hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
- hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
-
- switch(hw->mac_type) {
- case em_82543:
- if(hw->phy_id == M88E1000_E_PHY_ID) match = TRUE;
- break;
- case em_82544:
- if(hw->phy_id == M88E1000_I_PHY_ID) match = TRUE;
- break;
- case em_82540:
- case em_82545:
- case em_82545_rev_3:
- case em_82546:
- case em_82546_rev_3:
- if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
- break;
- case em_82541:
- case em_82541_rev_2:
- case em_82547:
- case em_82547_rev_2:
- if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
- break;
- case em_82573:
- if(hw->phy_id == M88E1111_I_PHY_ID) match = TRUE;
- break;
- default:
- DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
- return -E1000_ERR_CONFIG;
- }
- phy_init_status = em_set_phy_type(hw);
-
- if ((match) && (phy_init_status == E1000_SUCCESS)) {
- DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
- return E1000_SUCCESS;
- }
- DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
- return -E1000_ERR_PHY;
-}
-
-/******************************************************************************
-* Resets the PHY's DSP
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static int32_t
-em_phy_reset_dsp(struct em_hw *hw)
-{
- int32_t ret_val;
- DEBUGFUNC("em_phy_reset_dsp");
-
- do {
- ret_val = em_write_phy_reg(hw, 29, 0x001d);
- if(ret_val) break;
- ret_val = em_write_phy_reg(hw, 30, 0x00c1);
- if(ret_val) break;
- ret_val = em_write_phy_reg(hw, 30, 0x0000);
- if(ret_val) break;
- ret_val = E1000_SUCCESS;
- } while(0);
-
- return ret_val;
-}
-
-/******************************************************************************
-* Get PHY information from various PHY registers for igp PHY only.
-*
-* hw - Struct containing variables accessed by shared code
-* phy_info - PHY information structure
-******************************************************************************/
-int32_t
-em_phy_igp_get_info(struct em_hw *hw,
- struct em_phy_info *phy_info)
-{
- int32_t ret_val;
- uint16_t phy_data, polarity, min_length, max_length, average;
-
- DEBUGFUNC("em_phy_igp_get_info");
-
- /* The downshift status is checked only once, after link is established,
- * and it stored in the hw->speed_downgraded parameter. */
- phy_info->downshift = (em_downshift)hw->speed_downgraded;
-
- /* IGP01E1000 does not need to support it. */
- phy_info->extended_10bt_distance = em_10bt_ext_dist_enable_normal;
-
- /* IGP01E1000 always correct polarity reversal */
- phy_info->polarity_correction = em_polarity_reversal_enabled;
-
- /* Check polarity status */
- ret_val = em_check_polarity(hw, &polarity);
- if(ret_val)
- return ret_val;
-
- phy_info->cable_polarity = polarity;
-
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
- IGP01E1000_PSSR_MDIX_SHIFT;
-
- if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
- /* Local/Remote Receiver Information are only valid at 1000 Mbps */
- ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
- SR_1000T_LOCAL_RX_STATUS_SHIFT;
- phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
- SR_1000T_REMOTE_RX_STATUS_SHIFT;
-
- /* Get cable length */
- ret_val = em_get_cable_length(hw, &min_length, &max_length);
- if(ret_val)
- return ret_val;
-
- /* Translate to old method */
- average = (max_length + min_length) / 2;
-
- if(average <= em_igp_cable_length_50)
- phy_info->cable_length = em_cable_length_50;
- else if(average <= em_igp_cable_length_80)
- phy_info->cable_length = em_cable_length_50_80;
- else if(average <= em_igp_cable_length_110)
- phy_info->cable_length = em_cable_length_80_110;
- else if(average <= em_igp_cable_length_140)
- phy_info->cable_length = em_cable_length_110_140;
- else
- phy_info->cable_length = em_cable_length_140;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Get PHY information from various PHY registers fot m88 PHY only.
-*
-* hw - Struct containing variables accessed by shared code
-* phy_info - PHY information structure
-******************************************************************************/
-int32_t
-em_phy_m88_get_info(struct em_hw *hw,
- struct em_phy_info *phy_info)
-{
- int32_t ret_val;
- uint16_t phy_data, polarity;
-
- DEBUGFUNC("em_phy_m88_get_info");
-
- /* The downshift status is checked only once, after link is established,
- * and it stored in the hw->speed_downgraded parameter. */
- phy_info->downshift = (em_downshift)hw->speed_downgraded;
-
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_info->extended_10bt_distance =
- (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
- M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
- phy_info->polarity_correction =
- (phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
- M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
-
- /* Check polarity status */
- ret_val = em_check_polarity(hw, &polarity);
- if(ret_val)
- return ret_val;
- phy_info->cable_polarity = polarity;
-
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
- M88E1000_PSSR_MDIX_SHIFT;
-
- if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
- /* Cable Length Estimation and Local/Remote Receiver Information
- * are only valid at 1000 Mbps.
- */
- phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
- M88E1000_PSSR_CABLE_LENGTH_SHIFT);
-
- ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
- SR_1000T_LOCAL_RX_STATUS_SHIFT;
-
- phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
- SR_1000T_REMOTE_RX_STATUS_SHIFT;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Get PHY information from various PHY registers
-*
-* hw - Struct containing variables accessed by shared code
-* phy_info - PHY information structure
-******************************************************************************/
-int32_t
-em_phy_get_info(struct em_hw *hw,
- struct em_phy_info *phy_info)
-{
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_phy_get_info");
-
- phy_info->cable_length = em_cable_length_undefined;
- phy_info->extended_10bt_distance = em_10bt_ext_dist_enable_undefined;
- phy_info->cable_polarity = em_rev_polarity_undefined;
- phy_info->downshift = em_downshift_undefined;
- phy_info->polarity_correction = em_polarity_reversal_undefined;
- phy_info->mdix_mode = em_auto_x_mode_undefined;
- phy_info->local_rx = em_1000t_rx_status_undefined;
- phy_info->remote_rx = em_1000t_rx_status_undefined;
-
- if(hw->media_type != em_media_type_copper) {
- DEBUGOUT("PHY info is only valid for copper media\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
-
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if(ret_val)
- return ret_val;
-
- if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
- DEBUGOUT("PHY info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
- if(hw->phy_type == em_phy_igp ||
- hw->phy_type == em_phy_igp_2)
- return em_phy_igp_get_info(hw, phy_info);
- else
- return em_phy_m88_get_info(hw, phy_info);
-}
-
-int32_t
-em_validate_mdi_setting(struct em_hw *hw)
-{
- DEBUGFUNC("em_validate_mdi_settings");
-
- if(!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
- DEBUGOUT("Invalid MDI setting detected\n");
- hw->mdix = 1;
- return -E1000_ERR_CONFIG;
- }
- return E1000_SUCCESS;
-}
-
-
-/******************************************************************************
- * Sets up eeprom variables in the hw struct. Must be called after mac_type
- * is configured.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_init_eeprom_params(struct em_hw *hw)
-{
- struct em_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd = E1000_READ_REG(hw, EECD);
- int32_t ret_val = E1000_SUCCESS;
- uint16_t eeprom_size;
-
- DEBUGFUNC("em_init_eeprom_params");
-
- switch (hw->mac_type) {
- case em_82542_rev2_0:
- case em_82542_rev2_1:
- case em_82543:
- case em_82544:
- eeprom->type = em_eeprom_microwire;
- eeprom->word_size = 64;
- eeprom->opcode_bits = 3;
- eeprom->address_bits = 6;
- eeprom->delay_usec = 50;
- eeprom->use_eerd = FALSE;
- eeprom->use_eewr = FALSE;
- break;
- case em_82540:
- case em_82545:
- case em_82545_rev_3:
- case em_82546:
- case em_82546_rev_3:
- eeprom->type = em_eeprom_microwire;
- eeprom->opcode_bits = 3;
- eeprom->delay_usec = 50;
- if(eecd & E1000_EECD_SIZE) {
- eeprom->word_size = 256;
- eeprom->address_bits = 8;
- } else {
- eeprom->word_size = 64;
- eeprom->address_bits = 6;
- }
- eeprom->use_eerd = FALSE;
- eeprom->use_eewr = FALSE;
- break;
- case em_82541:
- case em_82541_rev_2:
- case em_82547:
- case em_82547_rev_2:
- if (eecd & E1000_EECD_TYPE) {
- eeprom->type = em_eeprom_spi;
- eeprom->opcode_bits = 8;
- eeprom->delay_usec = 1;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->page_size = 32;
- eeprom->address_bits = 16;
- } else {
- eeprom->page_size = 8;
- eeprom->address_bits = 8;
- }
- } else {
- eeprom->type = em_eeprom_microwire;
- eeprom->opcode_bits = 3;
- eeprom->delay_usec = 50;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->word_size = 256;
- eeprom->address_bits = 8;
- } else {
- eeprom->word_size = 64;
- eeprom->address_bits = 6;
- }
- }
- eeprom->use_eerd = FALSE;
- eeprom->use_eewr = FALSE;
- break;
- case em_82573:
- eeprom->type = em_eeprom_spi;
- eeprom->opcode_bits = 8;
- eeprom->delay_usec = 1;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->page_size = 32;
- eeprom->address_bits = 16;
- } else {
- eeprom->page_size = 8;
- eeprom->address_bits = 8;
- }
- eeprom->use_eerd = TRUE;
- eeprom->use_eewr = TRUE;
- if(em_is_onboard_nvm_eeprom(hw) == FALSE) {
- eeprom->type = em_eeprom_flash;
- eeprom->word_size = 2048;
-
- /* Ensure that the Autonomous FLASH update bit is cleared due to
- * Flash update issue on parts which use a FLASH for NVM. */
- eecd &= ~E1000_EECD_AUPDEN;
- E1000_WRITE_REG(hw, EECD, eecd);
- }
- break;
- default:
- break;
- }
-
- if (eeprom->type == em_eeprom_spi) {
- /* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
- * 32KB (incremented by powers of 2).
- */
- if(hw->mac_type <= em_82547_rev_2) {
- /* Set to default value for initial eeprom read. */
- eeprom->word_size = 64;
- ret_val = em_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
- if(ret_val)
- return ret_val;
- eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
- /* 256B eeprom size was not supported in earlier hardware, so we
- * bump eeprom_size up one to ensure that "1" (which maps to 256B)
- * is never the result used in the shifting logic below. */
- if(eeprom_size)
- eeprom_size++;
- } else {
- eeprom_size = (uint16_t)((eecd & E1000_EECD_SIZE_EX_MASK) >>
- E1000_EECD_SIZE_EX_SHIFT);
- }
-
- eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
- }
- return ret_val;
-}
-
-/******************************************************************************
- * Raises the EEPROM's clock input.
- *
- * hw - Struct containing variables accessed by shared code
- * eecd - EECD's current value
- *****************************************************************************/
-static void
-em_raise_ee_clk(struct em_hw *hw,
- uint32_t *eecd)
-{
- /* Raise the clock input to the EEPROM (by setting the SK bit), and then
- * wait <delay> microseconds.
- */
- *eecd = *eecd | E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, *eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(hw->eeprom.delay_usec);
-}
-
-/******************************************************************************
- * Lowers the EEPROM's clock input.
- *
- * hw - Struct containing variables accessed by shared code
- * eecd - EECD's current value
- *****************************************************************************/
-static void
-em_lower_ee_clk(struct em_hw *hw,
- uint32_t *eecd)
-{
- /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
- * wait 50 microseconds.
- */
- *eecd = *eecd & ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, *eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(hw->eeprom.delay_usec);
-}
-
-/******************************************************************************
- * Shift data bits out to the EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * data - data to send to the EEPROM
- * count - number of bits to shift out
- *****************************************************************************/
-static void
-em_shift_out_ee_bits(struct em_hw *hw,
- uint16_t data,
- uint16_t count)
-{
- struct em_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd;
- uint32_t mask;
-
- /* We need to shift "count" bits out to the EEPROM. So, value in the
- * "data" parameter will be shifted out to the EEPROM one bit at a time.
- * In order to do this, "data" must be broken down into bits.
- */
- mask = 0x01 << (count - 1);
- eecd = E1000_READ_REG(hw, EECD);
- if (eeprom->type == em_eeprom_microwire) {
- eecd &= ~E1000_EECD_DO;
- } else if (eeprom->type == em_eeprom_spi) {
- eecd |= E1000_EECD_DO;
- }
- do {
- /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
- * and then raising and then lowering the clock (the SK bit controls
- * the clock input to the EEPROM). A "0" is shifted out to the EEPROM
- * by setting "DI" to "0" and then raising and then lowering the clock.
- */
- eecd &= ~E1000_EECD_DI;
-
- if(data & mask)
- eecd |= E1000_EECD_DI;
-
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-
- usec_delay(eeprom->delay_usec);
-
- em_raise_ee_clk(hw, &eecd);
- em_lower_ee_clk(hw, &eecd);
-
- mask = mask >> 1;
-
- } while(mask);
-
- /* We leave the "DI" bit set to "0" when we leave this routine. */
- eecd &= ~E1000_EECD_DI;
- E1000_WRITE_REG(hw, EECD, eecd);
-}
-
-/******************************************************************************
- * Shift data bits in from the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static uint16_t
-em_shift_in_ee_bits(struct em_hw *hw,
- uint16_t count)
-{
- uint32_t eecd;
- uint32_t i;
- uint16_t data;
-
- /* 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 "DO" bit. During this "shifting in" process the "DI" bit should
- * always be clear.
- */
-
- eecd = E1000_READ_REG(hw, EECD);
-
- eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
- data = 0;
-
- for(i = 0; i < count; i++) {
- data = data << 1;
- em_raise_ee_clk(hw, &eecd);
-
- eecd = E1000_READ_REG(hw, EECD);
-
- eecd &= ~(E1000_EECD_DI);
- if(eecd & E1000_EECD_DO)
- data |= 1;
-
- em_lower_ee_clk(hw, &eecd);
- }
-
- return data;
-}
-
-/******************************************************************************
- * Prepares EEPROM for access
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
- * function should be called before issuing a command to the EEPROM.
- *****************************************************************************/
-static int32_t
-em_acquire_eeprom(struct em_hw *hw)
-{
- struct em_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd, i=0;
-
- DEBUGFUNC("em_acquire_eeprom");
-
- if(em_get_hw_eeprom_semaphore(hw))
- return -E1000_ERR_EEPROM;
-
- eecd = E1000_READ_REG(hw, EECD);
-
- if (hw->mac_type != em_82573) {
- /* Request EEPROM Access */
- if(hw->mac_type > em_82544) {
- eecd |= E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
- eecd = E1000_READ_REG(hw, EECD);
- while((!(eecd & E1000_EECD_GNT)) &&
- (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
- i++;
- usec_delay(5);
- eecd = E1000_READ_REG(hw, EECD);
- }
- if(!(eecd & E1000_EECD_GNT)) {
- eecd &= ~E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
- DEBUGOUT("Could not acquire EEPROM grant\n");
- return -E1000_ERR_EEPROM;
- }
- }
- }
-
- /* Setup EEPROM for Read/Write */
-
- if (eeprom->type == em_eeprom_microwire) {
- /* Clear SK and DI */
- eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
- E1000_WRITE_REG(hw, EECD, eecd);
-
- /* Set CS */
- eecd |= E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- } else if (eeprom->type == em_eeprom_spi) {
- /* Clear SK and CS */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- E1000_WRITE_REG(hw, EECD, eecd);
- usec_delay(1);
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Returns EEPROM to a "standby" state
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void
-em_standby_eeprom(struct em_hw *hw)
-{
- struct em_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd;
-
- eecd = E1000_READ_REG(hw, EECD);
-
- if(eeprom->type == em_eeprom_microwire) {
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(eeprom->delay_usec);
-
- /* Clock high */
- eecd |= E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(eeprom->delay_usec);
-
- /* Select EEPROM */
- eecd |= E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(eeprom->delay_usec);
-
- /* Clock low */
- eecd &= ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(eeprom->delay_usec);
- } else if(eeprom->type == em_eeprom_spi) {
- /* Toggle CS to flush commands */
- eecd |= E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(eeprom->delay_usec);
- eecd &= ~E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(eeprom->delay_usec);
- }
-}
-
-/******************************************************************************
- * Terminates a command by inverting the EEPROM's chip select pin
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void
-em_release_eeprom(struct em_hw *hw)
-{
- uint32_t eecd;
-
- DEBUGFUNC("em_release_eeprom");
-
- eecd = E1000_READ_REG(hw, EECD);
-
- if (hw->eeprom.type == em_eeprom_spi) {
- eecd |= E1000_EECD_CS; /* Pull CS high */
- eecd &= ~E1000_EECD_SK; /* Lower SCK */
-
- E1000_WRITE_REG(hw, EECD, eecd);
-
- usec_delay(hw->eeprom.delay_usec);
- } else if(hw->eeprom.type == em_eeprom_microwire) {
- /* cleanup eeprom */
-
- /* CS on Microwire is active-high */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
-
- E1000_WRITE_REG(hw, EECD, eecd);
-
- /* Rising edge of clock */
- eecd |= E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(hw->eeprom.delay_usec);
-
- /* Falling edge of clock */
- eecd &= ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(hw->eeprom.delay_usec);
- }
-
- /* Stop requesting EEPROM access */
- if(hw->mac_type > em_82544) {
- eecd &= ~E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
- }
-
- em_put_hw_eeprom_semaphore(hw);
-}
-
-/******************************************************************************
- * Reads a 16 bit word from the EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_spi_eeprom_ready(struct em_hw *hw)
-{
- uint16_t retry_count = 0;
- uint8_t spi_stat_reg;
-
- DEBUGFUNC("em_spi_eeprom_ready");
-
- /* Read "Status Register" repeatedly until the LSB is cleared. The
- * EEPROM will signal that the command has been completed by clearing
- * bit 0 of the internal status register. If it's not cleared within
- * 5 milliseconds, then error out.
- */
- retry_count = 0;
- do {
- em_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
- hw->eeprom.opcode_bits);
- spi_stat_reg = (uint8_t)em_shift_in_ee_bits(hw, 8);
- if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
- break;
-
- usec_delay(5);
- retry_count += 5;
-
- em_standby_eeprom(hw);
- } while(retry_count < EEPROM_MAX_RETRY_SPI);
-
- /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
- * only 0-5mSec on 5V devices)
- */
- if(retry_count >= EEPROM_MAX_RETRY_SPI) {
- DEBUGOUT("SPI EEPROM Status error\n");
- return -E1000_ERR_EEPROM;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Reads a 16 bit word from the EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- *****************************************************************************/
-int32_t
-em_read_eeprom(struct em_hw *hw,
- uint16_t offset,
- uint16_t words,
- uint16_t *data)
-{
- struct em_eeprom_info *eeprom = &hw->eeprom;
- uint32_t i = 0;
- int32_t ret_val;
-
- DEBUGFUNC("em_read_eeprom");
-
- /* A check for invalid values: offset too large, too many words, and not
- * enough words.
- */
- if((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
- (words == 0)) {
- DEBUGOUT("\"words\" parameter out of bounds\n");
- return -E1000_ERR_EEPROM;
- }
-
- /* FLASH reads without acquiring the semaphore are safe in 82573-based
- * controllers.
- */
- if ((em_is_onboard_nvm_eeprom(hw) == TRUE) ||
- (hw->mac_type != em_82573)) {
- /* Prepare the EEPROM for reading */
- if(em_acquire_eeprom(hw) != E1000_SUCCESS)
- return -E1000_ERR_EEPROM;
- }
-
- if(eeprom->use_eerd == TRUE) {
- ret_val = em_read_eeprom_eerd(hw, offset, words, data);
- if ((em_is_onboard_nvm_eeprom(hw) == TRUE) ||
- (hw->mac_type != em_82573))
- em_release_eeprom(hw);
- return ret_val;
- }
-
- if(eeprom->type == em_eeprom_spi) {
- uint16_t word_in;
- uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
-
- if(em_spi_eeprom_ready(hw)) {
- em_release_eeprom(hw);
- return -E1000_ERR_EEPROM;
- }
-
- em_standby_eeprom(hw);
-
- /* Some SPI eeproms use the 8th address bit embedded in the opcode */
- if((eeprom->address_bits == 8) && (offset >= 128))
- read_opcode |= EEPROM_A8_OPCODE_SPI;
-
- /* Send the READ command (opcode + addr) */
- em_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
- em_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits);
-
- /* Read the data. The address of the eeprom internally increments with
- * each byte (spi) being read, saving on the overhead of eeprom setup
- * and tear-down. The address counter will roll over if reading beyond
- * the size of the eeprom, thus allowing the entire memory to be read
- * starting from any offset. */
- for (i = 0; i < words; i++) {
- word_in = em_shift_in_ee_bits(hw, 16);
- data[i] = (word_in >> 8) | (word_in << 8);
- }
- } else if(eeprom->type == em_eeprom_microwire) {
- for (i = 0; i < words; i++) {
- /* Send the READ command (opcode + addr) */
- em_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
- eeprom->opcode_bits);
- em_shift_out_ee_bits(hw, (uint16_t)(offset + i),
- eeprom->address_bits);
-
- /* Read the data. For microwire, each word requires the overhead
- * of eeprom setup and tear-down. */
- data[i] = em_shift_in_ee_bits(hw, 16);
- em_standby_eeprom(hw);
- }
- }
-
- /* End this read operation */
- em_release_eeprom(hw);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Reads a 16 bit word from the EEPROM using the EERD register.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- *****************************************************************************/
-int32_t
-em_read_eeprom_eerd(struct em_hw *hw,
- uint16_t offset,
- uint16_t words,
- uint16_t *data)
-{
- uint32_t i, eerd = 0;
- int32_t error = 0;
-
- for (i = 0; i < words; i++) {
- eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) +
- E1000_EEPROM_RW_REG_START;
-
- E1000_WRITE_REG(hw, EERD, eerd);
- error = em_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);
-
- if(error) {
- break;
- }
- data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA);
-
- }
-
- return error;
-}
-
-/******************************************************************************
- * Writes a 16 bit word from the EEPROM using the EEWR register.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- *****************************************************************************/
-int32_t
-em_write_eeprom_eewr(struct em_hw *hw,
- uint16_t offset,
- uint16_t words,
- uint16_t *data)
-{
- uint32_t register_value = 0;
- uint32_t i = 0;
- int32_t error = 0;
-
- for (i = 0; i < words; i++) {
- register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) |
- ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) |
- E1000_EEPROM_RW_REG_START;
-
- error = em_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
- if(error) {
- break;
- }
-
- E1000_WRITE_REG(hw, EEWR, register_value);
-
- error = em_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
-
- if(error) {
- break;
- }
- }
-
- return error;
-}
-
-/******************************************************************************
- * Polls the status bit (bit 1) of the EERD to determine when the read is done.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_poll_eerd_eewr_done(struct em_hw *hw, int eerd)
-{
- uint32_t attempts = 100000;
- uint32_t i, reg = 0;
- int32_t done = E1000_ERR_EEPROM;
-
- for(i = 0; i < attempts; i++) {
- if(eerd == E1000_EEPROM_POLL_READ)
- reg = E1000_READ_REG(hw, EERD);
- else
- reg = E1000_READ_REG(hw, EEWR);
-
- if(reg & E1000_EEPROM_RW_REG_DONE) {
- done = E1000_SUCCESS;
- break;
- }
- usec_delay(5);
- }
-
- return done;
-}
-
-/***************************************************************************
-* Description: Determines if the onboard NVM is FLASH or EEPROM.
-*
-* hw - Struct containing variables accessed by shared code
-****************************************************************************/
-boolean_t
-em_is_onboard_nvm_eeprom(struct em_hw *hw)
-{
- uint32_t eecd = 0;
-
- if(hw->mac_type == em_82573) {
- eecd = E1000_READ_REG(hw, EECD);
-
- /* Isolate bits 15 & 16 */
- eecd = ((eecd >> 15) & 0x03);
-
- /* If both bits are set, device is Flash type */
- if(eecd == 0x03) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-/******************************************************************************
- * Verifies that the EEPROM has a valid checksum
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Reads the first 64 16 bit words of the EEPROM and sums the values read.
- * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
- * valid.
- *****************************************************************************/
-int32_t
-em_validate_eeprom_checksum(struct em_hw *hw)
-{
- uint16_t checksum = 0;
- uint16_t i, eeprom_data;
-
- DEBUGFUNC("em_validate_eeprom_checksum");
-
- if ((hw->mac_type == em_82573) &&
- (em_is_onboard_nvm_eeprom(hw) == FALSE)) {
- /* Check bit 4 of word 10h. If it is 0, firmware is done updating
- * 10h-12h. Checksum may need to be fixed. */
- em_read_eeprom(hw, 0x10, 1, &eeprom_data);
- if ((eeprom_data & 0x10) == 0) {
- /* Read 0x23 and check bit 15. This bit is a 1 when the checksum
- * has already been fixed. If the checksum is still wrong and this
- * bit is a 1, we need to return bad checksum. Otherwise, we need
- * to set this bit to a 1 and update the checksum. */
- em_read_eeprom(hw, 0x23, 1, &eeprom_data);
- if ((eeprom_data & 0x8000) == 0) {
- eeprom_data |= 0x8000;
- em_write_eeprom(hw, 0x23, 1, &eeprom_data);
- em_update_eeprom_checksum(hw);
- }
- }
- }
-
- for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
- if(em_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- checksum += eeprom_data;
- }
-
- if(checksum == (uint16_t) EEPROM_SUM)
- return E1000_SUCCESS;
- else {
- DEBUGOUT("EEPROM Checksum Invalid\n");
- return -E1000_ERR_EEPROM;
- }
-}
-
-/******************************************************************************
- * Calculates the EEPROM checksum and writes it to the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
- * Writes the difference to word offset 63 of the EEPROM.
- *****************************************************************************/
-int32_t
-em_update_eeprom_checksum(struct em_hw *hw)
-{
- uint16_t checksum = 0;
- uint16_t i, eeprom_data;
-
- DEBUGFUNC("em_update_eeprom_checksum");
-
- for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
- if(em_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- checksum += eeprom_data;
- }
- checksum = (uint16_t) EEPROM_SUM - checksum;
- if(em_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
- DEBUGOUT("EEPROM Write Error\n");
- return -E1000_ERR_EEPROM;
- } else if (hw->eeprom.type == em_eeprom_flash) {
- em_commit_shadow_ram(hw);
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Parent function for writing words to the different EEPROM types.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset within the EEPROM to be written to
- * words - number of words to write
- * data - 16 bit word to be written to the EEPROM
- *
- * If em_update_eeprom_checksum is not called after this function, the
- * EEPROM will most likely contain an invalid checksum.
- *****************************************************************************/
-int32_t
-em_write_eeprom(struct em_hw *hw,
- uint16_t offset,
- uint16_t words,
- uint16_t *data)
-{
- struct em_eeprom_info *eeprom = &hw->eeprom;
- int32_t status = 0;
-
- DEBUGFUNC("em_write_eeprom");
-
- /* A check for invalid values: offset too large, too many words, and not
- * enough words.
- */
- if((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
- (words == 0)) {
- DEBUGOUT("\"words\" parameter out of bounds\n");
- return -E1000_ERR_EEPROM;
- }
-
- /* 82573 reads only through eerd */
- if(eeprom->use_eewr == TRUE)
- return em_write_eeprom_eewr(hw, offset, words, data);
-
- /* Prepare the EEPROM for writing */
- if (em_acquire_eeprom(hw) != E1000_SUCCESS)
- return -E1000_ERR_EEPROM;
-
- if(eeprom->type == em_eeprom_microwire) {
- status = em_write_eeprom_microwire(hw, offset, words, data);
- } else {
- status = em_write_eeprom_spi(hw, offset, words, data);
- msec_delay(10);
- }
-
- /* Done with writing */
- em_release_eeprom(hw);
-
- return status;
-}
-
-/******************************************************************************
- * Writes a 16 bit word to a given offset in an SPI EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset within the EEPROM to be written to
- * words - number of words to write
- * data - pointer to array of 8 bit words to be written to the EEPROM
- *
- *****************************************************************************/
-int32_t
-em_write_eeprom_spi(struct em_hw *hw,
- uint16_t offset,
- uint16_t words,
- uint16_t *data)
-{
- struct em_eeprom_info *eeprom = &hw->eeprom;
- uint16_t widx = 0;
-
- DEBUGFUNC("em_write_eeprom_spi");
-
- while (widx < words) {
- uint8_t write_opcode = EEPROM_WRITE_OPCODE_SPI;
-
- if(em_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
-
- em_standby_eeprom(hw);
-
- /* Send the WRITE ENABLE command (8 bit opcode ) */
- em_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
- eeprom->opcode_bits);
-
- em_standby_eeprom(hw);
-
- /* Some SPI eeproms use the 8th address bit embedded in the opcode */
- if((eeprom->address_bits == 8) && (offset >= 128))
- write_opcode |= EEPROM_A8_OPCODE_SPI;
-
- /* Send the Write command (8-bit opcode + addr) */
- em_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
-
- em_shift_out_ee_bits(hw, (uint16_t)((offset + widx)*2),
- eeprom->address_bits);
-
- /* Send the data */
-
- /* Loop to allow for up to whole page write (32 bytes) of eeprom */
- while (widx < words) {
- uint16_t word_out = data[widx];
- word_out = (word_out >> 8) | (word_out << 8);
- em_shift_out_ee_bits(hw, word_out, 16);
- widx++;
-
- /* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
- * operation, while the smaller eeproms are capable of an 8-byte
- * PAGE WRITE operation. Break the inner loop to pass new address
- */
- if((((offset + widx)*2) % eeprom->page_size) == 0) {
- em_standby_eeprom(hw);
- break;
- }
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Writes a 16 bit word to a given offset in a Microwire EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset within the EEPROM to be written to
- * words - number of words to write
- * data - pointer to array of 16 bit words to be written to the EEPROM
- *
- *****************************************************************************/
-int32_t
-em_write_eeprom_microwire(struct em_hw *hw,
- uint16_t offset,
- uint16_t words,
- uint16_t *data)
-{
- struct em_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd;
- uint16_t words_written = 0;
- uint16_t i = 0;
-
- DEBUGFUNC("em_write_eeprom_microwire");
-
- /* Send the write enable command to the EEPROM (3-bit opcode plus
- * 6/8-bit dummy address beginning with 11). It's less work to include
- * the 11 of the dummy address as part of the opcode than it is to shift
- * it over the correct number of bits for the address. This puts the
- * EEPROM into write/erase mode.
- */
- em_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
- (uint16_t)(eeprom->opcode_bits + 2));
-
- em_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
-
- /* Prepare the EEPROM */
- em_standby_eeprom(hw);
-
- while (words_written < words) {
- /* Send the Write command (3-bit opcode + addr) */
- em_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
- eeprom->opcode_bits);
-
- em_shift_out_ee_bits(hw, (uint16_t)(offset + words_written),
- eeprom->address_bits);
-
- /* Send the data */
- em_shift_out_ee_bits(hw, data[words_written], 16);
-
- /* Toggle the CS line. This in effect tells the EEPROM to execute
- * the previous command.
- */
- em_standby_eeprom(hw);
-
- /* Read DO repeatedly until it is high (equal to '1'). The EEPROM will
- * signal that the command has been completed by raising the DO signal.
- * If DO does not go high in 10 milliseconds, then error out.
- */
- for(i = 0; i < 200; i++) {
- eecd = E1000_READ_REG(hw, EECD);
- if(eecd & E1000_EECD_DO) break;
- usec_delay(50);
- }
- if(i == 200) {
- DEBUGOUT("EEPROM Write did not complete\n");
- return -E1000_ERR_EEPROM;
- }
-
- /* Recover from write */
- em_standby_eeprom(hw);
-
- words_written++;
- }
-
- /* Send the write disable command to the EEPROM (3-bit opcode plus
- * 6/8-bit dummy address beginning with 10). It's less work to include
- * the 10 of the dummy address as part of the opcode than it is to shift
- * it over the correct number of bits for the address. This takes the
- * EEPROM out of write/erase mode.
- */
- em_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
- (uint16_t)(eeprom->opcode_bits + 2));
-
- em_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Flushes the cached eeprom to NVM. This is done by saving the modified values
- * in the eeprom cache and the non modified values in the currently active bank
- * to the new bank.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- *****************************************************************************/
-int32_t
-em_commit_shadow_ram(struct em_hw *hw)
-{
- uint32_t attempts = 100000;
- uint32_t eecd = 0;
- uint32_t flop = 0;
- uint32_t i = 0;
- int32_t error = E1000_SUCCESS;
-
- /* The flop register will be used to determine if flash type is STM */
- flop = E1000_READ_REG(hw, FLOP);
-
- if (hw->mac_type == em_82573) {
- for (i=0; i < attempts; i++) {
- eecd = E1000_READ_REG(hw, EECD);
- if ((eecd & E1000_EECD_FLUPD) == 0) {
- break;
- }
- usec_delay(5);
- }
-
- if (i == attempts) {
- return -E1000_ERR_EEPROM;
- }
-
- /* If STM opcode located in bits 15:8 of flop, reset firmware */
- if ((flop & 0xFF00) == E1000_STM_OPCODE) {
- E1000_WRITE_REG(hw, HICR, E1000_HICR_FW_RESET);
- }
-
- /* Perform the flash update */
- E1000_WRITE_REG(hw, EECD, eecd | E1000_EECD_FLUPD);
-
- for (i=0; i < attempts; i++) {
- eecd = E1000_READ_REG(hw, EECD);
- if ((eecd & E1000_EECD_FLUPD) == 0) {
- break;
- }
- usec_delay(5);
- }
-
- if (i == attempts) {
- return -E1000_ERR_EEPROM;
- }
- }
-
- return error;
-}
-
-/******************************************************************************
- * Reads the adapter's part number from the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
- * part_num - Adapter's part number
- *****************************************************************************/
-int32_t
-em_read_part_num(struct em_hw *hw,
- uint32_t *part_num)
-{
- uint16_t offset = EEPROM_PBA_BYTE_1;
- uint16_t eeprom_data;
-
- DEBUGFUNC("em_read_part_num");
-
- /* Get word 0 from EEPROM */
- if(em_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- /* Save word 0 in upper half of part_num */
- *part_num = (uint32_t) (eeprom_data << 16);
-
- /* Get word 1 from EEPROM */
- if(em_read_eeprom(hw, ++offset, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- /* Save word 1 in lower half of part_num */
- *part_num |= eeprom_data;
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
- * second function of dual function devices
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_read_mac_addr(struct em_hw * hw)
-{
- uint16_t offset;
- uint16_t eeprom_data, i;
-
- DEBUGFUNC("em_read_mac_addr");
-
- for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
- offset = i >> 1;
- if(em_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
- hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
- }
- if(((hw->mac_type == em_82546) || (hw->mac_type == em_82546_rev_3)) &&
- (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
- hw->perm_mac_addr[5] ^= 0x01;
-
- for(i = 0; i < NODE_ADDRESS_SIZE; i++)
- hw->mac_addr[i] = hw->perm_mac_addr[i];
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Initializes receive address filters.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Places the MAC address in receive address register 0 and clears the rest
- * of the receive addresss registers. Clears the multicast table. Assumes
- * the receiver is in reset when the routine is called.
- *****************************************************************************/
-void
-em_init_rx_addrs(struct em_hw *hw)
-{
- uint32_t i;
- uint32_t rar_num;
-
- DEBUGFUNC("em_init_rx_addrs");
-
- /* Setup the receive address. */
- DEBUGOUT("Programming MAC Address into RAR[0]\n");
-
- em_rar_set(hw, hw->mac_addr, 0);
-
- rar_num = E1000_RAR_ENTRIES;
- /* Zero out the other 15 receive addresses. */
- DEBUGOUT("Clearing RAR[1-15]\n");
- for(i = 1; i < rar_num; i++) {
- E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
- E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
- }
-}
-
-/******************************************************************************
- * Updates the MAC's list of multicast addresses.
- *
- * hw - Struct containing variables accessed by shared code
- * mc_addr_list - the list of new multicast addresses
- * mc_addr_count - number of addresses
- * pad - number of bytes between addresses in the list
- * rar_used_count - offset where to start adding mc addresses into the RAR's
- *
- * The given list replaces any existing list. Clears the last 15 receive
- * address registers and the multicast table. Uses receive address registers
- * for the first 15 multicast addresses, and hashes the rest into the
- * multicast table.
- *****************************************************************************/
-void
-em_mc_addr_list_update(struct em_hw *hw,
- uint8_t *mc_addr_list,
- uint32_t mc_addr_count,
- uint32_t pad,
- uint32_t rar_used_count)
-{
- uint32_t hash_value;
- uint32_t i;
- uint32_t num_rar_entry;
- uint32_t num_mta_entry;
-
- DEBUGFUNC("em_mc_addr_list_update");
-
- /* Set the new number of MC addresses that we are being requested to use. */
- hw->num_mc_addrs = mc_addr_count;
-
- /* Clear RAR[1-15] */
- DEBUGOUT(" Clearing RAR[1-15]\n");
- num_rar_entry = E1000_RAR_ENTRIES;
- for(i = rar_used_count; i < num_rar_entry; i++) {
- E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
- E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
- }
-
- /* Clear the MTA */
- DEBUGOUT(" Clearing MTA\n");
- num_mta_entry = E1000_NUM_MTA_REGISTERS;
- for(i = 0; i < num_mta_entry; i++) {
- E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
- }
-
- /* Add the new addresses */
- for(i = 0; i < mc_addr_count; i++) {
- DEBUGOUT(" Adding the multicast addresses:\n");
- DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad)],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 1],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 2],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 3],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 4],
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 5]);
-
- hash_value = em_hash_mc_addr(hw,
- mc_addr_list +
- (i * (ETH_LENGTH_OF_ADDRESS + pad)));
-
- DEBUGOUT1(" Hash value = 0x%03X\n", hash_value);
-
- /* Place this multicast address in the RAR if there is room, *
- * else put it in the MTA
- */
- if (rar_used_count < num_rar_entry) {
- em_rar_set(hw,
- mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)),
- rar_used_count);
- rar_used_count++;
- } else {
- em_mta_set(hw, hash_value);
- }
- }
- DEBUGOUT("MC Update Complete\n");
-}
-
-/******************************************************************************
- * Hashes an address to determine its location in the multicast table
- *
- * hw - Struct containing variables accessed by shared code
- * mc_addr - the multicast address to hash
- *****************************************************************************/
-uint32_t
-em_hash_mc_addr(struct em_hw *hw,
- uint8_t *mc_addr)
-{
- uint32_t hash_value = 0;
-
- /* The portion of the address that is used for the hash table is
- * determined by the mc_filter_type setting.
- */
- switch (hw->mc_filter_type) {
- /* [0] [1] [2] [3] [4] [5]
- * 01 AA 00 12 34 56
- * LSB MSB
- */
- case 0:
- /* [47:36] i.e. 0x563 for above example address */
- hash_value = ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4));
- break;
- case 1:
- /* [46:35] i.e. 0xAC6 for above example address */
- hash_value = ((mc_addr[4] >> 3) | (((uint16_t) mc_addr[5]) << 5));
- break;
- case 2:
- /* [45:34] i.e. 0x5D8 for above example address */
- hash_value = ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6));
- break;
- case 3:
- /* [43:32] i.e. 0x634 for above example address */
- hash_value = ((mc_addr[4]) | (((uint16_t) mc_addr[5]) << 8));
- break;
- }
-
- hash_value &= 0xFFF;
-
- return hash_value;
-}
-
-/******************************************************************************
- * Sets the bit in the multicast table corresponding to the hash value.
- *
- * hw - Struct containing variables accessed by shared code
- * hash_value - Multicast address hash value
- *****************************************************************************/
-void
-em_mta_set(struct em_hw *hw,
- uint32_t hash_value)
-{
- uint32_t hash_bit, hash_reg;
- uint32_t mta;
- uint32_t temp;
-
- /* The MTA is a register array of 128 32-bit registers.
- * It is treated like an array of 4096 bits. We want to set
- * bit BitArray[hash_value]. So we figure out what register
- * the bit is in, read it, OR in the new bit, then write
- * back the new value. The register is determined by the
- * upper 7 bits of the hash value and the bit within that
- * register are determined by the lower 5 bits of the value.
- */
- hash_reg = (hash_value >> 5) & 0x7F;
- hash_bit = hash_value & 0x1F;
-
- mta = E1000_READ_REG_ARRAY(hw, MTA, hash_reg);
-
- mta |= (1 << hash_bit);
-
- /* If we are on an 82544 and we are trying to write an odd offset
- * in the MTA, save off the previous entry before writing and
- * restore the old value after writing.
- */
- if((hw->mac_type == em_82544) && ((hash_reg & 0x1) == 1)) {
- temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1));
- E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
- E1000_WRITE_REG_ARRAY(hw, MTA, (hash_reg - 1), temp);
- } else {
- E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
- }
-}
-
-/******************************************************************************
- * Puts an ethernet address into a receive address register.
- *
- * hw - Struct containing variables accessed by shared code
- * addr - Address to put into receive address register
- * index - Receive address register to write
- *****************************************************************************/
-void
-em_rar_set(struct em_hw *hw,
- uint8_t *addr,
- uint32_t index)
-{
- uint32_t rar_low, rar_high;
-
- /* HW expects these in little endian so we reverse the byte order
- * from network order (big endian) to little endian
- */
- rar_low = ((uint32_t) addr[0] |
- ((uint32_t) addr[1] << 8) |
- ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
-
- rar_high = ((uint32_t) addr[4] | ((uint32_t) addr[5] << 8) | E1000_RAH_AV);
-
- E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
- E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
-}
-
-/******************************************************************************
- * Writes a value to the specified offset in the VLAN filter table.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - Offset in VLAN filer table to write
- * value - Value to write into VLAN filter table
- *****************************************************************************/
-void
-em_write_vfta(struct em_hw *hw,
- uint32_t offset,
- uint32_t value)
-{
- uint32_t temp;
-
- if((hw->mac_type == em_82544) && ((offset & 0x1) == 1)) {
- temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
- E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
- } else {
- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
- }
-}
-
-/******************************************************************************
- * Clears the VLAN filer table
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-void
-em_clear_vfta(struct em_hw *hw)
-{
- uint32_t offset;
- uint32_t vfta_value = 0;
- uint32_t vfta_offset = 0;
- uint32_t vfta_bit_in_reg = 0;
-
- if (hw->mac_type == em_82573) {
- if (hw->mng_cookie.vlan_id != 0) {
- /* The VFTA is a 4096b bit-field, each identifying a single VLAN
- * ID. The following operations determine which 32b entry
- * (i.e. offset) into the array we want to set the VLAN ID
- * (i.e. bit) of the manageability unit. */
- vfta_offset = (hw->mng_cookie.vlan_id >>
- E1000_VFTA_ENTRY_SHIFT) &
- E1000_VFTA_ENTRY_MASK;
- vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
- E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
- }
- }
- for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
- /* If the offset we want to clear is the same offset of the
- * manageability VLAN ID, then clear all bits except that of the
- * manageability unit */
- vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
- }
-}
-
-int32_t
-em_id_led_init(struct em_hw * hw)
-{
- uint32_t ledctl;
- const uint32_t ledctl_mask = 0x000000FF;
- const uint32_t ledctl_on = E1000_LEDCTL_MODE_LED_ON;
- const uint32_t ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
- uint16_t eeprom_data, i, temp;
- const uint16_t led_mask = 0x0F;
-
- DEBUGFUNC("em_id_led_init");
-
- if(hw->mac_type < em_82540) {
- /* Nothing to do */
- return E1000_SUCCESS;
- }
-
- ledctl = E1000_READ_REG(hw, LEDCTL);
- hw->ledctl_default = ledctl;
- hw->ledctl_mode1 = hw->ledctl_default;
- hw->ledctl_mode2 = hw->ledctl_default;
-
- if(em_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- if((eeprom_data== ID_LED_RESERVED_0000) ||
- (eeprom_data == ID_LED_RESERVED_FFFF)) eeprom_data = ID_LED_DEFAULT;
- for(i = 0; i < 4; i++) {
- temp = (eeprom_data >> (i << 2)) & led_mask;
- switch(temp) {
- case ID_LED_ON1_DEF2:
- case ID_LED_ON1_ON2:
- case ID_LED_ON1_OFF2:
- hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
- hw->ledctl_mode1 |= ledctl_on << (i << 3);
- break;
- case ID_LED_OFF1_DEF2:
- case ID_LED_OFF1_ON2:
- case ID_LED_OFF1_OFF2:
- hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
- hw->ledctl_mode1 |= ledctl_off << (i << 3);
- break;
- default:
- /* Do nothing */
- break;
- }
- switch(temp) {
- case ID_LED_DEF1_ON2:
- case ID_LED_ON1_ON2:
- case ID_LED_OFF1_ON2:
- hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
- hw->ledctl_mode2 |= ledctl_on << (i << 3);
- break;
- case ID_LED_DEF1_OFF2:
- case ID_LED_ON1_OFF2:
- case ID_LED_OFF1_OFF2:
- hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
- hw->ledctl_mode2 |= ledctl_off << (i << 3);
- break;
- default:
- /* Do nothing */
- break;
- }
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Prepares SW controlable LED for use and saves the current state of the LED.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_setup_led(struct em_hw *hw)
-{
- uint32_t ledctl;
- int32_t ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("em_setup_led");
-
- switch(hw->mac_type) {
- case em_82542_rev2_0:
- case em_82542_rev2_1:
- case em_82543:
- case em_82544:
- /* No setup necessary */
- break;
- case em_82541:
- case em_82547:
- case em_82541_rev_2:
- case em_82547_rev_2:
- /* Turn off PHY Smart Power Down (if enabled) */
- ret_val = em_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
- &hw->phy_spd_default);
- if(ret_val)
- return ret_val;
- ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
- (uint16_t)(hw->phy_spd_default &
- ~IGP01E1000_GMII_SPD));
- if(ret_val)
- return ret_val;
- /* Fall Through */
- default:
- if(hw->media_type == em_media_type_fiber) {
- ledctl = E1000_READ_REG(hw, LEDCTL);
- /* Save current LEDCTL settings */
- hw->ledctl_default = ledctl;
- /* Turn off LED0 */
- ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
- E1000_LEDCTL_LED0_BLINK |
- E1000_LEDCTL_LED0_MODE_MASK);
- ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
- E1000_LEDCTL_LED0_MODE_SHIFT);
- E1000_WRITE_REG(hw, LEDCTL, ledctl);
- } else if(hw->media_type == em_media_type_copper)
- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Restores the saved state of the SW controlable LED.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_cleanup_led(struct em_hw *hw)
-{
- int32_t ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("em_cleanup_led");
-
- switch(hw->mac_type) {
- case em_82542_rev2_0:
- case em_82542_rev2_1:
- case em_82543:
- case em_82544:
- /* No cleanup necessary */
- break;
- case em_82541:
- case em_82547:
- case em_82541_rev_2:
- case em_82547_rev_2:
- /* Turn on PHY Smart Power Down (if previously enabled) */
- ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
- hw->phy_spd_default);
- if(ret_val)
- return ret_val;
- /* Fall Through */
- default:
- /* Restore LEDCTL settings */
- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Turns on the software controllable LED
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_led_on(struct em_hw *hw)
-{
- uint32_t ctrl = E1000_READ_REG(hw, CTRL);
-
- DEBUGFUNC("em_led_on");
-
- switch(hw->mac_type) {
- case em_82542_rev2_0:
- case em_82542_rev2_1:
- case em_82543:
- /* Set SW Defineable Pin 0 to turn on the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- break;
- case em_82544:
- if(hw->media_type == em_media_type_fiber) {
- /* Set SW Defineable Pin 0 to turn on the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- } else {
- /* Clear SW Defineable Pin 0 to turn on the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- }
- break;
- default:
- if(hw->media_type == em_media_type_fiber) {
- /* Clear SW Defineable Pin 0 to turn on the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- } else if(hw->media_type == em_media_type_copper) {
- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
- return E1000_SUCCESS;
- }
- break;
- }
-
- E1000_WRITE_REG(hw, CTRL, ctrl);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Turns off the software controllable LED
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-int32_t
-em_led_off(struct em_hw *hw)
-{
- uint32_t ctrl = E1000_READ_REG(hw, CTRL);
-
- DEBUGFUNC("em_led_off");
-
- switch(hw->mac_type) {
- case em_82542_rev2_0:
- case em_82542_rev2_1:
- case em_82543:
- /* Clear SW Defineable Pin 0 to turn off the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- break;
- case em_82544:
- if(hw->media_type == em_media_type_fiber) {
- /* Clear SW Defineable Pin 0 to turn off the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- } else {
- /* Set SW Defineable Pin 0 to turn off the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- }
- break;
- default:
- if(hw->media_type == em_media_type_fiber) {
- /* Set SW Defineable Pin 0 to turn off the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- } else if(hw->media_type == em_media_type_copper) {
- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
- return E1000_SUCCESS;
- }
- break;
- }
-
- E1000_WRITE_REG(hw, CTRL, ctrl);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Clears all hardware statistics counters.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-void
-em_clear_hw_cntrs(struct em_hw *hw)
-{
- volatile uint32_t temp;
-
- temp = E1000_READ_REG(hw, CRCERRS);
- temp = E1000_READ_REG(hw, SYMERRS);
- temp = E1000_READ_REG(hw, MPC);
- temp = E1000_READ_REG(hw, SCC);
- temp = E1000_READ_REG(hw, ECOL);
- temp = E1000_READ_REG(hw, MCC);
- temp = E1000_READ_REG(hw, LATECOL);
- temp = E1000_READ_REG(hw, COLC);
- temp = E1000_READ_REG(hw, DC);
- temp = E1000_READ_REG(hw, SEC);
- temp = E1000_READ_REG(hw, RLEC);
- temp = E1000_READ_REG(hw, XONRXC);
- temp = E1000_READ_REG(hw, XONTXC);
- temp = E1000_READ_REG(hw, XOFFRXC);
- temp = E1000_READ_REG(hw, XOFFTXC);
- temp = E1000_READ_REG(hw, FCRUC);
- temp = E1000_READ_REG(hw, PRC64);
- temp = E1000_READ_REG(hw, PRC127);
- temp = E1000_READ_REG(hw, PRC255);
- temp = E1000_READ_REG(hw, PRC511);
- temp = E1000_READ_REG(hw, PRC1023);
- temp = E1000_READ_REG(hw, PRC1522);
- temp = E1000_READ_REG(hw, GPRC);
- temp = E1000_READ_REG(hw, BPRC);
- temp = E1000_READ_REG(hw, MPRC);
- temp = E1000_READ_REG(hw, GPTC);
- temp = E1000_READ_REG(hw, GORCL);
- temp = E1000_READ_REG(hw, GORCH);
- temp = E1000_READ_REG(hw, GOTCL);
- temp = E1000_READ_REG(hw, GOTCH);
- temp = E1000_READ_REG(hw, RNBC);
- temp = E1000_READ_REG(hw, RUC);
- temp = E1000_READ_REG(hw, RFC);
- temp = E1000_READ_REG(hw, ROC);
- temp = E1000_READ_REG(hw, RJC);
- temp = E1000_READ_REG(hw, TORL);
- temp = E1000_READ_REG(hw, TORH);
- temp = E1000_READ_REG(hw, TOTL);
- temp = E1000_READ_REG(hw, TOTH);
- temp = E1000_READ_REG(hw, TPR);
- temp = E1000_READ_REG(hw, TPT);
- temp = E1000_READ_REG(hw, PTC64);
- temp = E1000_READ_REG(hw, PTC127);
- temp = E1000_READ_REG(hw, PTC255);
- temp = E1000_READ_REG(hw, PTC511);
- temp = E1000_READ_REG(hw, PTC1023);
- temp = E1000_READ_REG(hw, PTC1522);
- temp = E1000_READ_REG(hw, MPTC);
- temp = E1000_READ_REG(hw, BPTC);
-
- if(hw->mac_type < em_82543) return;
-
- temp = E1000_READ_REG(hw, ALGNERRC);
- temp = E1000_READ_REG(hw, RXERRC);
- temp = E1000_READ_REG(hw, TNCRS);
- temp = E1000_READ_REG(hw, CEXTERR);
- temp = E1000_READ_REG(hw, TSCTC);
- temp = E1000_READ_REG(hw, TSCTFC);
-
- if(hw->mac_type <= em_82544) return;
-
- temp = E1000_READ_REG(hw, MGTPRC);
- temp = E1000_READ_REG(hw, MGTPDC);
- temp = E1000_READ_REG(hw, MGTPTC);
-
- if(hw->mac_type <= em_82547_rev_2) return;
-
- temp = E1000_READ_REG(hw, IAC);
- temp = E1000_READ_REG(hw, ICRXOC);
- temp = E1000_READ_REG(hw, ICRXPTC);
- temp = E1000_READ_REG(hw, ICRXATC);
- temp = E1000_READ_REG(hw, ICTXPTC);
- temp = E1000_READ_REG(hw, ICTXATC);
- temp = E1000_READ_REG(hw, ICTXQEC);
- temp = E1000_READ_REG(hw, ICTXQMTC);
- temp = E1000_READ_REG(hw, ICRXDMTC);
-
-}
-
-/******************************************************************************
- * Resets Adaptive IFS to its default state.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Call this after em_init_hw. You may override the IFS defaults by setting
- * hw->ifs_params_forced to TRUE. However, you must initialize hw->
- * current_ifs_val, ifs_min_val, ifs_max_val, ifs_step_size, and ifs_ratio
- * before calling this function.
- *****************************************************************************/
-void
-em_reset_adaptive(struct em_hw *hw)
-{
- DEBUGFUNC("em_reset_adaptive");
-
- if(hw->adaptive_ifs) {
- if(!hw->ifs_params_forced) {
- hw->current_ifs_val = 0;
- hw->ifs_min_val = IFS_MIN;
- hw->ifs_max_val = IFS_MAX;
- hw->ifs_step_size = IFS_STEP;
- hw->ifs_ratio = IFS_RATIO;
- }
- hw->in_ifs_mode = FALSE;
- E1000_WRITE_REG(hw, AIT, 0);
- } else {
- DEBUGOUT("Not in Adaptive IFS mode!\n");
- }
-}
-
-/******************************************************************************
- * Called during the callback/watchdog routine to update IFS value based on
- * the ratio of transmits to collisions.
- *
- * hw - Struct containing variables accessed by shared code
- * tx_packets - Number of transmits since last callback
- * total_collisions - Number of collisions since last callback
- *****************************************************************************/
-void
-em_update_adaptive(struct em_hw *hw)
-{
- DEBUGFUNC("em_update_adaptive");
-
- if(hw->adaptive_ifs) {
- if((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) {
- if(hw->tx_packet_delta > MIN_NUM_XMITS) {
- hw->in_ifs_mode = TRUE;
- if(hw->current_ifs_val < hw->ifs_max_val) {
- if(hw->current_ifs_val == 0)
- hw->current_ifs_val = hw->ifs_min_val;
- else
- hw->current_ifs_val += hw->ifs_step_size;
- E1000_WRITE_REG(hw, AIT, hw->current_ifs_val);
- }
- }
- } else {
- if(hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
- hw->current_ifs_val = 0;
- hw->in_ifs_mode = FALSE;
- E1000_WRITE_REG(hw, AIT, 0);
- }
- }
- } else {
- DEBUGOUT("Not in Adaptive IFS mode!\n");
- }
-}
-
-/******************************************************************************
- * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
- *
- * hw - Struct containing variables accessed by shared code
- * frame_len - The length of the frame in question
- * mac_addr - The Ethernet destination address of the frame in question
- *****************************************************************************/
-void
-em_tbi_adjust_stats(struct em_hw *hw,
- struct em_hw_stats *stats,
- uint32_t frame_len,
- uint8_t *mac_addr)
-{
- uint64_t carry_bit;
-
- /* First adjust the frame length. */
- frame_len--;
- /* We need to adjust the statistics counters, since the hardware
- * counters overcount this packet as a CRC error and undercount
- * the packet as a good packet
- */
- /* This packet should not be counted as a CRC error. */
- stats->crcerrs--;
- /* This packet does count as a Good Packet Received. */
- stats->gprc++;
-
- /* Adjust the Good Octets received counters */
- carry_bit = 0x80000000 & stats->gorcl;
- stats->gorcl += frame_len;
- /* If the high bit of Gorcl (the low 32 bits of the Good Octets
- * Received Count) was one before the addition,
- * AND it is zero after, then we lost the carry out,
- * need to add one to Gorch (Good Octets Received Count High).
- * This could be simplified if all environments supported
- * 64-bit integers.
- */
- if(carry_bit && ((stats->gorcl & 0x80000000) == 0))
- stats->gorch++;
- /* Is this a broadcast or multicast? Check broadcast first,
- * since the test for a multicast frame will test positive on
- * a broadcast frame.
- */
- if((mac_addr[0] == (uint8_t) 0xff) && (mac_addr[1] == (uint8_t) 0xff))
- /* Broadcast packet */
- stats->bprc++;
- else if(*mac_addr & 0x01)
- /* Multicast packet */
- stats->mprc++;
-
- if(frame_len == hw->max_frame_size) {
- /* In this case, the hardware has overcounted the number of
- * oversize frames.
- */
- if(stats->roc > 0)
- stats->roc--;
- }
-
- /* Adjust the bin counters when the extra byte put the frame in the
- * wrong bin. Remember that the frame_len was adjusted above.
- */
- if(frame_len == 64) {
- stats->prc64++;
- stats->prc127--;
- } else if(frame_len == 127) {
- stats->prc127++;
- stats->prc255--;
- } else if(frame_len == 255) {
- stats->prc255++;
- stats->prc511--;
- } else if(frame_len == 511) {
- stats->prc511++;
- stats->prc1023--;
- } else if(frame_len == 1023) {
- stats->prc1023++;
- stats->prc1522--;
- } else if(frame_len == 1522) {
- stats->prc1522++;
- }
-}
-
-/******************************************************************************
- * Gets the current PCI bus type, speed, and width of the hardware
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-void
-em_get_bus_info(struct em_hw *hw)
-{
- uint32_t status;
-
- switch (hw->mac_type) {
- case em_82542_rev2_0:
- case em_82542_rev2_1:
- hw->bus_type = em_bus_type_unknown;
- hw->bus_speed = em_bus_speed_unknown;
- hw->bus_width = em_bus_width_unknown;
- break;
- case em_82573:
- hw->bus_type = em_bus_type_pci_express;
- hw->bus_speed = em_bus_speed_2500;
- hw->bus_width = em_bus_width_pciex_4;
- break;
- default:
- status = E1000_READ_REG(hw, STATUS);
- hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
- em_bus_type_pcix : em_bus_type_pci;
-
- if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
- hw->bus_speed = (hw->bus_type == em_bus_type_pci) ?
- em_bus_speed_66 : em_bus_speed_120;
- } else if(hw->bus_type == em_bus_type_pci) {
- hw->bus_speed = (status & E1000_STATUS_PCI66) ?
- em_bus_speed_66 : em_bus_speed_33;
- } else {
- switch (status & E1000_STATUS_PCIX_SPEED) {
- case E1000_STATUS_PCIX_SPEED_66:
- hw->bus_speed = em_bus_speed_66;
- break;
- case E1000_STATUS_PCIX_SPEED_100:
- hw->bus_speed = em_bus_speed_100;
- break;
- case E1000_STATUS_PCIX_SPEED_133:
- hw->bus_speed = em_bus_speed_133;
- break;
- default:
- hw->bus_speed = em_bus_speed_reserved;
- break;
- }
- }
- hw->bus_width = (status & E1000_STATUS_BUS64) ?
- em_bus_width_64 : em_bus_width_32;
- break;
- }
-}
-/******************************************************************************
- * Reads a value from one of the devices registers using port I/O (as opposed
- * memory mapped I/O). Only 82544 and newer devices support port I/O.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset to read from
- *****************************************************************************/
-uint32_t
-em_read_reg_io(struct em_hw *hw,
- uint32_t offset)
-{
- unsigned long io_addr = hw->io_base;
- unsigned long io_data = hw->io_base + 4;
-
- em_io_write(hw, io_addr, offset);
- return em_io_read(hw, io_data);
-}
-
-/******************************************************************************
- * Writes a value to one of the devices registers using port I/O (as opposed to
- * memory mapped I/O). Only 82544 and newer devices support port I/O.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset to write to
- * value - value to write
- *****************************************************************************/
-void
-em_write_reg_io(struct em_hw *hw,
- uint32_t offset,
- uint32_t value)
-{
- unsigned long io_addr = hw->io_base;
- unsigned long io_data = hw->io_base + 4;
-
- em_io_write(hw, io_addr, offset);
- em_io_write(hw, io_data, value);
-}
-
-
-/******************************************************************************
- * Estimates the cable length.
- *
- * hw - Struct containing variables accessed by shared code
- * min_length - The estimated minimum length
- * max_length - The estimated maximum length
- *
- * returns: - E1000_ERR_XXX
- * E1000_SUCCESS
- *
- * This function always returns a ranged length (minimum & maximum).
- * So for M88 phy's, this function interprets the one value returned from the
- * register to the minimum and maximum range.
- * For IGP phy's, the function calculates the range by the AGC registers.
- *****************************************************************************/
-int32_t
-em_get_cable_length(struct em_hw *hw,
- uint16_t *min_length,
- uint16_t *max_length)
-{
- int32_t ret_val;
- uint16_t agc_value = 0;
- uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
- uint16_t i, phy_data;
- uint16_t cable_length;
-
- DEBUGFUNC("em_get_cable_length");
-
- *min_length = *max_length = 0;
-
- /* Use old method for Phy older than IGP */
- if(hw->phy_type == em_phy_m88) {
-
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
- if(ret_val)
- return ret_val;
- cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
- M88E1000_PSSR_CABLE_LENGTH_SHIFT;
-
- /* Convert the enum value to ranged values */
- switch (cable_length) {
- case em_cable_length_50:
- *min_length = 0;
- *max_length = em_igp_cable_length_50;
- break;
- case em_cable_length_50_80:
- *min_length = em_igp_cable_length_50;
- *max_length = em_igp_cable_length_80;
- break;
- case em_cable_length_80_110:
- *min_length = em_igp_cable_length_80;
- *max_length = em_igp_cable_length_110;
- break;
- case em_cable_length_110_140:
- *min_length = em_igp_cable_length_110;
- *max_length = em_igp_cable_length_140;
- break;
- case em_cable_length_140:
- *min_length = em_igp_cable_length_140;
- *max_length = em_igp_cable_length_170;
- break;
- default:
- return -E1000_ERR_PHY;
- break;
- }
- } else if(hw->phy_type == em_phy_igp) { /* For IGP PHY */
- uint16_t agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
- {IGP01E1000_PHY_AGC_A,
- IGP01E1000_PHY_AGC_B,
- IGP01E1000_PHY_AGC_C,
- IGP01E1000_PHY_AGC_D};
- /* Read the AGC registers for all channels */
- for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
-
- ret_val = em_read_phy_reg(hw, agc_reg_array[i], &phy_data);
- if(ret_val)
- return ret_val;
-
- cur_agc = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
-
- /* Array bound check. */
- if((cur_agc >= IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1) ||
- (cur_agc == 0))
- return -E1000_ERR_PHY;
-
- agc_value += cur_agc;
-
- /* Update minimal AGC value. */
- if(min_agc > cur_agc)
- min_agc = cur_agc;
- }
-
- /* Remove the minimal AGC result for length < 50m */
- if(agc_value < IGP01E1000_PHY_CHANNEL_NUM * em_igp_cable_length_50) {
- agc_value -= min_agc;
-
- /* Get the average length of the remaining 3 channels */
- agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
- } else {
- /* Get the average length of all the 4 channels. */
- agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
- }
-
- /* Set the range of the calculated length. */
- *min_length = ((em_igp_cable_length_table[agc_value] -
- IGP01E1000_AGC_RANGE) > 0) ?
- (em_igp_cable_length_table[agc_value] -
- IGP01E1000_AGC_RANGE) : 0;
- *max_length = em_igp_cable_length_table[agc_value] +
- IGP01E1000_AGC_RANGE;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Check the cable polarity
- *
- * hw - Struct containing variables accessed by shared code
- * polarity - output parameter : 0 - Polarity is not reversed
- * 1 - Polarity is reversed.
- *
- * returns: - E1000_ERR_XXX
- * E1000_SUCCESS
- *
- * For phy's older then IGP, this function simply reads the polarity bit in the
- * Phy Status register. For IGP phy's, this bit is valid only if link speed is
- * 10 Mbps. If the link speed is 100 Mbps there is no polarity so this bit will
- * return 0. If the link speed is 1000 Mbps the polarity status is in the
- * IGP01E1000_PHY_PCS_INIT_REG.
- *****************************************************************************/
-int32_t
-em_check_polarity(struct em_hw *hw,
- uint16_t *polarity)
-{
- int32_t ret_val;
- uint16_t phy_data;
-#ifdef __rtems__
- *polarity = 0; /* keep compiler happy */
-#endif
-
- DEBUGFUNC("em_check_polarity");
-
- if(hw->phy_type == em_phy_m88) {
- /* return the Polarity bit in the Status register. */
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
- if(ret_val)
- return ret_val;
- *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
- M88E1000_PSSR_REV_POLARITY_SHIFT;
- } else if(hw->phy_type == em_phy_igp ||
- hw->phy_type == em_phy_igp_2) {
- /* Read the Status register to check the speed */
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
- &phy_data);
- if(ret_val)
- return ret_val;
-
- /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
- * find the polarity status */
- if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
-
- /* Read the GIG initialization PCS register (0x00B4) */
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
- &phy_data);
- if(ret_val)
- return ret_val;
-
- /* Check the polarity bits */
- *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
- } else {
- /* For 10 Mbps, read the polarity bit in the status register. (for
- * 100 Mbps this bit is always 0) */
- *polarity = phy_data & IGP01E1000_PSSR_POLARITY_REVERSED;
- }
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Check if Downshift occured
- *
- * hw - Struct containing variables accessed by shared code
- * downshift - output parameter : 0 - No Downshift ocured.
- * 1 - Downshift ocured.
- *
- * returns: - E1000_ERR_XXX
- * E1000_SUCCESS
- *
- * For phy's older then IGP, this function reads the Downshift bit in the Phy
- * Specific Status register. For IGP phy's, it reads the Downgrade bit in the
- * Link Health register. In IGP this bit is latched high, so the driver must
- * read it immediately after link is established.
- *****************************************************************************/
-int32_t
-em_check_downshift(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t phy_data;
-
- DEBUGFUNC("em_check_downshift");
-
- if(hw->phy_type == em_phy_igp ||
- hw->phy_type == em_phy_igp_2) {
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
- &phy_data);
- if(ret_val)
- return ret_val;
-
- hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
- } else if(hw->phy_type == em_phy_m88) {
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
- if(ret_val)
- return ret_val;
-
- hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
- M88E1000_PSSR_DOWNSHIFT_SHIFT;
- }
-
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- *
- * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
- * gigabit link is achieved to improve link quality.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_PHY if fail to read/write the PHY
- * E1000_SUCCESS at any other case.
- *
- ****************************************************************************/
-
-int32_t
-em_config_dsp_after_link_change(struct em_hw *hw,
- boolean_t link_up)
-{
- int32_t ret_val;
- uint16_t phy_data, phy_saved_data, speed, duplex, i;
- uint16_t dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
- {IGP01E1000_PHY_AGC_PARAM_A,
- IGP01E1000_PHY_AGC_PARAM_B,
- IGP01E1000_PHY_AGC_PARAM_C,
- IGP01E1000_PHY_AGC_PARAM_D};
- uint16_t min_length, max_length;
-
- DEBUGFUNC("em_config_dsp_after_link_change");
-
- if(hw->phy_type != em_phy_igp)
- return E1000_SUCCESS;
-
- if(link_up) {
- ret_val = em_get_speed_and_duplex(hw, &speed, &duplex);
- if(ret_val) {
- DEBUGOUT("Error getting link speed and duplex\n");
- return ret_val;
- }
-
- if(speed == SPEED_1000) {
-
- em_get_cable_length(hw, &min_length, &max_length);
-
- if((hw->dsp_config_state == em_dsp_config_enabled) &&
- min_length >= em_igp_cable_length_50) {
-
- for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = em_read_phy_reg(hw, dsp_reg_array[i],
- &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
-
- ret_val = em_write_phy_reg(hw, dsp_reg_array[i],
- phy_data);
- if(ret_val)
- return ret_val;
- }
- hw->dsp_config_state = em_dsp_config_activated;
- }
-
- if((hw->ffe_config_state == em_ffe_config_enabled) &&
- (min_length < em_igp_cable_length_50)) {
-
- uint16_t ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
- uint32_t idle_errs = 0;
-
- /* clear previous idle error counts */
- ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_data);
- if(ret_val)
- return ret_val;
-
- for(i = 0; i < ffe_idle_err_timeout; i++) {
- usec_delay(1000);
- ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_data);
- if(ret_val)
- return ret_val;
-
- idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
- if(idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
- hw->ffe_config_state = em_ffe_config_active;
-
- ret_val = em_write_phy_reg(hw,
- IGP01E1000_PHY_DSP_FFE,
- IGP01E1000_PHY_DSP_FFE_CM_CP);
- if(ret_val)
- return ret_val;
- break;
- }
-
- if(idle_errs)
- ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_100;
- }
- }
- }
- } else {
- if(hw->dsp_config_state == em_dsp_config_activated) {
- /* Save off the current value of register 0x2F5B to be restored at
- * the end of the routines. */
- ret_val = em_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
-
- if(ret_val)
- return ret_val;
-
- /* Disable the PHY transmitter */
- ret_val = em_write_phy_reg(hw, 0x2F5B, 0x0003);
-
- if(ret_val)
- return ret_val;
-
- msec_delay_irq(20);
-
- ret_val = em_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_FORCE_GIGA);
- if(ret_val)
- return ret_val;
- for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = em_read_phy_reg(hw, dsp_reg_array[i], &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
- phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
-
- ret_val = em_write_phy_reg(hw,dsp_reg_array[i], phy_data);
- if(ret_val)
- return ret_val;
- }
-
- ret_val = em_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_RESTART_AUTONEG);
- if(ret_val)
- return ret_val;
-
- msec_delay_irq(20);
-
- /* Now enable the transmitter */
- ret_val = em_write_phy_reg(hw, 0x2F5B, phy_saved_data);
-
- if(ret_val)
- return ret_val;
-
- hw->dsp_config_state = em_dsp_config_enabled;
- }
-
- if(hw->ffe_config_state == em_ffe_config_active) {
- /* Save off the current value of register 0x2F5B to be restored at
- * the end of the routines. */
- ret_val = em_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
-
- if(ret_val)
- return ret_val;
-
- /* Disable the PHY transmitter */
- ret_val = em_write_phy_reg(hw, 0x2F5B, 0x0003);
-
- if(ret_val)
- return ret_val;
-
- msec_delay_irq(20);
-
- ret_val = em_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_FORCE_GIGA);
- if(ret_val)
- return ret_val;
- ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
- IGP01E1000_PHY_DSP_FFE_DEFAULT);
- if(ret_val)
- return ret_val;
-
- ret_val = em_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_RESTART_AUTONEG);
- if(ret_val)
- return ret_val;
-
- msec_delay_irq(20);
-
- /* Now enable the transmitter */
- ret_val = em_write_phy_reg(hw, 0x2F5B, phy_saved_data);
-
- if(ret_val)
- return ret_val;
-
- hw->ffe_config_state = em_ffe_config_enabled;
- }
- }
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- * Set PHY to class A mode
- * 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.
- *
- * hw - Struct containing variables accessed by shared code
- ****************************************************************************/
-static int32_t
-em_set_phy_mode(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t eeprom_data;
-
- DEBUGFUNC("em_set_phy_mode");
-
- if((hw->mac_type == em_82545_rev_3) &&
- (hw->media_type == em_media_type_copper)) {
- ret_val = em_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1, &eeprom_data);
- if(ret_val) {
- return ret_val;
- }
-
- if((eeprom_data != EEPROM_RESERVED_WORD) &&
- (eeprom_data & EEPROM_PHY_CLASS_A)) {
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x000B);
- if(ret_val)
- return ret_val;
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x8104);
- if(ret_val)
- return ret_val;
-
- hw->phy_reset_disable = FALSE;
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- *
- * This function sets the lplu state according to the active flag. When
- * activating lplu this function also disables smart speed and vise versa.
- * lplu will not be activated unless the device autonegotiation advertisment
- * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
- * hw: Struct containing variables accessed by shared code
- * active - true to enable lplu false to disable lplu.
- *
- * returns: - E1000_ERR_PHY if fail to read/write the PHY
- * E1000_SUCCESS at any other case.
- *
- ****************************************************************************/
-
-int32_t
-em_set_d3_lplu_state(struct em_hw *hw,
- boolean_t active)
-{
- int32_t ret_val;
- uint16_t phy_data;
- DEBUGFUNC("em_set_d3_lplu_state");
-
- if(hw->phy_type != em_phy_igp && hw->phy_type != em_phy_igp_2)
- return E1000_SUCCESS;
-
- /* During driver activity LPLU should not be used or it will attain link
- * from the lowest speeds starting from 10Mbps. The capability is used for
- * Dx transitions and states */
- if(hw->mac_type == em_82541_rev_2 || hw->mac_type == em_82547_rev_2) {
- ret_val = em_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
- if(ret_val)
- return ret_val;
- } else {
- ret_val = em_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
- if(ret_val)
- return ret_val;
- }
-
- if(!active) {
- if(hw->mac_type == em_82541_rev_2 ||
- hw->mac_type == em_82547_rev_2) {
- phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
- ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
- if(ret_val)
- return ret_val;
- } else {
- phy_data &= ~IGP02E1000_PM_D3_LPLU;
- ret_val = em_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- phy_data);
- if (ret_val)
- return ret_val;
- }
-
- /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during
- * Dx states where the power conservation is most important. During
- * driver activity we should enable SmartSpeed, so performance is
- * maintained. */
- if (hw->smart_speed == em_smart_speed_on) {
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if(ret_val)
- return ret_val;
- } else if (hw->smart_speed == em_smart_speed_off) {
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if(ret_val)
- return ret_val;
- }
-
- } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
- (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
- (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
-
- if(hw->mac_type == em_82541_rev_2 ||
- hw->mac_type == em_82547_rev_2) {
- phy_data |= IGP01E1000_GMII_FLEX_SPD;
- ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
- if(ret_val)
- return ret_val;
- } else {
- phy_data |= IGP02E1000_PM_D3_LPLU;
- ret_val = em_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- phy_data);
- if (ret_val)
- return ret_val;
- }
-
- /* When LPLU is enabled we should disable SmartSpeed */
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
- if(ret_val)
- return ret_val;
-
- }
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- *
- * This function sets the lplu d0 state according to the active flag. When
- * activating lplu this function also disables smart speed and vise versa.
- * lplu will not be activated unless the device autonegotiation advertisment
- * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
- * hw: Struct containing variables accessed by shared code
- * active - true to enable lplu false to disable lplu.
- *
- * returns: - E1000_ERR_PHY if fail to read/write the PHY
- * E1000_SUCCESS at any other case.
- *
- ****************************************************************************/
-
-int32_t
-em_set_d0_lplu_state(struct em_hw *hw,
- boolean_t active)
-{
- int32_t ret_val;
- uint16_t phy_data;
- DEBUGFUNC("em_set_d0_lplu_state");
-
- if(hw->mac_type <= em_82547_rev_2)
- return E1000_SUCCESS;
-
- ret_val = em_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
- if(ret_val)
- return ret_val;
-
- if (!active) {
- phy_data &= ~IGP02E1000_PM_D0_LPLU;
- ret_val = em_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
- if (ret_val)
- return ret_val;
-
- /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during
- * Dx states where the power conservation is most important. During
- * driver activity we should enable SmartSpeed, so performance is
- * maintained. */
- if (hw->smart_speed == em_smart_speed_on) {
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if(ret_val)
- return ret_val;
- } else if (hw->smart_speed == em_smart_speed_off) {
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if(ret_val)
- return ret_val;
- }
-
-
- } else {
-
- phy_data |= IGP02E1000_PM_D0_LPLU;
- ret_val = em_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
- if (ret_val)
- return ret_val;
-
- /* When LPLU is enabled we should disable SmartSpeed */
- ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
- if(ret_val)
- return ret_val;
-
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Change VCO speed register to improve Bit Error Rate performance of SERDES.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static int32_t
-em_set_vco_speed(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t default_page = 0;
- uint16_t phy_data;
-
- DEBUGFUNC("em_set_vco_speed");
-
- switch(hw->mac_type) {
- case em_82545_rev_3:
- case em_82546_rev_3:
- break;
- default:
- return E1000_SUCCESS;
- }
-
- /* Set PHY register 30, page 5, bit 8 to 0 */
-
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
- if(ret_val)
- return ret_val;
-
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
- if(ret_val)
- return ret_val;
-
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
- if(ret_val)
- return ret_val;
-
- /* Set PHY register 30, page 4, bit 11 to 1 */
-
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
- if(ret_val)
- return ret_val;
-
- ret_val = em_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
- if(ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PHY_VCO_REG_BIT11;
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
- if(ret_val)
- return ret_val;
-
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
- if(ret_val)
- return ret_val;
-
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function reads the cookie from ARC ram.
- *
- * returns: - E1000_SUCCESS .
- ****************************************************************************/
-int32_t
-em_host_if_read_cookie(struct em_hw * hw, uint8_t *buffer)
-{
- uint8_t i;
- uint32_t offset = E1000_MNG_DHCP_COOKIE_OFFSET;
- uint8_t length = E1000_MNG_DHCP_COOKIE_LENGTH;
-
- length = (length >> 2);
- offset = (offset >> 2);
-
- for (i = 0; i < length; i++) {
- *((uint32_t *) buffer + i) =
- E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i);
- }
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function checks whether the HOST IF is enabled for command operaton
- * and also checks whether the previous command is completed.
- * It busy waits in case of previous command is not completed.
- *
- * returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or
- * timeout
- * - E1000_SUCCESS for success.
- ****************************************************************************/
-int32_t
-em_mng_enable_host_if(struct em_hw * hw)
-{
- uint32_t hicr;
- uint8_t i;
-
- /* Check that the host interface is enabled. */
- hicr = E1000_READ_REG(hw, HICR);
- if ((hicr & E1000_HICR_EN) == 0) {
- DEBUGOUT("E1000_HOST_EN bit disabled.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
- /* check the previous command is completed */
- for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
- hicr = E1000_READ_REG(hw, HICR);
- if (!(hicr & E1000_HICR_C))
- break;
- msec_delay_irq(1);
- }
-
- if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
- DEBUGOUT("Previous command timeout failed .\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- * This function writes the buffer content at the offset given on the host if.
- * It also does alignment considerations to do the writes in most efficient way.
- * Also fills up the sum of the buffer in *buffer parameter.
- *
- * returns - E1000_SUCCESS for success.
- ****************************************************************************/
-int32_t
-em_mng_host_if_write(struct em_hw * hw, uint8_t *buffer,
- uint16_t length, uint16_t offset, uint8_t *sum)
-{
- uint8_t *tmp;
- uint8_t *bufptr = buffer;
- uint32_t data;
- uint16_t remaining, i, j, prev_bytes;
-
- /* sum = only sum of the data and it is not checksum */
-
- if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
- return -E1000_ERR_PARAM;
- }
-
- tmp = (uint8_t *)&data;
- prev_bytes = offset & 0x3;
- offset &= 0xFFFC;
- offset >>= 2;
-
- if (prev_bytes) {
- data = E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset);
- for (j = prev_bytes; j < sizeof(uint32_t); j++) {
- *(tmp + j) = *bufptr++;
- *sum += *(tmp + j);
- }
- E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset, data);
- length -= j - prev_bytes;
- offset++;
- }
-
- remaining = length & 0x3;
- length -= remaining;
-
- /* Calculate length in DWORDs */
- length >>= 2;
-
- /* The device driver writes the relevant command block into the
- * ram area. */
- for (i = 0; i < length; i++) {
- for (j = 0; j < sizeof(uint32_t); j++) {
- *(tmp + j) = *bufptr++;
- *sum += *(tmp + j);
- }
-
- E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
- }
- if (remaining) {
- for (j = 0; j < sizeof(uint32_t); j++) {
- if (j < remaining)
- *(tmp + j) = *bufptr++;
- else
- *(tmp + j) = 0;
-
- *sum += *(tmp + j);
- }
- E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
- }
-
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function writes the command header after does the checksum calculation.
- *
- * returns - E1000_SUCCESS for success.
- ****************************************************************************/
-int32_t
-em_mng_write_cmd_header(struct em_hw * hw,
- struct em_host_mng_command_header * hdr)
-{
- uint16_t i;
- uint8_t sum;
- uint8_t *buffer;
-
- /* Write the whole command header structure which includes sum of
- * the buffer */
-
- uint16_t length = sizeof(struct em_host_mng_command_header);
-
- sum = hdr->checksum;
- hdr->checksum = 0;
-
- buffer = (uint8_t *) hdr;
- i = length;
- while(i--)
- sum += buffer[i];
-
- hdr->checksum = 0 - sum;
-
- length >>= 2;
- /* The device driver writes the relevant command block into the ram area. */
- for (i = 0; i < length; i++)
- E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((uint32_t *) hdr + i));
-
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function indicates to ARC that a new command is pending which completes
- * one write operation by the driver.
- *
- * returns - E1000_SUCCESS for success.
- ****************************************************************************/
-int32_t
-em_mng_write_commit(
- struct em_hw * hw)
-{
- uint32_t hicr;
-
- hicr = E1000_READ_REG(hw, HICR);
- /* Setting this bit tells the ARC that a new command is pending. */
- E1000_WRITE_REG(hw, HICR, hicr | E1000_HICR_C);
-
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function checks the mode of the firmware.
- *
- * returns - TRUE when the mode is IAMT or FALSE.
- ****************************************************************************/
-boolean_t
-em_check_mng_mode(
- struct em_hw *hw)
-{
- uint32_t fwsm;
-
- fwsm = E1000_READ_REG(hw, FWSM);
-
- if((fwsm & E1000_FWSM_MODE_MASK) ==
- (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
- return TRUE;
-
- return FALSE;
-}
-
-
-/*****************************************************************************
- * This function writes the dhcp info .
- ****************************************************************************/
-int32_t
-em_mng_write_dhcp_info(struct em_hw * hw, uint8_t *buffer,
- uint16_t length)
-{
- int32_t ret_val;
- struct em_host_mng_command_header hdr;
-
- hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
- hdr.command_length = length;
- hdr.reserved1 = 0;
- hdr.reserved2 = 0;
- hdr.checksum = 0;
-
- ret_val = em_mng_enable_host_if(hw);
- if (ret_val == E1000_SUCCESS) {
- ret_val = em_mng_host_if_write(hw, buffer, length, sizeof(hdr),
- &(hdr.checksum));
- if (ret_val == E1000_SUCCESS) {
- ret_val = em_mng_write_cmd_header(hw, &hdr);
- if (ret_val == E1000_SUCCESS)
- ret_val = em_mng_write_commit(hw);
- }
- }
- return ret_val;
-}
-
-
-/*****************************************************************************
- * This function calculates the checksum.
- *
- * returns - checksum of buffer contents.
- ****************************************************************************/
-uint8_t
-em_calculate_mng_checksum(char *buffer, uint32_t length)
-{
- uint8_t sum = 0;
- uint32_t i;
-
- if (!buffer)
- return 0;
-
- for (i=0; i < length; i++)
- sum += buffer[i];
-
- return (uint8_t) (0 - sum);
-}
-
-/*****************************************************************************
- * This function checks whether tx pkt filtering needs to be enabled or not.
- *
- * returns - TRUE for packet filtering or FALSE.
- ****************************************************************************/
-boolean_t
-em_enable_tx_pkt_filtering(struct em_hw *hw)
-{
- /* called in init as well as watchdog timer functions */
-
- int32_t ret_val, checksum;
- boolean_t tx_filter = FALSE;
- struct em_host_mng_dhcp_cookie *hdr = &(hw->mng_cookie);
- uint8_t *buffer = (uint8_t *) &(hw->mng_cookie);
-
- if (em_check_mng_mode(hw)) {
- ret_val = em_mng_enable_host_if(hw);
- if (ret_val == E1000_SUCCESS) {
- ret_val = em_host_if_read_cookie(hw, buffer);
- if (ret_val == E1000_SUCCESS) {
- checksum = hdr->checksum;
- hdr->checksum = 0;
- if ((hdr->signature == E1000_IAMT_SIGNATURE) &&
- checksum == em_calculate_mng_checksum((char *)buffer,
- E1000_MNG_DHCP_COOKIE_LENGTH)) {
- if (hdr->status &
- E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT)
- tx_filter = TRUE;
- } else
- tx_filter = TRUE;
- } else
- tx_filter = TRUE;
- }
- }
-
- hw->tx_pkt_filtering = tx_filter;
- return tx_filter;
-}
-
-/******************************************************************************
- * Verifies the hardware needs to allow ARPs to be processed by the host
- *
- * hw - Struct containing variables accessed by shared code
- *
- * returns: - TRUE/FALSE
- *
- *****************************************************************************/
-uint32_t
-em_enable_mng_pass_thru(struct em_hw *hw)
-{
- uint32_t manc;
- uint32_t fwsm, factps;
-
- if (hw->asf_firmware_present) {
- manc = E1000_READ_REG(hw, MANC);
-
- if (!(manc & E1000_MANC_RCV_TCO_EN) ||
- !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
- return FALSE;
- if (em_arc_subsystem_valid(hw) == TRUE) {
- fwsm = E1000_READ_REG(hw, FWSM);
- factps = E1000_READ_REG(hw, FACTPS);
-
- if (((fwsm & E1000_FWSM_MODE_MASK) ==
- (em_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) &&
- (factps & E1000_FACTPS_MNGCG))
- return TRUE;
- } else
- if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
- return TRUE;
- }
- return FALSE;
-}
-
-static int32_t
-em_polarity_reversal_workaround(struct em_hw *hw)
-{
- int32_t ret_val;
- uint16_t mii_status_reg;
- uint16_t i;
-
- /* Polarity reversal workaround for forced 10F/10H links. */
-
- /* Disable the transmitter on the PHY */
-
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
- if(ret_val)
- return ret_val;
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
- if(ret_val)
- return ret_val;
-
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
- if(ret_val)
- return ret_val;
-
- /* This loop will early-out if the NO link condition has been met. */
- for(i = PHY_FORCE_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Link Status bit
- * to be clear.
- */
-
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
-
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
-
- if((mii_status_reg & ~MII_SR_LINK_STATUS) == 0) break;
- msec_delay_irq(100);
- }
-
- /* Recommended delay time after link has been lost */
- msec_delay_irq(1000);
-
- /* Now we will re-enable th transmitter on the PHY */
-
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
- if(ret_val)
- return ret_val;
- msec_delay_irq(50);
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
- if(ret_val)
- return ret_val;
- msec_delay_irq(50);
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
- if(ret_val)
- return ret_val;
- msec_delay_irq(50);
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
- if(ret_val)
- return ret_val;
-
- ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
- if(ret_val)
- return ret_val;
-
- /* This loop will early-out if the link condition has been met. */
- for(i = PHY_FORCE_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Link Status bit
- * to be set.
- */
-
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
-
- ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if(ret_val)
- return ret_val;
-
- if(mii_status_reg & MII_SR_LINK_STATUS) break;
- msec_delay_irq(100);
- }
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- *
- * Disables PCI-Express master access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - none.
- *
- ***************************************************************************/
-void
-em_set_pci_express_master_disable(struct em_hw *hw)
-{
- uint32_t ctrl;
-
- DEBUGFUNC("em_set_pci_express_master_disable");
-
- if (hw->bus_type != em_bus_type_pci_express)
- return;
-
- ctrl = E1000_READ_REG(hw, CTRL);
- ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
- E1000_WRITE_REG(hw, CTRL, ctrl);
-}
-
-/***************************************************************************
- *
- * Enables PCI-Express master access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - none.
- *
- ***************************************************************************/
-void
-em_enable_pciex_master(struct em_hw *hw)
-{
- uint32_t ctrl;
-
- DEBUGFUNC("em_enable_pciex_master");
-
- if (hw->bus_type != em_bus_type_pci_express)
- return;
-
- ctrl = E1000_READ_REG(hw, CTRL);
- ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
- E1000_WRITE_REG(hw, CTRL, ctrl);
-}
-
-/*******************************************************************************
- *
- * Disables PCI-Express master access and verifies there are no pending requests
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_MASTER_REQUESTS_PENDING if master disable bit hasn't
- * caused the master requests to be disabled.
- * E1000_SUCCESS master requests disabled.
- *
- ******************************************************************************/
-int32_t
-em_disable_pciex_master(struct em_hw *hw)
-{
- int32_t timeout = MASTER_DISABLE_TIMEOUT; /* 80ms */
-
- DEBUGFUNC("em_disable_pciex_master");
-
- if (hw->bus_type != em_bus_type_pci_express)
- return E1000_SUCCESS;
-
- em_set_pci_express_master_disable(hw);
-
- while(timeout) {
- if(!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
- break;
- else
- usec_delay(100);
- timeout--;
- }
-
- if(!timeout) {
- DEBUGOUT("Master requests are pending.\n");
- return -E1000_ERR_MASTER_REQUESTS_PENDING;
- }
-
- return E1000_SUCCESS;
-}
-
-/*******************************************************************************
- *
- * Check for EEPROM Auto Read bit done.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_RESET if fail to reset MAC
- * E1000_SUCCESS at any other case.
- *
- ******************************************************************************/
-int32_t
-em_get_auto_rd_done(struct em_hw *hw)
-{
- int32_t timeout = AUTO_READ_DONE_TIMEOUT;
-
- DEBUGFUNC("em_get_auto_rd_done");
-
- switch (hw->mac_type) {
- default:
- msec_delay(5);
- break;
- case em_82573:
- while(timeout) {
- if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break;
- else msec_delay(1);
- timeout--;
- }
-
- if(!timeout) {
- DEBUGOUT("Auto read by HW from EEPROM has not completed.\n");
- return -E1000_ERR_RESET;
- }
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- * Checks if the PHY configuration is done
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_RESET if fail to reset MAC
- * E1000_SUCCESS at any other case.
- *
- ***************************************************************************/
-int32_t
-em_get_phy_cfg_done(struct em_hw *hw)
-{
- DEBUGFUNC("em_get_phy_cfg_done");
-
- /* Simply wait for 10ms */
- msec_delay(10);
-
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- *
- * Using the combination of SMBI and SWESMBI semaphore bits when resetting
- * adapter or Eeprom access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_EEPROM if fail to access EEPROM.
- * E1000_SUCCESS at any other case.
- *
- ***************************************************************************/
-int32_t
-em_get_hw_eeprom_semaphore(struct em_hw *hw)
-{
- int32_t timeout;
- uint32_t swsm;
-
- DEBUGFUNC("em_get_hw_eeprom_semaphore");
-
- if(!hw->eeprom_semaphore_present)
- return E1000_SUCCESS;
-
-
- /* Get the FW semaphore. */
- timeout = hw->eeprom.word_size + 1;
- while(timeout) {
- swsm = E1000_READ_REG(hw, SWSM);
- swsm |= E1000_SWSM_SWESMBI;
- E1000_WRITE_REG(hw, SWSM, swsm);
- /* if we managed to set the bit we got the semaphore. */
- swsm = E1000_READ_REG(hw, SWSM);
- if(swsm & E1000_SWSM_SWESMBI)
- break;
-
- usec_delay(50);
- timeout--;
- }
-
- if(!timeout) {
- /* Release semaphores */
- em_put_hw_eeprom_semaphore(hw);
- DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n");
- return -E1000_ERR_EEPROM;
- }
-
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- * This function clears HW semaphore bits.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - None.
- *
- ***************************************************************************/
-void
-em_put_hw_eeprom_semaphore(struct em_hw *hw)
-{
- uint32_t swsm;
-
- DEBUGFUNC("em_put_hw_eeprom_semaphore");
-
- if(!hw->eeprom_semaphore_present)
- return;
-
- swsm = E1000_READ_REG(hw, SWSM);
- /* Release both semaphores. */
- swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
- E1000_WRITE_REG(hw, SWSM, swsm);
-}
-
-/******************************************************************************
- * Checks if PHY reset is blocked due to SOL/IDER session, for example.
- * Returning E1000_BLK_PHY_RESET isn't necessarily an error. But it's up to
- * the caller to figure out how to deal with it.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * returns: - E1000_BLK_PHY_RESET
- * E1000_SUCCESS
- *
- *****************************************************************************/
-int32_t
-em_check_phy_reset_block(struct em_hw *hw)
-{
- uint32_t manc = 0;
- if(hw->mac_type > em_82547_rev_2)
- manc = E1000_READ_REG(hw, MANC);
- return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
- E1000_BLK_PHY_RESET : E1000_SUCCESS;
-}
-
-uint8_t
-em_arc_subsystem_valid(struct em_hw *hw)
-{
- uint32_t fwsm;
-
- /* On 8257x silicon, registers in the range of 0x8800 - 0x8FFC
- * may not be provided a DMA clock when no manageability features are
- * enabled. We do not want to perform any reads/writes to these registers
- * if this is the case. We read FWSM to determine the manageability mode.
- */
- switch (hw->mac_type) {
- case em_82573:
- fwsm = E1000_READ_REG(hw, FWSM);
- if((fwsm & E1000_FWSM_MODE_MASK) != 0)
- return TRUE;
- break;
- default:
- break;
- }
- return FALSE;
-}
-
-
-
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_hw.h b/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_hw.h
deleted file mode 100644
index 98f4c5e6ba..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_hw.h
+++ /dev/null
@@ -1,2678 +0,0 @@
-/*******************************************************************************
-
- 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:
-
- 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: /repoman/r/ncvs/src/sys/dev/em/if_em_hw.h,v 1.15 2005/05/26 23:32:02 tackerman Exp $*/
-/* if_em_hw.h
- * Structures, enums, and macros for the MAC
- */
-
-#ifndef _EM_HW_H_
-#define _EM_HW_H_
-
-#ifndef __rtems__
-#include <dev/em/if_em_osdep.h>
-#else
-#include "if_em_osdep.h"
-#endif
-
-
-/* Forward declarations of structures used by the shared code */
-struct em_hw;
-struct em_hw_stats;
-
-/* Enumerated types specific to the e1000 hardware */
-/* Media Access Controlers */
-typedef enum {
- em_undefined = 0,
- em_82542_rev2_0,
- em_82542_rev2_1,
- em_82543,
- em_82544,
- em_82540,
- em_82545,
- em_82545_rev_3,
- em_82546,
- em_82546_rev_3,
- em_82541,
- em_82541_rev_2,
- em_82547,
- em_82547_rev_2,
- em_82573,
- em_num_macs
-} em_mac_type;
-
-typedef enum {
- em_eeprom_uninitialized = 0,
- em_eeprom_spi,
- em_eeprom_microwire,
- em_eeprom_flash,
- em_num_eeprom_types
-} em_eeprom_type;
-
-/* Media Types */
-typedef enum {
- em_media_type_copper = 0,
- em_media_type_fiber = 1,
- em_media_type_internal_serdes = 2,
- em_num_media_types
-} em_media_type;
-
-typedef enum {
- em_10_half = 0,
- em_10_full = 1,
- em_100_half = 2,
- em_100_full = 3
-} em_speed_duplex_type;
-
-/* Flow Control Settings */
-typedef enum {
- em_fc_none = 0,
- em_fc_rx_pause = 1,
- em_fc_tx_pause = 2,
- em_fc_full = 3,
- em_fc_default = 0xFF
-} em_fc_type;
-
-/* PCI bus types */
-typedef enum {
- em_bus_type_unknown = 0,
- em_bus_type_pci,
- em_bus_type_pcix,
- em_bus_type_pci_express,
- em_bus_type_reserved
-} em_bus_type;
-
-/* PCI bus speeds */
-typedef enum {
- em_bus_speed_unknown = 0,
- em_bus_speed_33,
- em_bus_speed_66,
- em_bus_speed_100,
- em_bus_speed_120,
- em_bus_speed_133,
- em_bus_speed_2500,
- em_bus_speed_reserved
-} em_bus_speed;
-
-/* PCI bus widths */
-typedef enum {
- em_bus_width_unknown = 0,
- em_bus_width_32,
- em_bus_width_64,
- em_bus_width_pciex_1,
- em_bus_width_pciex_4,
- em_bus_width_reserved
-} em_bus_width;
-
-/* PHY status info structure and supporting enums */
-typedef enum {
- em_cable_length_50 = 0,
- em_cable_length_50_80,
- em_cable_length_80_110,
- em_cable_length_110_140,
- em_cable_length_140,
- em_cable_length_undefined = 0xFF
-} em_cable_length;
-
-typedef enum {
- em_igp_cable_length_10 = 10,
- em_igp_cable_length_20 = 20,
- em_igp_cable_length_30 = 30,
- em_igp_cable_length_40 = 40,
- em_igp_cable_length_50 = 50,
- em_igp_cable_length_60 = 60,
- em_igp_cable_length_70 = 70,
- em_igp_cable_length_80 = 80,
- em_igp_cable_length_90 = 90,
- em_igp_cable_length_100 = 100,
- em_igp_cable_length_110 = 110,
- em_igp_cable_length_120 = 120,
- em_igp_cable_length_130 = 130,
- em_igp_cable_length_140 = 140,
- em_igp_cable_length_150 = 150,
- em_igp_cable_length_160 = 160,
- em_igp_cable_length_170 = 170,
- em_igp_cable_length_180 = 180
-} em_igp_cable_length;
-
-typedef enum {
- em_10bt_ext_dist_enable_normal = 0,
- em_10bt_ext_dist_enable_lower,
- em_10bt_ext_dist_enable_undefined = 0xFF
-} em_10bt_ext_dist_enable;
-
-typedef enum {
- em_rev_polarity_normal = 0,
- em_rev_polarity_reversed,
- em_rev_polarity_undefined = 0xFF
-} em_rev_polarity;
-
-typedef enum {
- em_downshift_normal = 0,
- em_downshift_activated,
- em_downshift_undefined = 0xFF
-} em_downshift;
-
-typedef enum {
- em_smart_speed_default = 0,
- em_smart_speed_on,
- em_smart_speed_off
-} em_smart_speed;
-
-typedef enum {
- em_polarity_reversal_enabled = 0,
- em_polarity_reversal_disabled,
- em_polarity_reversal_undefined = 0xFF
-} em_polarity_reversal;
-
-typedef enum {
- em_auto_x_mode_manual_mdi = 0,
- em_auto_x_mode_manual_mdix,
- em_auto_x_mode_auto1,
- em_auto_x_mode_auto2,
- em_auto_x_mode_undefined = 0xFF
-} em_auto_x_mode;
-
-typedef enum {
- em_1000t_rx_status_not_ok = 0,
- em_1000t_rx_status_ok,
- em_1000t_rx_status_undefined = 0xFF
-} em_1000t_rx_status;
-
-typedef enum {
- em_phy_m88 = 0,
- em_phy_igp,
- em_phy_igp_2,
- em_phy_undefined = 0xFF
-} em_phy_type;
-
-typedef enum {
- em_ms_hw_default = 0,
- em_ms_force_master,
- em_ms_force_slave,
- em_ms_auto
-} em_ms_type;
-
-typedef enum {
- em_ffe_config_enabled = 0,
- em_ffe_config_active,
- em_ffe_config_blocked
-} em_ffe_config;
-
-typedef enum {
- em_dsp_config_disabled = 0,
- em_dsp_config_enabled,
- em_dsp_config_activated,
- em_dsp_config_undefined = 0xFF
-} em_dsp_config;
-
-struct em_phy_info {
- em_cable_length cable_length;
- em_10bt_ext_dist_enable extended_10bt_distance;
- em_rev_polarity cable_polarity;
- em_downshift downshift;
- em_polarity_reversal polarity_correction;
- em_auto_x_mode mdix_mode;
- em_1000t_rx_status local_rx;
- em_1000t_rx_status remote_rx;
-};
-
-struct em_phy_stats {
- uint32_t idle_errors;
- uint32_t receive_errors;
-};
-
-struct em_eeprom_info {
- em_eeprom_type type;
- uint16_t word_size;
- uint16_t opcode_bits;
- uint16_t address_bits;
- uint16_t delay_usec;
- uint16_t page_size;
- boolean_t use_eerd;
- boolean_t use_eewr;
-};
-
-/* Flex ASF Information */
-#define E1000_HOST_IF_MAX_SIZE 2048
-
-typedef enum {
- em_byte_align = 0,
- em_word_align = 1,
- em_dword_align = 2
-} em_align_type;
-
-
-
-/* Error Codes */
-#define E1000_SUCCESS 0
-#define E1000_ERR_EEPROM 1
-#define E1000_ERR_PHY 2
-#define E1000_ERR_CONFIG 3
-#define E1000_ERR_PARAM 4
-#define E1000_ERR_MAC_TYPE 5
-#define E1000_ERR_PHY_TYPE 6
-#define E1000_ERR_RESET 9
-#define E1000_ERR_MASTER_REQUESTS_PENDING 10
-#define E1000_ERR_HOST_INTERFACE_COMMAND 11
-#define E1000_BLK_PHY_RESET 12
-
-/* Function prototypes */
-/* Initialization */
-int32_t em_reset_hw(struct em_hw *hw);
-int32_t em_init_hw(struct em_hw *hw);
-int32_t em_id_led_init(struct em_hw * hw);
-int32_t em_set_mac_type(struct em_hw *hw);
-void em_set_media_type(struct em_hw *hw);
-
-/* Link Configuration */
-int32_t em_setup_link(struct em_hw *hw);
-int32_t em_phy_setup_autoneg(struct em_hw *hw);
-void em_config_collision_dist(struct em_hw *hw);
-int32_t em_config_fc_after_link_up(struct em_hw *hw);
-int32_t em_check_for_link(struct em_hw *hw);
-int32_t em_get_speed_and_duplex(struct em_hw *hw, uint16_t * speed, uint16_t * duplex);
-int32_t em_wait_autoneg(struct em_hw *hw);
-int32_t em_force_mac_fc(struct em_hw *hw);
-
-/* PHY */
-int32_t em_read_phy_reg(struct em_hw *hw, uint32_t reg_addr, uint16_t *phy_data);
-int32_t em_write_phy_reg(struct em_hw *hw, uint32_t reg_addr, uint16_t data);
-int32_t em_phy_hw_reset(struct em_hw *hw);
-int32_t em_phy_reset(struct em_hw *hw);
-int32_t em_detect_gig_phy(struct em_hw *hw);
-int32_t em_phy_get_info(struct em_hw *hw, struct em_phy_info *phy_info);
-int32_t em_phy_m88_get_info(struct em_hw *hw, struct em_phy_info *phy_info);
-int32_t em_phy_igp_get_info(struct em_hw *hw, struct em_phy_info *phy_info);
-int32_t em_get_cable_length(struct em_hw *hw, uint16_t *min_length, uint16_t *max_length);
-int32_t em_check_polarity(struct em_hw *hw, uint16_t *polarity);
-int32_t em_check_downshift(struct em_hw *hw);
-int32_t em_validate_mdi_setting(struct em_hw *hw);
-
-/* EEPROM Functions */
-int32_t em_init_eeprom_params(struct em_hw *hw);
-boolean_t em_is_onboard_nvm_eeprom(struct em_hw *hw);
-int32_t em_read_eeprom_eerd(struct em_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-int32_t em_write_eeprom_eewr(struct em_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-int32_t em_poll_eerd_eewr_done(struct em_hw *hw, int eerd);
-
-/* MNG HOST IF functions */
-uint32_t em_enable_mng_pass_thru(struct em_hw *hw);
-
-#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
-#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 /* Host Interface data length */
-
-#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 /* Time in ms to process MNG command */
-#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 /* Cookie offset */
-#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 /* Cookie length */
-#define E1000_MNG_IAMT_MODE 0x3
-#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management Technology signature */
-
-#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT 0x1 /* DHCP parsing enabled */
-#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT 0x2 /* DHCP parsing enabled */
-#define E1000_VFTA_ENTRY_SHIFT 0x5
-#define E1000_VFTA_ENTRY_MASK 0x7F
-#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
-
-struct em_host_mng_command_header {
- uint8_t command_id;
- uint8_t checksum;
- uint16_t reserved1;
- uint16_t reserved2;
- uint16_t command_length;
-};
-
-struct em_host_mng_command_info {
- struct em_host_mng_command_header command_header; /* Command Head/Command Result Head has 4 bytes */
- uint8_t command_data[E1000_HI_MAX_MNG_DATA_LENGTH]; /* Command data can length 0..0x658*/
-};
-#ifdef __BIG_ENDIAN
-struct em_host_mng_dhcp_cookie{
- uint32_t signature;
- uint16_t vlan_id;
- uint8_t reserved0;
- uint8_t status;
- uint32_t reserved1;
- uint8_t checksum;
- uint8_t reserved3;
- uint16_t reserved2;
-};
-#else
-struct em_host_mng_dhcp_cookie{
- uint32_t signature;
- uint8_t status;
- uint8_t reserved0;
- uint16_t vlan_id;
- uint32_t reserved1;
- uint16_t reserved2;
- uint8_t reserved3;
- uint8_t checksum;
-};
-#endif
-
-int32_t em_mng_write_dhcp_info(struct em_hw *hw, uint8_t *buffer,
- uint16_t length);
-boolean_t em_check_mng_mode(struct em_hw *hw);
-boolean_t em_enable_tx_pkt_filtering(struct em_hw *hw);
-int32_t em_mng_enable_host_if(struct em_hw *hw);
-int32_t em_mng_host_if_write(struct em_hw *hw, uint8_t *buffer,
- uint16_t length, uint16_t offset, uint8_t *sum);
-int32_t em_mng_write_cmd_header(struct em_hw* hw,
- struct em_host_mng_command_header* hdr);
-
-int32_t em_mng_write_commit(struct em_hw *hw);
-
-int32_t em_read_eeprom(struct em_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
-int32_t em_validate_eeprom_checksum(struct em_hw *hw);
-int32_t em_update_eeprom_checksum(struct em_hw *hw);
-int32_t em_write_eeprom(struct em_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
-int32_t em_read_part_num(struct em_hw *hw, uint32_t * part_num);
-int32_t em_read_mac_addr(struct em_hw * hw);
-int32_t em_swfw_sync_acquire(struct em_hw *hw, uint16_t mask);
-void em_swfw_sync_release(struct em_hw *hw, uint16_t mask);
-
-/* Filters (multicast, vlan, receive) */
-void em_init_rx_addrs(struct em_hw *hw);
-void em_mc_addr_list_update(struct em_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad, uint32_t rar_used_count);
-uint32_t em_hash_mc_addr(struct em_hw *hw, uint8_t * mc_addr);
-void em_mta_set(struct em_hw *hw, uint32_t hash_value);
-void em_rar_set(struct em_hw *hw, uint8_t * mc_addr, uint32_t rar_index);
-void em_write_vfta(struct em_hw *hw, uint32_t offset, uint32_t value);
-void em_clear_vfta(struct em_hw *hw);
-
-/* LED functions */
-int32_t em_setup_led(struct em_hw *hw);
-int32_t em_cleanup_led(struct em_hw *hw);
-int32_t em_led_on(struct em_hw *hw);
-int32_t em_led_off(struct em_hw *hw);
-
-/* Adaptive IFS Functions */
-
-/* Everything else */
-void em_clear_hw_cntrs(struct em_hw *hw);
-void em_reset_adaptive(struct em_hw *hw);
-void em_update_adaptive(struct em_hw *hw);
-void em_tbi_adjust_stats(struct em_hw *hw, struct em_hw_stats *stats, uint32_t frame_len, uint8_t * mac_addr);
-void em_get_bus_info(struct em_hw *hw);
-void em_pci_set_mwi(struct em_hw *hw);
-void em_pci_clear_mwi(struct em_hw *hw);
-void em_read_pci_cfg(struct em_hw *hw, uint32_t reg, uint16_t * value);
-void em_write_pci_cfg(struct em_hw *hw, uint32_t reg, uint16_t * value);
-/* Port I/O is only supported on 82544 and newer */
-uint32_t em_io_read(struct em_hw *hw, unsigned long port);
-uint32_t em_read_reg_io(struct em_hw *hw, uint32_t offset);
-void em_io_write(struct em_hw *hw, unsigned long port, uint32_t value);
-void em_write_reg_io(struct em_hw *hw, uint32_t offset, uint32_t value);
-int32_t em_config_dsp_after_link_change(struct em_hw *hw, boolean_t link_up);
-int32_t em_set_d3_lplu_state(struct em_hw *hw, boolean_t active);
-int32_t em_set_d0_lplu_state(struct em_hw *hw, boolean_t active);
-void em_set_pci_express_master_disable(struct em_hw *hw);
-void em_enable_pciex_master(struct em_hw *hw);
-int32_t em_disable_pciex_master(struct em_hw *hw);
-int32_t em_get_auto_rd_done(struct em_hw *hw);
-int32_t em_get_phy_cfg_done(struct em_hw *hw);
-int32_t em_get_software_semaphore(struct em_hw *hw);
-void em_release_software_semaphore(struct em_hw *hw);
-int32_t em_check_phy_reset_block(struct em_hw *hw);
-int32_t em_get_hw_eeprom_semaphore(struct em_hw *hw);
-void em_put_hw_eeprom_semaphore(struct em_hw *hw);
-int32_t em_commit_shadow_ram(struct em_hw *hw);
-uint8_t em_arc_subsystem_valid(struct em_hw *hw);
-
-#define E1000_READ_REG_IO(a, reg) \
- em_read_reg_io((a), E1000_##reg)
-#define E1000_WRITE_REG_IO(a, reg, val) \
- em_write_reg_io((a), E1000_##reg, val)
-
-/* PCI Device IDs */
-#define E1000_DEV_ID_82542 0x1000
-#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_82541ER_LOM 0x1014
-#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_82541EI 0x1013
-#define E1000_DEV_ID_82541EI_MOBILE 0x1018
-#define E1000_DEV_ID_82541ER 0x1078
-#define E1000_DEV_ID_82547GI 0x1075
-#define E1000_DEV_ID_82541GI 0x1076
-#define E1000_DEV_ID_82541GI_MOBILE 0x1077
-#define E1000_DEV_ID_82541GI_LF 0x107C
-#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_82547EI 0x1019
-#define E1000_DEV_ID_82547EI_MOBILE 0x101A
-#define E1000_DEV_ID_82573E 0x108B
-#define E1000_DEV_ID_82573E_IAMT 0x108C
-
-#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
-
-#define NODE_ADDRESS_SIZE 6
-#define ETH_LENGTH_OF_ADDRESS 6
-
-/* MAC decode size is 128K - This is the size of BAR0 */
-#define MAC_DECODE_SIZE (128 * 1024)
-
-#define E1000_82542_2_0_REV_ID 2
-#define E1000_82542_2_1_REV_ID 3
-#define E1000_REVISION_0 0
-#define E1000_REVISION_1 1
-#define E1000_REVISION_2 2
-#define E1000_REVISION_3 3
-
-#define SPEED_10 10
-#define SPEED_100 100
-#define SPEED_1000 1000
-#define HALF_DUPLEX 1
-#define FULL_DUPLEX 2
-
-/* The sizes (in bytes) of a ethernet packet */
-#define ENET_HEADER_SIZE 14
-#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* With FCS */
-#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
-#define ETHERNET_FCS_SIZE 4
-#define MAXIMUM_ETHERNET_PACKET_SIZE \
- (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
-#define MINIMUM_ETHERNET_PACKET_SIZE \
- (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
-#define CRC_LENGTH ETHERNET_FCS_SIZE
-#define MAX_JUMBO_FRAME_SIZE 0x3F00
-
-
-/* 802.1q VLAN Packet Sizes */
-#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */
-
-/* Ethertype field values */
-#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */
-#define ETHERNET_IP_TYPE 0x0800 /* IP packets */
-#define ETHERNET_ARP_TYPE 0x0806 /* Address Resolution Protocol (ARP) */
-
-/* Packet Header defines */
-#define IP_PROTOCOL_TCP 6
-#define IP_PROTOCOL_UDP 0x11
-
-/* This defines the bits that are set in the Interrupt Mask
- * Set/Read Register. Each bit is documented below:
- * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
- * o RXSEQ = Receive Sequence Error
- */
-#define POLL_IMS_ENABLE_MASK ( \
- E1000_IMS_RXDMT0 | \
- E1000_IMS_RXSEQ)
-
-/* This defines the bits that are set in the Interrupt Mask
- * Set/Read Register. Each bit is documented below:
- * o RXT0 = Receiver Timer Interrupt (ring 0)
- * o TXDW = Transmit Descriptor Written Back
- * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
- * o RXSEQ = Receive Sequence Error
- * o LSC = Link Status Change
- */
-#define IMS_ENABLE_MASK ( \
- E1000_IMS_RXT0 | \
- E1000_IMS_TXDW | \
- E1000_IMS_RXDMT0 | \
- E1000_IMS_RXSEQ | \
- E1000_IMS_LSC)
-
-
-/* Number of high/low register pairs in the RAR. The RAR (Receive Address
- * Registers) holds the directed and multicast addresses that we monitor. We
- * reserve one of these spots for our directed address, allowing us room for
- * E1000_RAR_ENTRIES - 1 multicast addresses.
- */
-#define E1000_RAR_ENTRIES 15
-
-#define MIN_NUMBER_OF_DESCRIPTORS 8
-#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
-
-/* Receive Descriptor */
-struct em_rx_desc {
- uint64_t buffer_addr; /* Address of the descriptor's data buffer */
- uint16_t length; /* Length of data DMAed into data buffer */
- uint16_t csum; /* Packet checksum */
- uint8_t status; /* Descriptor status */
- uint8_t errors; /* Descriptor Errors */
- uint16_t special;
-};
-
-/* Receive Descriptor - Extended */
-union em_rx_desc_extended {
- struct {
- uint64_t buffer_addr;
- uint64_t reserved;
- } read;
- struct {
- struct {
- uint32_t mrq; /* Multiple Rx Queues */
- union {
- uint32_t rss; /* RSS Hash */
- struct {
- uint16_t ip_id; /* IP id */
- uint16_t csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- uint32_t status_error; /* ext status/error */
- uint16_t length;
- uint16_t vlan; /* VLAN tag */
- } upper;
- } wb; /* writeback */
-};
-
-#define MAX_PS_BUFFERS 4
-/* Receive Descriptor - Packet Split */
-union em_rx_desc_packet_split {
- struct {
- /* one buffer for protocol header(s), three data buffers */
- uint64_t buffer_addr[MAX_PS_BUFFERS];
- } read;
- struct {
- struct {
- uint32_t mrq; /* Multiple Rx Queues */
- union {
- uint32_t rss; /* RSS Hash */
- struct {
- uint16_t ip_id; /* IP id */
- uint16_t csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- uint32_t status_error; /* ext status/error */
- uint16_t length0; /* length of buffer 0 */
- uint16_t vlan; /* VLAN tag */
- } middle;
- struct {
- uint16_t header_status;
- uint16_t length[3]; /* length of buffers 1-3 */
- } upper;
- uint64_t reserved;
- } wb; /* writeback */
-};
-
-/* Receive Decriptor bit definitions */
-#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
-#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
-#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
-#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
-#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
-#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
-#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
-#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */
-#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
-#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
-#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
-#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
-#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
-#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
-#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
-#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
-#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
-#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
-#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
-#define E1000_RXD_SPC_PRI_SHIFT 13
-#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */
-#define E1000_RXD_SPC_CFI_SHIFT 12
-
-#define E1000_RXDEXT_STATERR_CE 0x01000000
-#define E1000_RXDEXT_STATERR_SE 0x02000000
-#define E1000_RXDEXT_STATERR_SEQ 0x04000000
-#define E1000_RXDEXT_STATERR_CXE 0x10000000
-#define E1000_RXDEXT_STATERR_TCPE 0x20000000
-#define E1000_RXDEXT_STATERR_IPE 0x40000000
-#define E1000_RXDEXT_STATERR_RXE 0x80000000
-
-#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
-#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
-
-/* mask to determine if packets should be dropped due to frame errors */
-#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
- E1000_RXD_ERR_CE | \
- E1000_RXD_ERR_SE | \
- E1000_RXD_ERR_SEQ | \
- E1000_RXD_ERR_CXE | \
- E1000_RXD_ERR_RXE)
-
-
-/* Same mask, but for extended and packet split descriptors */
-#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
- E1000_RXDEXT_STATERR_CE | \
- E1000_RXDEXT_STATERR_SE | \
- E1000_RXDEXT_STATERR_SEQ | \
- E1000_RXDEXT_STATERR_CXE | \
- E1000_RXDEXT_STATERR_RXE)
-
-/* Transmit Descriptor */
-struct em_tx_desc {
- uint64_t buffer_addr; /* Address of the descriptor's data buffer */
- union {
- uint32_t data;
- struct {
- uint16_t length; /* Data buffer length */
- uint8_t cso; /* Checksum offset */
- uint8_t cmd; /* Descriptor control */
- } flags;
- } lower;
- union {
- uint32_t data;
- struct {
- uint8_t status; /* Descriptor status */
- uint8_t css; /* Checksum start */
- uint16_t special;
- } fields;
- } upper;
-};
-
-/* Transmit Descriptor bit definitions */
-#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
-#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
-#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
-#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
-#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
-#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
-#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
-#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
-#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
-#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
-#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
-#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
-#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
-#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
-#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
-#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
-#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
-#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
-#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
-#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
-
-/* Offload Context Descriptor */
-struct em_context_desc {
- union {
- uint32_t ip_config;
- struct {
- uint8_t ipcss; /* IP checksum start */
- uint8_t ipcso; /* IP checksum offset */
- uint16_t ipcse; /* IP checksum end */
- } ip_fields;
- } lower_setup;
- union {
- uint32_t tcp_config;
- struct {
- uint8_t tucss; /* TCP checksum start */
- uint8_t tucso; /* TCP checksum offset */
- uint16_t tucse; /* TCP checksum end */
- } tcp_fields;
- } upper_setup;
- uint32_t cmd_and_length; /* */
- union {
- uint32_t data;
- struct {
- uint8_t status; /* Descriptor status */
- uint8_t hdr_len; /* Header length */
- uint16_t mss; /* Maximum segment size */
- } fields;
- } tcp_seg_setup;
-};
-
-/* Offload data descriptor */
-struct em_data_desc {
- uint64_t buffer_addr; /* Address of the descriptor's buffer address */
- union {
- uint32_t data;
- struct {
- uint16_t length; /* Data buffer length */
- uint8_t typ_len_ext; /* */
- uint8_t cmd; /* */
- } flags;
- } lower;
- union {
- uint32_t data;
- struct {
- uint8_t status; /* Descriptor status */
- uint8_t popts; /* Packet Options */
- uint16_t special; /* */
- } fields;
- } upper;
-};
-
-/* Filters */
-#define E1000_NUM_UNICAST 16 /* Unicast filter entries */
-#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
-#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
-
-
-/* Receive Address Register */
-struct em_rar {
- volatile uint32_t low; /* receive address low */
- volatile uint32_t high; /* receive address high */
-};
-
-/* Number of entries in the Multicast Table Array (MTA). */
-#define E1000_NUM_MTA_REGISTERS 128
-
-/* IPv4 Address Table Entry */
-struct em_ipv4_at_entry {
- volatile uint32_t ipv4_addr; /* IP Address (RW) */
- volatile uint32_t reserved;
-};
-
-/* Four wakeup IP addresses are supported */
-#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
-#define E1000_IP4AT_SIZE E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
-#define E1000_IP6AT_SIZE 1
-
-/* IPv6 Address Table Entry */
-struct em_ipv6_at_entry {
- volatile uint8_t ipv6_addr[16];
-};
-
-/* Flexible Filter Length Table Entry */
-struct em_fflt_entry {
- volatile uint32_t length; /* Flexible Filter Length (RW) */
- volatile uint32_t reserved;
-};
-
-/* Flexible Filter Mask Table Entry */
-struct em_ffmt_entry {
- volatile uint32_t mask; /* Flexible Filter Mask (RW) */
- volatile uint32_t reserved;
-};
-
-/* Flexible Filter Value Table Entry */
-struct em_ffvt_entry {
- volatile uint32_t value; /* Flexible Filter Value (RW) */
- volatile uint32_t reserved;
-};
-
-/* Four Flexible Filters are supported */
-#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
-
-/* Each Flexible Filter is at most 128 (0x80) bytes in length */
-#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128
-
-#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
-#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
-#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
-
-/* Register Set. (82543, 82544)
- *
- * Registers are defined to be 32 bits and should be accessed as 32 bit values.
- * These registers are physically located on the NIC, but are mapped into the
- * host memory address space.
- *
- * RW - register is both readable and writable
- * RO - register is read only
- * WO - register is write only
- * R/clr - register is read only and is cleared when read
- * A - register array
- */
-#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_FCAL 0x00028 /* Flow Control Address Low - RW */
-#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
-#define E1000_FCT 0x00030 /* Flow Control Type - RW */
-#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
-#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
-#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
-#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
-#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
-#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
-#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
-#define E1000_RCTL 0x00100 /* RX Control - RW */
-#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
-#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
-#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
-#define E1000_TCTL 0x00400 /* 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_PBA 0x01000 /* Packet Buffer Allocation - RW */
-#define E1000_PBS 0x01008 /* Packet Buffer Size */
-#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
-#define E1000_FLASH_UPDATES 1000
-#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
-#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
-#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
-#define E1000_FLSWCTL 0x01030 /* FLASH control register */
-#define E1000_FLSWDATA 0x01034 /* FLASH data register */
-#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
-#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
-#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
-#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
-#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
-#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
-#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
-#define E1000_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_RXDCTL 0x02828 /* RX Descriptor Control - RW */
-#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - 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_TDFH 0x03410 /* TX Data FIFO Head - RW */
-#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
-#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
-#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */
-#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
-#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
-#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
-#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
-#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
-#define E1000_TDT 0x03818 /* TX Descripotr 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_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */
-#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */
-#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */
-#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */
-#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */
-#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */
-#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */
-#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
-#define E1000_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 0x4100 /* Interrupt Assertion Count */
-#define E1000_ICRXPTC 0x4104 /* Interrupt Cause Rx Packet Timer Expire Count */
-#define E1000_ICRXATC 0x4108 /* Interrupt Cause Rx Absolute Timer Expire Count */
-#define E1000_ICTXPTC 0x410C /* Interrupt Cause Tx Packet Timer Expire Count */
-#define E1000_ICTXATC 0x4110 /* Interrupt Cause Tx Absolute Timer Expire Count */
-#define E1000_ICTXQEC 0x4118 /* Interrupt Cause Tx Queue Empty Count */
-#define E1000_ICTXQMTC 0x411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
-#define E1000_ICRXDMTC 0x4120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
-#define E1000_ICRXOC 0x4124 /* Interrupt Cause Receiver Overrun Count */
-#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
-#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
-#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
-#define E1000_RA 0x05400 /* Receive Address - RW Array */
-#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
-#define E1000_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_GCR 0x05B00 /* PCI-Ex Control */
-#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
-#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
-#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
-#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
-#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
-#define E1000_SWSM 0x05B50 /* SW Semaphore */
-#define E1000_FWSM 0x05B54 /* FW Semaphore */
-#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
-#define E1000_HICR 0x08F00 /* Host Inteface Control */
-/* Register Set (82542)
- *
- * Some of the 82542 registers are located at different offsets than they are
- * in more current versions of the 8254x. Despite the difference in location,
- * the registers function in the same manner.
- */
-#define E1000_82542_CTRL E1000_CTRL
-#define E1000_82542_CTRL_DUP E1000_CTRL_DUP
-#define E1000_82542_STATUS E1000_STATUS
-#define E1000_82542_EECD E1000_EECD
-#define E1000_82542_EERD E1000_EERD
-#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
-#define E1000_82542_FLA E1000_FLA
-#define E1000_82542_MDIC E1000_MDIC
-#define E1000_82542_FCAL E1000_FCAL
-#define E1000_82542_FCAH E1000_FCAH
-#define E1000_82542_FCT E1000_FCT
-#define E1000_82542_VET E1000_VET
-#define E1000_82542_RA 0x00040
-#define E1000_82542_ICR E1000_ICR
-#define E1000_82542_ITR E1000_ITR
-#define E1000_82542_ICS E1000_ICS
-#define E1000_82542_IMS E1000_IMS
-#define E1000_82542_IMC E1000_IMC
-#define E1000_82542_RCTL E1000_RCTL
-#define E1000_82542_RDTR 0x00108
-#define E1000_82542_RDBAL 0x00110
-#define E1000_82542_RDBAH 0x00114
-#define E1000_82542_RDLEN 0x00118
-#define E1000_82542_RDH 0x00120
-#define E1000_82542_RDT 0x00128
-#define E1000_82542_FCRTH 0x00160
-#define E1000_82542_FCRTL 0x00168
-#define E1000_82542_FCTTV E1000_FCTTV
-#define E1000_82542_TXCW E1000_TXCW
-#define E1000_82542_RXCW E1000_RXCW
-#define E1000_82542_MTA 0x00200
-#define E1000_82542_TCTL E1000_TCTL
-#define E1000_82542_TIPG E1000_TIPG
-#define E1000_82542_TDBAL 0x00420
-#define E1000_82542_TDBAH 0x00424
-#define E1000_82542_TDLEN 0x00428
-#define E1000_82542_TDH 0x00430
-#define E1000_82542_TDT 0x00438
-#define E1000_82542_TIDV 0x00440
-#define E1000_82542_TBT E1000_TBT
-#define E1000_82542_AIT E1000_AIT
-#define E1000_82542_VFTA 0x00600
-#define E1000_82542_LEDCTL E1000_LEDCTL
-#define E1000_82542_PBA E1000_PBA
-#define E1000_82542_PBS E1000_PBS
-#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
-#define E1000_82542_EEARBC E1000_EEARBC
-#define E1000_82542_FLASHT E1000_FLASHT
-#define E1000_82542_EEWR E1000_EEWR
-#define E1000_82542_FLSWCTL E1000_FLSWCTL
-#define E1000_82542_FLSWDATA E1000_FLSWDATA
-#define E1000_82542_FLSWCNT E1000_FLSWCNT
-#define E1000_82542_FLOP E1000_FLOP
-#define E1000_82542_EXTCNF_CTRL E1000_EXTCNF_CTRL
-#define E1000_82542_EXTCNF_SIZE E1000_EXTCNF_SIZE
-#define E1000_82542_ERT E1000_ERT
-#define E1000_82542_RXDCTL E1000_RXDCTL
-#define E1000_82542_RADV E1000_RADV
-#define E1000_82542_RSRPD E1000_RSRPD
-#define E1000_82542_TXDMAC E1000_TXDMAC
-#define E1000_82542_TDFHS E1000_TDFHS
-#define E1000_82542_TDFTS E1000_TDFTS
-#define E1000_82542_TDFPC E1000_TDFPC
-#define E1000_82542_TXDCTL E1000_TXDCTL
-#define E1000_82542_TADV E1000_TADV
-#define E1000_82542_TSPMT E1000_TSPMT
-#define E1000_82542_CRCERRS E1000_CRCERRS
-#define E1000_82542_ALGNERRC E1000_ALGNERRC
-#define E1000_82542_SYMERRS E1000_SYMERRS
-#define E1000_82542_RXERRC E1000_RXERRC
-#define E1000_82542_MPC E1000_MPC
-#define E1000_82542_SCC E1000_SCC
-#define E1000_82542_ECOL E1000_ECOL
-#define E1000_82542_MCC E1000_MCC
-#define E1000_82542_LATECOL E1000_LATECOL
-#define E1000_82542_COLC E1000_COLC
-#define E1000_82542_DC E1000_DC
-#define E1000_82542_TNCRS E1000_TNCRS
-#define E1000_82542_SEC E1000_SEC
-#define E1000_82542_CEXTERR E1000_CEXTERR
-#define E1000_82542_RLEC E1000_RLEC
-#define E1000_82542_XONRXC E1000_XONRXC
-#define E1000_82542_XONTXC E1000_XONTXC
-#define E1000_82542_XOFFRXC E1000_XOFFRXC
-#define E1000_82542_XOFFTXC E1000_XOFFTXC
-#define E1000_82542_FCRUC E1000_FCRUC
-#define E1000_82542_PRC64 E1000_PRC64
-#define E1000_82542_PRC127 E1000_PRC127
-#define E1000_82542_PRC255 E1000_PRC255
-#define E1000_82542_PRC511 E1000_PRC511
-#define E1000_82542_PRC1023 E1000_PRC1023
-#define E1000_82542_PRC1522 E1000_PRC1522
-#define E1000_82542_GPRC E1000_GPRC
-#define E1000_82542_BPRC E1000_BPRC
-#define E1000_82542_MPRC E1000_MPRC
-#define E1000_82542_GPTC E1000_GPTC
-#define E1000_82542_GORCL E1000_GORCL
-#define E1000_82542_GORCH E1000_GORCH
-#define E1000_82542_GOTCL E1000_GOTCL
-#define E1000_82542_GOTCH E1000_GOTCH
-#define E1000_82542_RNBC E1000_RNBC
-#define E1000_82542_RUC E1000_RUC
-#define E1000_82542_RFC E1000_RFC
-#define E1000_82542_ROC E1000_ROC
-#define E1000_82542_RJC E1000_RJC
-#define E1000_82542_MGTPRC E1000_MGTPRC
-#define E1000_82542_MGTPDC E1000_MGTPDC
-#define E1000_82542_MGTPTC E1000_MGTPTC
-#define E1000_82542_TORL E1000_TORL
-#define E1000_82542_TORH E1000_TORH
-#define E1000_82542_TOTL E1000_TOTL
-#define E1000_82542_TOTH E1000_TOTH
-#define E1000_82542_TPR E1000_TPR
-#define E1000_82542_TPT E1000_TPT
-#define E1000_82542_PTC64 E1000_PTC64
-#define E1000_82542_PTC127 E1000_PTC127
-#define E1000_82542_PTC255 E1000_PTC255
-#define E1000_82542_PTC511 E1000_PTC511
-#define E1000_82542_PTC1023 E1000_PTC1023
-#define E1000_82542_PTC1522 E1000_PTC1522
-#define E1000_82542_MPTC E1000_MPTC
-#define E1000_82542_BPTC E1000_BPTC
-#define E1000_82542_TSCTC E1000_TSCTC
-#define E1000_82542_TSCTFC E1000_TSCTFC
-#define E1000_82542_RXCSUM E1000_RXCSUM
-#define E1000_82542_WUC E1000_WUC
-#define E1000_82542_WUFC E1000_WUFC
-#define E1000_82542_WUS E1000_WUS
-#define E1000_82542_MANC E1000_MANC
-#define E1000_82542_IPAV E1000_IPAV
-#define E1000_82542_IP4AT E1000_IP4AT
-#define E1000_82542_IP6AT E1000_IP6AT
-#define E1000_82542_WUPL E1000_WUPL
-#define E1000_82542_WUPM E1000_WUPM
-#define E1000_82542_FFLT E1000_FFLT
-#define E1000_82542_TDFH 0x08010
-#define E1000_82542_TDFT 0x08018
-#define E1000_82542_FFMT E1000_FFMT
-#define E1000_82542_FFVT E1000_FFVT
-#define E1000_82542_HOST_IF E1000_HOST_IF
-#define E1000_82542_IAM E1000_IAM
-#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
-#define E1000_82542_PSRCTL E1000_PSRCTL
-#define E1000_82542_RAID E1000_RAID
-#define E1000_82542_TARC0 E1000_TARC0
-#define E1000_82542_TDBAL1 E1000_TDBAL1
-#define E1000_82542_TDBAH1 E1000_TDBAH1
-#define E1000_82542_TDLEN1 E1000_TDLEN1
-#define E1000_82542_TDH1 E1000_TDH1
-#define E1000_82542_TDT1 E1000_TDT1
-#define E1000_82542_TXDCTL1 E1000_TXDCTL1
-#define E1000_82542_TARC1 E1000_TARC1
-#define E1000_82542_RFCTL E1000_RFCTL
-#define E1000_82542_GCR E1000_GCR
-#define E1000_82542_GSCL_1 E1000_GSCL_1
-#define E1000_82542_GSCL_2 E1000_GSCL_2
-#define E1000_82542_GSCL_3 E1000_GSCL_3
-#define E1000_82542_GSCL_4 E1000_GSCL_4
-#define E1000_82542_FACTPS E1000_FACTPS
-#define E1000_82542_SWSM E1000_SWSM
-#define E1000_82542_FWSM E1000_FWSM
-#define E1000_82542_FFLT_DBG E1000_FFLT_DBG
-#define E1000_82542_IAC E1000_IAC
-#define E1000_82542_ICRXPTC E1000_ICRXPTC
-#define E1000_82542_ICRXATC E1000_ICRXATC
-#define E1000_82542_ICTXPTC E1000_ICTXPTC
-#define E1000_82542_ICTXATC E1000_ICTXATC
-#define E1000_82542_ICTXQEC E1000_ICTXQEC
-#define E1000_82542_ICTXQMTC E1000_ICTXQMTC
-#define E1000_82542_ICRXDMTC E1000_ICRXDMTC
-#define E1000_82542_ICRXOC E1000_ICRXOC
-#define E1000_82542_HICR E1000_HICR
-
-/* Statistics counters collected by the MAC */
-struct em_hw_stats {
- uint64_t crcerrs;
- uint64_t algnerrc;
- uint64_t symerrs;
- uint64_t rxerrc;
- uint64_t mpc;
- uint64_t scc;
- uint64_t ecol;
- uint64_t mcc;
- uint64_t latecol;
- uint64_t colc;
- uint64_t dc;
- uint64_t tncrs;
- uint64_t sec;
- uint64_t cexterr;
- uint64_t rlec;
- uint64_t xonrxc;
- uint64_t xontxc;
- uint64_t xoffrxc;
- uint64_t xofftxc;
- uint64_t fcruc;
- uint64_t prc64;
- uint64_t prc127;
- uint64_t prc255;
- uint64_t prc511;
- uint64_t prc1023;
- uint64_t prc1522;
- uint64_t gprc;
- uint64_t bprc;
- uint64_t mprc;
- uint64_t gptc;
- uint64_t gorcl;
- uint64_t gorch;
- uint64_t gotcl;
- uint64_t gotch;
- uint64_t rnbc;
- uint64_t ruc;
- uint64_t rfc;
- uint64_t roc;
- uint64_t rjc;
- uint64_t mgprc;
- uint64_t mgpdc;
- uint64_t mgptc;
- uint64_t torl;
- uint64_t torh;
- uint64_t totl;
- uint64_t toth;
- uint64_t tpr;
- uint64_t tpt;
- uint64_t ptc64;
- uint64_t ptc127;
- uint64_t ptc255;
- uint64_t ptc511;
- uint64_t ptc1023;
- uint64_t ptc1522;
- uint64_t mptc;
- uint64_t bptc;
- uint64_t tsctc;
- uint64_t tsctfc;
- uint64_t iac;
- uint64_t icrxptc;
- uint64_t icrxatc;
- uint64_t ictxptc;
- uint64_t ictxatc;
- uint64_t ictxqec;
- uint64_t ictxqmtc;
- uint64_t icrxdmtc;
- uint64_t icrxoc;
-};
-
-/* Structure containing variables used by the shared code (em_hw.c) */
-struct em_hw {
- uint8_t *hw_addr;
- uint8_t *flash_address;
- em_mac_type mac_type;
- em_phy_type phy_type;
- uint32_t phy_init_script;
- em_media_type media_type;
- void *back;
- em_fc_type fc;
- em_bus_speed bus_speed;
- em_bus_width bus_width;
- em_bus_type bus_type;
- struct em_eeprom_info eeprom;
- em_ms_type master_slave;
- em_ms_type original_master_slave;
- em_ffe_config ffe_config_state;
- uint32_t asf_firmware_present;
- uint32_t eeprom_semaphore_present;
- unsigned long io_base;
- uint32_t phy_id;
- uint32_t phy_revision;
- uint32_t phy_addr;
- uint32_t original_fc;
- uint32_t txcw;
- uint32_t autoneg_failed;
- uint32_t max_frame_size;
- uint32_t min_frame_size;
- uint32_t mc_filter_type;
- uint32_t num_mc_addrs;
- uint32_t collision_delta;
- uint32_t tx_packet_delta;
- uint32_t ledctl_default;
- uint32_t ledctl_mode1;
- uint32_t ledctl_mode2;
- boolean_t tx_pkt_filtering;
- struct em_host_mng_dhcp_cookie mng_cookie;
- uint16_t phy_spd_default;
- uint16_t autoneg_advertised;
- uint16_t pci_cmd_word;
- uint16_t fc_high_water;
- uint16_t fc_low_water;
- uint16_t fc_pause_time;
- uint16_t current_ifs_val;
- uint16_t ifs_min_val;
- uint16_t ifs_max_val;
- uint16_t ifs_step_size;
- uint16_t ifs_ratio;
- uint16_t device_id;
- uint16_t vendor_id;
- uint16_t subsystem_id;
- uint16_t subsystem_vendor_id;
- uint8_t revision_id;
- uint8_t autoneg;
- uint8_t mdix;
- uint8_t forced_speed_duplex;
- uint8_t wait_autoneg_complete;
- uint8_t dma_fairness;
- uint8_t mac_addr[NODE_ADDRESS_SIZE];
- uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
- boolean_t disable_polarity_correction;
- boolean_t speed_downgraded;
- em_smart_speed smart_speed;
- em_dsp_config dsp_config_state;
- boolean_t get_link_status;
- boolean_t serdes_link_down;
- boolean_t tbi_compatibility_en;
- boolean_t tbi_compatibility_on;
- boolean_t phy_reset_disable;
- boolean_t fc_send_xon;
- boolean_t fc_strict_ieee;
- boolean_t report_tx_early;
- boolean_t adaptive_ifs;
- boolean_t ifs_params_forced;
- boolean_t in_ifs_mode;
- boolean_t mng_reg_access_disabled;
-};
-
-
-#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
-#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */
-#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */
-#define E1000_EEPROM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
-#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */
-#define E1000_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
-#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */
-#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */
-/* Register Bit Masks */
-/* Device Control */
-#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
-#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
-#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
-#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
-#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
-#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
-#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
-#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
-#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
-#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
-#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
-#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
-#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
-#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
-#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
-#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
-#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
-#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
-#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
-#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
-#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
-#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
-#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
-#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */
-#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
-#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
-#define E1000_CTRL_RST 0x04000000 /* Global reset */
-#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
-#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
-#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */
-#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
-#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
-
-/* Device Status */
-#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
-#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
-#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
-#define E1000_STATUS_FUNC_SHIFT 2
-#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */
-#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
-#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
-#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */
-#define E1000_STATUS_SPEED_MASK 0x000000C0
-#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
-#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
-#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
-#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
-#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */
-#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
-#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
-#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
-#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
-#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */
-#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */
-
-/* Constants used to intrepret the masked PCI-X bus speed. */
-#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
-#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */
-#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */
-
-/* EEPROM/Flash Control */
-#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */
-#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */
-#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */
-#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */
-#define E1000_EECD_FWE_MASK 0x00000030
-#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */
-#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */
-#define E1000_EECD_FWE_SHIFT 4
-#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */
-#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */
-#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */
-#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
-#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
- * (0-small, 1-large) */
-#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
-#ifndef E1000_EEPROM_GRANT_ATTEMPTS
-#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
-#endif
-#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */
-#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */
-#define E1000_EECD_SIZE_EX_SHIFT 11
-#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */
-#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
-#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
-#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
-#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
-#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
-#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
-#define E1000_STM_OPCODE 0xDB00
-#define E1000_HICR_FW_RESET 0xC0
-
-/* EEPROM Read */
-#define E1000_EERD_START 0x00000001 /* Start Read */
-#define E1000_EERD_DONE 0x00000010 /* Read Done */
-#define E1000_EERD_ADDR_SHIFT 8
-#define E1000_EERD_ADDR_MASK 0x0000FF00 /* Read Address */
-#define E1000_EERD_DATA_SHIFT 16
-#define E1000_EERD_DATA_MASK 0xFFFF0000 /* Read Data */
-
-/* SPI EEPROM Status Register */
-#define EEPROM_STATUS_RDY_SPI 0x01
-#define EEPROM_STATUS_WEN_SPI 0x02
-#define EEPROM_STATUS_BP0_SPI 0x04
-#define EEPROM_STATUS_BP1_SPI 0x08
-#define EEPROM_STATUS_WPEN_SPI 0x80
-
-/* Extended Device Control */
-#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */
-#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
-#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
-#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */
-#define E1000_CTRL_EXT_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */
-#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
-#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
-#define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA
-#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */
-#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
-#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
-#define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */
-#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */
-#define E1000_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7 0=in 1=out */
-#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */
-#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
-#define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */
-#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
-#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
-#define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000
-#define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000
-#define E1000_CTRL_EXT_WR_WMARK_256 0x00000000
-#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
-#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
-#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
-#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
-#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
-
-/* MDI Control */
-#define E1000_MDIC_DATA_MASK 0x0000FFFF
-#define E1000_MDIC_REG_MASK 0x001F0000
-#define E1000_MDIC_REG_SHIFT 16
-#define E1000_MDIC_PHY_MASK 0x03E00000
-#define E1000_MDIC_PHY_SHIFT 21
-#define E1000_MDIC_OP_WRITE 0x04000000
-#define E1000_MDIC_OP_READ 0x08000000
-#define E1000_MDIC_READY 0x10000000
-#define E1000_MDIC_INT_EN 0x20000000
-#define E1000_MDIC_ERROR 0x40000000
-
-/* LED Control */
-#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
-#define E1000_LEDCTL_LED0_MODE_SHIFT 0
-#define E1000_LEDCTL_LED0_BLINK_RATE 0x0000020
-#define E1000_LEDCTL_LED0_IVRT 0x00000040
-#define E1000_LEDCTL_LED0_BLINK 0x00000080
-#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00
-#define E1000_LEDCTL_LED1_MODE_SHIFT 8
-#define E1000_LEDCTL_LED1_BLINK_RATE 0x0002000
-#define E1000_LEDCTL_LED1_IVRT 0x00004000
-#define E1000_LEDCTL_LED1_BLINK 0x00008000
-#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000
-#define E1000_LEDCTL_LED2_MODE_SHIFT 16
-#define E1000_LEDCTL_LED2_BLINK_RATE 0x00200000
-#define E1000_LEDCTL_LED2_IVRT 0x00400000
-#define E1000_LEDCTL_LED2_BLINK 0x00800000
-#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
-#define E1000_LEDCTL_LED3_MODE_SHIFT 24
-#define E1000_LEDCTL_LED3_IVRT 0x40000000
-#define E1000_LEDCTL_LED3_BLINK 0x80000000
-
-#define E1000_LEDCTL_MODE_LINK_10_1000 0x0
-#define E1000_LEDCTL_MODE_LINK_100_1000 0x1
-#define E1000_LEDCTL_MODE_LINK_UP 0x2
-#define E1000_LEDCTL_MODE_ACTIVITY 0x3
-#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4
-#define E1000_LEDCTL_MODE_LINK_10 0x5
-#define E1000_LEDCTL_MODE_LINK_100 0x6
-#define E1000_LEDCTL_MODE_LINK_1000 0x7
-#define E1000_LEDCTL_MODE_PCIX_MODE 0x8
-#define E1000_LEDCTL_MODE_FULL_DUPLEX 0x9
-#define E1000_LEDCTL_MODE_COLLISION 0xA
-#define E1000_LEDCTL_MODE_BUS_SPEED 0xB
-#define E1000_LEDCTL_MODE_BUS_SIZE 0xC
-#define E1000_LEDCTL_MODE_PAUSED 0xD
-#define E1000_LEDCTL_MODE_LED_ON 0xE
-#define E1000_LEDCTL_MODE_LED_OFF 0xF
-
-/* Receive Address */
-#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
-
-/* Interrupt Cause Read */
-#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
-#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
-#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
-#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
-#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
-#define E1000_ICR_RXO 0x00000040 /* rx overrun */
-#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
-#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
-#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
-#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
-#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
-#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
-#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
-#define E1000_ICR_TXD_LOW 0x00008000
-#define E1000_ICR_SRPD 0x00010000
-#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
-#define E1000_ICR_MNG 0x00040000 /* Manageability event */
-#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
-#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */
-
-/* Interrupt Cause Set */
-#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
-#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
-#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
-#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
-#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
-#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
-#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
-#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
-#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_ICS_SRPD E1000_ICR_SRPD
-#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */
-#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */
-#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */
-
-/* Interrupt Mask Set */
-#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
-#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
-#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
-#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
-#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
-#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
-#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
-#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
-#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMS_SRPD E1000_ICR_SRPD
-#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */
-#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */
-#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */
-
-/* Interrupt Mask Clear */
-#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
-#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
-#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
-#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
-#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
-#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
-#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
-#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
-#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMC_SRPD E1000_ICR_SRPD
-#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */
-#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */
-#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */
-
-/* Receive Control */
-#define E1000_RCTL_RST 0x00000001 /* Software reset */
-#define E1000_RCTL_EN 0x00000002 /* enable */
-#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
-#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
-#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
-#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
-#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
-#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
-#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
-#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
-#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */
-#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
-#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
-#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
-#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
-#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
-#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */
-#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
-#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */
-#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
-#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
-#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
-#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
-#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
-#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
-#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
-#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
-#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
-#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
-#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
-#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
-#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
-#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
-#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */
-#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */
-
-/* Use byte values for the following shift parameters
- * Usage:
- * psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
- * E1000_PSRCTL_BSIZE0_MASK) |
- * ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
- * E1000_PSRCTL_BSIZE1_MASK) |
- * ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
- * E1000_PSRCTL_BSIZE2_MASK) |
- * ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
- * E1000_PSRCTL_BSIZE3_MASK))
- * where value0 = [128..16256], default=256
- * value1 = [1024..64512], default=4096
- * value2 = [0..64512], default=4096
- * value3 = [0..64512], default=0
- */
-
-#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F
-#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00
-#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000
-#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000
-
-#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */
-#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */
-#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */
-#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */
-
-/* Receive Descriptor */
-#define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */
-#define E1000_RDT_FPDB 0x80000000 /* Flush descriptor block */
-#define E1000_RDLEN_LEN 0x0007ff80 /* descriptor length */
-#define E1000_RDH_RDH 0x0000ffff /* receive descriptor head */
-#define E1000_RDT_RDT 0x0000ffff /* receive descriptor tail */
-
-/* Flow Control */
-#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */
-#define E1000_FCRTH_XFCE 0x80000000 /* External Flow Control Enable */
-#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
-#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
-
-/* Header split receive */
-#define E1000_RFCTL_ISCSI_DIS 0x00000001
-#define E1000_RFCTL_ISCSI_DWC_MASK 0x0000003E
-#define E1000_RFCTL_ISCSI_DWC_SHIFT 1
-#define E1000_RFCTL_NFSW_DIS 0x00000040
-#define E1000_RFCTL_NFSR_DIS 0x00000080
-#define E1000_RFCTL_NFS_VER_MASK 0x00000300
-#define E1000_RFCTL_NFS_VER_SHIFT 8
-#define E1000_RFCTL_IPV6_DIS 0x00000400
-#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800
-#define E1000_RFCTL_ACK_DIS 0x00001000
-#define E1000_RFCTL_ACKD_DIS 0x00002000
-#define E1000_RFCTL_IPFRSP_DIS 0x00004000
-#define E1000_RFCTL_EXTEN 0x00008000
-#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
-#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
-
-/* Receive Descriptor Control */
-#define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */
-#define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */
-#define E1000_RXDCTL_WTHRESH 0x003F0000 /* RXDCTL Writeback Threshold */
-#define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */
-
-/* Transmit Descriptor Control */
-#define E1000_TXDCTL_PTHRESH 0x000000FF /* TXDCTL Prefetch Threshold */
-#define E1000_TXDCTL_HTHRESH 0x0000FF00 /* TXDCTL Host Threshold */
-#define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */
-#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
-#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
-#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
-#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc.
- still to be processed. */
-
-/* Transmit Configuration Word */
-#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
-#define E1000_TXCW_HD 0x00000040 /* TXCW half duplex */
-#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */
-#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */
-#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */
-#define E1000_TXCW_RF 0x00003000 /* TXCW remote fault */
-#define E1000_TXCW_NP 0x00008000 /* TXCW next page */
-#define E1000_TXCW_CW 0x0000ffff /* TxConfigWord mask */
-#define E1000_TXCW_TXC 0x40000000 /* Transmit Config control */
-#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
-
-/* Receive Configuration Word */
-#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */
-#define E1000_RXCW_NC 0x04000000 /* Receive config no carrier */
-#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */
-#define E1000_RXCW_CC 0x10000000 /* Receive config change */
-#define E1000_RXCW_C 0x20000000 /* Receive config */
-#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */
-#define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */
-
-/* Transmit Control */
-#define E1000_TCTL_RST 0x00000001 /* software reset */
-#define E1000_TCTL_EN 0x00000002 /* enable tx */
-#define E1000_TCTL_BCE 0x00000004 /* busy check enable */
-#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
-#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
-#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
-#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
-#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */
-#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
-#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
-#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
-
-/* Receive Checksum Control */
-#define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */
-#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */
-#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
-#define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */
-#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
-#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
-
-
-/* Definitions for power management and wakeup registers */
-/* Wake Up Control */
-#define E1000_WUC_APME 0x00000001 /* APM Enable */
-#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
-#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
-#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
-#define E1000_WUC_SPM 0x80000000 /* Enable SPM */
-
-/* Wake Up Filter Control */
-#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
-#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
-#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
-#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
-#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
-#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
-#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
-#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
-#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
-#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
-#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
-#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
-#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
-#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
-#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
-#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
-
-/* Wake Up Status */
-#define E1000_WUS_LNKC 0x00000001 /* Link Status Changed */
-#define E1000_WUS_MAG 0x00000002 /* Magic Packet Received */
-#define E1000_WUS_EX 0x00000004 /* Directed Exact Received */
-#define E1000_WUS_MC 0x00000008 /* Directed Multicast Received */
-#define E1000_WUS_BC 0x00000010 /* Broadcast Received */
-#define E1000_WUS_ARP 0x00000020 /* ARP Request Packet Received */
-#define E1000_WUS_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Received */
-#define E1000_WUS_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Received */
-#define E1000_WUS_FLX0 0x00010000 /* Flexible Filter 0 Match */
-#define E1000_WUS_FLX1 0x00020000 /* Flexible Filter 1 Match */
-#define E1000_WUS_FLX2 0x00040000 /* Flexible Filter 2 Match */
-#define E1000_WUS_FLX3 0x00080000 /* Flexible Filter 3 Match */
-#define E1000_WUS_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
-
-/* Management Control */
-#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
-#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
-#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */
-#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */
-#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */
-#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */
-#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */
-#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */
-#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
-#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery
- * Filtering */
-#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */
-#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */
-#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
-#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
-#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
-#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address
- * filtering */
-#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host
- * memory */
-#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address
- * filtering */
-#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */
-#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */
-#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
-#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
-#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
-#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */
-#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */
-#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */
-
-#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
-#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
-
-/* SW Semaphore Register */
-#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
-#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
-#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */
-#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
-
-/* FW Semaphore Register */
-#define E1000_FWSM_MODE_MASK 0x0000000E /* FW mode */
-#define E1000_FWSM_MODE_SHIFT 1
-#define E1000_FWSM_FW_VALID 0x00008000 /* FW established a valid mode */
-
-/* FFLT Debug Register */
-#define E1000_FFLT_DBG_INVC 0x00100000 /* Invalid /C/ code handling */
-
-typedef enum {
- em_mng_mode_none = 0,
- em_mng_mode_asf,
- em_mng_mode_pt,
- em_mng_mode_ipmi,
- em_mng_mode_host_interface_only
-} em_mng_mode;
-
-/* Host Inteface Control Register */
-#define E1000_HICR_EN 0x00000001 /* Enable Bit - RO */
-#define E1000_HICR_C 0x00000002 /* Driver sets this bit when done
- * to put command in RAM */
-#define E1000_HICR_SV 0x00000004 /* Status Validity */
-#define E1000_HICR_FWR 0x00000080 /* FW reset. Set by the Host */
-
-/* Host Interface Command Interface - Address range 0x8800-0x8EFF */
-#define E1000_HI_MAX_DATA_LENGTH 252 /* Host Interface data length */
-#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Number of bytes in range */
-#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Number of dwords in range */
-#define E1000_HI_COMMAND_TIMEOUT 500 /* Time in ms to process HI command */
-
-struct em_host_command_header {
- uint8_t command_id;
- uint8_t command_length;
- uint8_t command_options; /* I/F bits for command, status for return */
- uint8_t checksum;
-};
-struct em_host_command_info {
- struct em_host_command_header command_header; /* Command Head/Command Result Head has 4 bytes */
- uint8_t command_data[E1000_HI_MAX_DATA_LENGTH]; /* Command data can length 0..252 */
-};
-
-/* Host SMB register #0 */
-#define E1000_HSMC0R_CLKIN 0x00000001 /* SMB Clock in */
-#define E1000_HSMC0R_DATAIN 0x00000002 /* SMB Data in */
-#define E1000_HSMC0R_DATAOUT 0x00000004 /* SMB Data out */
-#define E1000_HSMC0R_CLKOUT 0x00000008 /* SMB Clock out */
-
-/* Host SMB register #1 */
-#define E1000_HSMC1R_CLKIN E1000_HSMC0R_CLKIN
-#define E1000_HSMC1R_DATAIN E1000_HSMC0R_DATAIN
-#define E1000_HSMC1R_DATAOUT E1000_HSMC0R_DATAOUT
-#define E1000_HSMC1R_CLKOUT E1000_HSMC0R_CLKOUT
-
-/* FW Status Register */
-#define E1000_FWSTS_FWS_MASK 0x000000FF /* FW Status */
-
-/* Wake Up Packet Length */
-#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */
-
-#define E1000_MDALIGN 4096
-
-#define E1000_GCR_BEM32 0x00400000
-/* Function Active and Power State to MNG */
-#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003
-#define E1000_FACTPS_LAN0_VALID 0x00000004
-#define E1000_FACTPS_FUNC0_AUX_EN 0x00000008
-#define E1000_FACTPS_FUNC1_POWER_STATE_MASK 0x000000C0
-#define E1000_FACTPS_FUNC1_POWER_STATE_SHIFT 6
-#define E1000_FACTPS_LAN1_VALID 0x00000100
-#define E1000_FACTPS_FUNC1_AUX_EN 0x00000200
-#define E1000_FACTPS_FUNC2_POWER_STATE_MASK 0x00003000
-#define E1000_FACTPS_FUNC2_POWER_STATE_SHIFT 12
-#define E1000_FACTPS_IDE_ENABLE 0x00004000
-#define E1000_FACTPS_FUNC2_AUX_EN 0x00008000
-#define E1000_FACTPS_FUNC3_POWER_STATE_MASK 0x000C0000
-#define E1000_FACTPS_FUNC3_POWER_STATE_SHIFT 18
-#define E1000_FACTPS_SP_ENABLE 0x00100000
-#define E1000_FACTPS_FUNC3_AUX_EN 0x00200000
-#define E1000_FACTPS_FUNC4_POWER_STATE_MASK 0x03000000
-#define E1000_FACTPS_FUNC4_POWER_STATE_SHIFT 24
-#define E1000_FACTPS_IPMI_ENABLE 0x04000000
-#define E1000_FACTPS_FUNC4_AUX_EN 0x08000000
-#define E1000_FACTPS_MNGCG 0x20000000
-#define E1000_FACTPS_LAN_FUNC_SEL 0x40000000
-#define E1000_FACTPS_PM_STATE_CHANGED 0x80000000
-
-/* EEPROM Commands - Microwire */
-#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
-#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
-#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */
-#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */
-#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */
-
-/* EEPROM Commands - SPI */
-#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
-#define EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */
-#define EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */
-#define EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */
-#define EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Enable latch */
-#define EEPROM_WRDI_OPCODE_SPI 0x04 /* EEPROM reset Write Enable latch */
-#define EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status register */
-#define EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status register */
-#define EEPROM_ERASE4K_OPCODE_SPI 0x20 /* EEPROM ERASE 4KB */
-#define EEPROM_ERASE64K_OPCODE_SPI 0xD8 /* EEPROM ERASE 64KB */
-#define EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */
-
-/* EEPROM Size definitions */
-#define EEPROM_WORD_SIZE_SHIFT 6
-#define EEPROM_SIZE_SHIFT 10
-#define EEPROM_SIZE_MASK 0x1C00
-
-/* EEPROM Word Offsets */
-#define EEPROM_COMPAT 0x0003
-#define EEPROM_ID_LED_SETTINGS 0x0004
-#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
-#define EEPROM_PHY_CLASS_WORD 0x0007
-#define EEPROM_INIT_CONTROL1_REG 0x000A
-#define EEPROM_INIT_CONTROL2_REG 0x000F
-#define EEPROM_INIT_CONTROL3_PORT_B 0x0014
-#define EEPROM_INIT_CONTROL3_PORT_A 0x0024
-#define EEPROM_CFG 0x0012
-#define EEPROM_FLASH_VERSION 0x0032
-#define EEPROM_CHECKSUM_REG 0x003F
-
-/* Word definitions for ID LED Settings */
-#define ID_LED_RESERVED_0000 0x0000
-#define ID_LED_RESERVED_FFFF 0xFFFF
-#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \
- (ID_LED_OFF1_OFF2 << 8) | \
- (ID_LED_DEF1_DEF2 << 4) | \
- (ID_LED_DEF1_DEF2))
-#define ID_LED_DEF1_DEF2 0x1
-#define ID_LED_DEF1_ON2 0x2
-#define ID_LED_DEF1_OFF2 0x3
-#define ID_LED_ON1_DEF2 0x4
-#define ID_LED_ON1_ON2 0x5
-#define ID_LED_ON1_OFF2 0x6
-#define ID_LED_OFF1_DEF2 0x7
-#define ID_LED_OFF1_ON2 0x8
-#define ID_LED_OFF1_OFF2 0x9
-
-#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
-#define IGP_ACTIVITY_LED_ENABLE 0x0300
-#define IGP_LED3_MODE 0x07000000
-
-
-/* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */
-#define EEPROM_SERDES_AMPLITUDE_MASK 0x000F
-
-/* Mask bit for PHY class in Word 7 of the EEPROM */
-#define EEPROM_PHY_CLASS_A 0x8000
-
-/* Mask bits for fields in Word 0x0a of the EEPROM */
-#define EEPROM_WORD0A_ILOS 0x0010
-#define EEPROM_WORD0A_SWDPIO 0x01E0
-#define EEPROM_WORD0A_LRST 0x0200
-#define EEPROM_WORD0A_FD 0x0400
-#define EEPROM_WORD0A_66MHZ 0x0800
-
-/* Mask bits for fields in Word 0x0f of the EEPROM */
-#define EEPROM_WORD0F_PAUSE_MASK 0x3000
-#define EEPROM_WORD0F_PAUSE 0x1000
-#define EEPROM_WORD0F_ASM_DIR 0x2000
-#define EEPROM_WORD0F_ANE 0x0800
-#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
-
-/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
-#define EEPROM_SUM 0xBABA
-
-/* EEPROM Map defines (WORD OFFSETS)*/
-#define EEPROM_NODE_ADDRESS_BYTE_0 0
-#define EEPROM_PBA_BYTE_1 8
-
-#define EEPROM_RESERVED_WORD 0xFFFF
-
-/* EEPROM Map Sizes (Byte Counts) */
-#define PBA_SIZE 4
-
-/* Collision related configuration parameters */
-#define E1000_COLLISION_THRESHOLD 15
-#define E1000_CT_SHIFT 4
-#define E1000_COLLISION_DISTANCE 64
-#define E1000_FDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
-#define E1000_HDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
-#define E1000_COLD_SHIFT 12
-
-/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
-#define REQ_TX_DESCRIPTOR_MULTIPLE 8
-#define REQ_RX_DESCRIPTOR_MULTIPLE 8
-
-/* Default values for the transmit IPG register */
-#define DEFAULT_82542_TIPG_IPGT 10
-#define DEFAULT_82543_TIPG_IPGT_FIBER 9
-#define DEFAULT_82543_TIPG_IPGT_COPPER 8
-
-#define E1000_TIPG_IPGT_MASK 0x000003FF
-#define E1000_TIPG_IPGR1_MASK 0x000FFC00
-#define E1000_TIPG_IPGR2_MASK 0x3FF00000
-
-#define DEFAULT_82542_TIPG_IPGR1 2
-#define DEFAULT_82543_TIPG_IPGR1 8
-#define E1000_TIPG_IPGR1_SHIFT 10
-
-#define DEFAULT_82542_TIPG_IPGR2 10
-#define DEFAULT_82543_TIPG_IPGR2 6
-#define E1000_TIPG_IPGR2_SHIFT 20
-
-#define E1000_TXDMAC_DPP 0x00000001
-
-/* Adaptive IFS defines */
-#define TX_THRESHOLD_START 8
-#define TX_THRESHOLD_INCREMENT 10
-#define TX_THRESHOLD_DECREMENT 1
-#define TX_THRESHOLD_STOP 190
-#define TX_THRESHOLD_DISABLE 0
-#define TX_THRESHOLD_TIMER_MS 10000
-#define MIN_NUM_XMITS 1000
-#define IFS_MAX 80
-#define IFS_STEP 10
-#define IFS_MIN 40
-#define IFS_RATIO 4
-
-/* Extended Configuration Control and Size */
-#define E1000_EXTCNF_CTRL_PCIE_WRITE_ENABLE 0x00000001
-#define E1000_EXTCNF_CTRL_PHY_WRITE_ENABLE 0x00000002
-#define E1000_EXTCNF_CTRL_D_UD_ENABLE 0x00000004
-#define E1000_EXTCNF_CTRL_D_UD_LATENCY 0x00000008
-#define E1000_EXTCNF_CTRL_D_UD_OWNER 0x00000010
-#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
-#define E1000_EXTCNF_CTRL_MDIO_HW_OWNERSHIP 0x00000040
-#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER 0x1FFF0000
-
-#define E1000_EXTCNF_SIZE_EXT_PHY_LENGTH 0x000000FF
-#define E1000_EXTCNF_SIZE_EXT_DOCK_LENGTH 0x0000FF00
-#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH 0x00FF0000
-
-/* PBA constants */
-#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */
-#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
-#define E1000_PBA_22K 0x0016
-#define E1000_PBA_24K 0x0018
-#define E1000_PBA_30K 0x001E
-#define E1000_PBA_40K 0x0028
-#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
-
-/* Flow Control Constants */
-#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
-#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
-#define FLOW_CONTROL_TYPE 0x8808
-
-/* The historical defaults for the flow control values are given below. */
-#define FC_DEFAULT_HI_THRESH (0x8000) /* 32KB */
-#define FC_DEFAULT_LO_THRESH (0x4000) /* 16KB */
-#define FC_DEFAULT_TX_TIMER (0x100) /* ~130 us */
-
-/* PCIX Config space */
-#define PCIX_COMMAND_REGISTER 0xE6
-#define PCIX_STATUS_REGISTER_LO 0xE8
-#define PCIX_STATUS_REGISTER_HI 0xEA
-
-#define PCIX_COMMAND_MMRBC_MASK 0x000C
-#define PCIX_COMMAND_MMRBC_SHIFT 0x2
-#define PCIX_STATUS_HI_MMRBC_MASK 0x0060
-#define PCIX_STATUS_HI_MMRBC_SHIFT 0x5
-#define PCIX_STATUS_HI_MMRBC_4K 0x3
-#define PCIX_STATUS_HI_MMRBC_2K 0x2
-
-
-/* Number of bits required to shift right the "pause" bits from the
- * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register.
- */
-#define PAUSE_SHIFT 5
-
-/* Number of bits required to shift left the "SWDPIO" bits from the
- * EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field in the CTRL register.
- */
-#define SWDPIO_SHIFT 17
-
-/* Number of bits required to shift left the "SWDPIO_EXT" bits from the
- * EEPROM word F (bits 7:4) to the bits 11:8 of The Extended CTRL register.
- */
-#define SWDPIO__EXT_SHIFT 4
-
-/* Number of bits required to shift left the "ILOS" bit from the EEPROM
- * (bit 4) to the "ILOS" (bit 7) field in the CTRL register.
- */
-#define ILOS_SHIFT 3
-
-
-#define RECEIVE_BUFFER_ALIGN_SIZE (256)
-
-/* Number of milliseconds we wait for auto-negotiation to complete */
-#define LINK_UP_TIMEOUT 500
-
-/* Number of 100 microseconds we wait for PCI Express master disable */
-#define MASTER_DISABLE_TIMEOUT 800
-/* Number of milliseconds we wait for Eeprom auto read bit done after MAC reset */
-#define AUTO_READ_DONE_TIMEOUT 10
-/* Number of milliseconds we wait for PHY configuration done after MAC reset */
-#define PHY_CFG_TIMEOUT 40
-
-#define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
-
-/* The carrier extension symbol, as received by the NIC. */
-#define CARRIER_EXTENSION 0x0F
-
-/* TBI_ACCEPT macro definition:
- *
- * This macro requires:
- * adapter = a pointer to struct em_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;
- * em_tbi_adjust_stats(adapter, MacAddress);
- * frame_length--;
- * } else {
- * accept_frame = FALSE;
- * }
- * ...
- */
-
-#define TBI_ACCEPT(adapter, status, errors, length, last_byte) \
- ((adapter)->tbi_compatibility_on && \
- (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
- ((last_byte) == CARRIER_EXTENSION) && \
- (((status) & E1000_RXD_STAT_VP) ? \
- (((length) > ((adapter)->min_frame_size - VLAN_TAG_SIZE)) && \
- ((length) <= ((adapter)->max_frame_size + 1))) : \
- (((length) > (adapter)->min_frame_size) && \
- ((length) <= ((adapter)->max_frame_size + VLAN_TAG_SIZE + 1)))))
-
-
-/* Structures, enums, and macros for the PHY */
-
-/* Bit definitions for the Management Data IO (MDIO) and Management Data
- * Clock (MDC) pins in the Device Control Register.
- */
-#define E1000_CTRL_PHY_RESET_DIR E1000_CTRL_SWDPIO0
-#define E1000_CTRL_PHY_RESET E1000_CTRL_SWDPIN0
-#define E1000_CTRL_MDIO_DIR E1000_CTRL_SWDPIO2
-#define E1000_CTRL_MDIO E1000_CTRL_SWDPIN2
-#define E1000_CTRL_MDC_DIR E1000_CTRL_SWDPIO3
-#define E1000_CTRL_MDC E1000_CTRL_SWDPIN3
-#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR
-#define E1000_CTRL_PHY_RESET4 E1000_CTRL_EXT_SDP4_DATA
-
-/* PHY 1000 MII Register/Bit Definitions */
-/* PHY Registers defined by IEEE */
-#define PHY_CTRL 0x00 /* Control Register */
-#define PHY_STATUS 0x01 /* Status Regiser */
-#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
-#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
-#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
-#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
-#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */
-#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
-#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
-#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */
-#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
-#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
-
-/* M88E1000 Specific Registers */
-#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
-#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
-#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Register */
-#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Register */
-#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
-#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
-
-#define M88E1000_PHY_EXT_CTRL 0x1A /* PHY extend control register */
-#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */
-#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */
-#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */
-#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */
-
-#define IGP01E1000_IEEE_REGS_PAGE 0x0000
-#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
-#define IGP01E1000_IEEE_FORCE_GIGA 0x0140
-
-/* IGP01E1000 Specific Registers */
-#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */
-#define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */
-#define IGP01E1000_PHY_PORT_CTRL 0x12 /* PHY Specific Control Register */
-#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */
-#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */
-#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */
-#define IGP02E1000_PHY_POWER_MGMT 0x19
-#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */
-
-/* IGP01E1000 AGC Registers - stores the cable length values*/
-#define IGP01E1000_PHY_AGC_A 0x1172
-#define IGP01E1000_PHY_AGC_B 0x1272
-#define IGP01E1000_PHY_AGC_C 0x1472
-#define IGP01E1000_PHY_AGC_D 0x1872
-
-/* IGP02E1000 AGC Registers for cable length values */
-#define IGP02E1000_PHY_AGC_A 0x11B1
-#define IGP02E1000_PHY_AGC_B 0x12B1
-#define IGP02E1000_PHY_AGC_C 0x14B1
-#define IGP02E1000_PHY_AGC_D 0x18B1
-
-/* IGP01E1000 DSP Reset Register */
-#define IGP01E1000_PHY_DSP_RESET 0x1F33
-#define IGP01E1000_PHY_DSP_SET 0x1F71
-#define IGP01E1000_PHY_DSP_FFE 0x1F35
-
-#define IGP01E1000_PHY_CHANNEL_NUM 4
-#define IGP02E1000_PHY_CHANNEL_NUM 4
-
-#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_ANALOG_TX_STATE 0x2890
-#define IGP01E1000_PHY_ANALOG_CLASS_A 0x2000
-#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE 0x0004
-#define IGP01E1000_PHY_DSP_FFE_CM_CP 0x0069
-
-#define IGP01E1000_PHY_DSP_FFE_DEFAULT 0x002A
-/* IGP01E1000 PCS Initialization register - stores the polarity status when
- * speed = 1000 Mbps. */
-#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
-#define IGP01E1000_PHY_PCS_CTRL_REG 0x00B5
-
-#define IGP01E1000_ANALOG_REGS_PAGE 0x20C0
-
-#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
-#define MAX_PHY_MULTI_PAGE_REG 0xF /*Registers that are equal on all pages*/
-/* PHY Control Register */
-#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
-#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
-#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
-#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
-#define MII_CR_POWER_DOWN 0x0800 /* Power down */
-#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
-#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
-#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
-
-/* PHY Status Register */
-#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
-#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
-#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
-#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
-#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
-#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
-#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
-#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
-#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
-#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
-#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
-#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
-#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
-#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
-#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
-
-/* Autoneg Advertisement Register */
-#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */
-#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
-#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
-#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
-#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
-#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */
-#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */
-#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */
-#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */
-#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */
-
-/* Link Partner Ability Register (Base Page) */
-#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */
-#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP is 10T Half Duplex Capable */
-#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP is 10T Full Duplex Capable */
-#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP is 100TX Half Duplex Capable */
-#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP is 100TX Full Duplex Capable */
-#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */
-#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */
-#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */
-#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP has detected Remote Fault */
-#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP has rx'd link code word */
-#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */
-
-/* Autoneg Expansion Register */
-#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */
-#define NWAY_ER_PAGE_RXD 0x0002 /* LP is 10T Half Duplex Capable */
-#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP is 10T Full Duplex Capable */
-#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */
-#define NWAY_ER_PAR_DETECT_FAULT 0x0010 /* LP is 100TX Full Duplex Capable */
-
-/* Next Page TX Register */
-#define NPTX_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
-#define NPTX_TOGGLE 0x0800 /* Toggles between exchanges
- * of different NP
- */
-#define NPTX_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg
- * 0 = cannot comply with msg
- */
-#define NPTX_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */
-#define NPTX_NEXT_PAGE 0x8000 /* 1 = addition NP will follow
- * 0 = sending last NP
- */
-
-/* Link Partner Next Page Register */
-#define LP_RNPR_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
-#define LP_RNPR_TOGGLE 0x0800 /* Toggles between exchanges
- * of different NP
- */
-#define LP_RNPR_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg
- * 0 = cannot comply with msg
- */
-#define LP_RNPR_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */
-#define LP_RNPR_ACKNOWLDGE 0x4000 /* 1 = ACK / 0 = NO ACK */
-#define LP_RNPR_NEXT_PAGE 0x8000 /* 1 = addition NP will follow
- * 0 = sending last NP
- */
-
-/* 1000BASE-T Control Register */
-#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */
-#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
-#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
-#define CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */
- /* 0=DTE device */
-#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */
- /* 0=Configure PHY as Slave */
-#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
- /* 0=Automatic Master/Slave config */
-#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
-#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
-#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
-#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
-#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
-
-/* 1000BASE-T Status Register */
-#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */
-#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */
-#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
-#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
-#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
-#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
-#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */
-#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */
-#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
-#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13
-#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5
-#define FFE_IDLE_ERR_COUNT_TIMEOUT_20 20
-#define FFE_IDLE_ERR_COUNT_TIMEOUT_100 100
-
-/* Extended Status Register */
-#define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
-#define IEEE_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */
-#define IEEE_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */
-#define IEEE_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */
-
-#define PHY_TX_POLARITY_MASK 0x0100 /* register 10h bit 8 (polarity bit) */
-#define PHY_TX_NORMAL_POLARITY 0 /* register 10h bit 8 (normal polarity) */
-
-#define AUTO_POLARITY_DISABLE 0x0010 /* register 11h bit 4 */
- /* (0=enable, 1=disable) */
-
-/* M88E1000 PHY Specific Control Register */
-#define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */
-#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
-#define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
-#define M88E1000_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low,
- * 0=CLK125 toggling
- */
-#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
- /* Manual MDI configuration */
-#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
-#define M88E1000_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover,
- * 100BASE-TX/10BASE-T:
- * MDI Mode
- */
-#define M88E1000_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled
- * all speeds.
- */
-#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
- /* 1=Enable Extended 10BASE-T distance
- * (Lower 10BASE-T RX Threshold)
- * 0=Normal 10BASE-T RX Threshold */
-#define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100
- /* 1=5-Bit interface in 100BASE-TX
- * 0=MII interface in 100BASE-TX */
-#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */
-#define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */
-#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
-
-#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT 1
-#define M88E1000_PSCR_AUTO_X_MODE_SHIFT 5
-#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
-
-/* M88E1000 PHY Specific Status Register */
-#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */
-#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
-#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */
-#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
-#define M88E1000_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M;
- * 3=110-140M;4=>140M */
-#define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */
-#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
-#define M88E1000_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */
-#define M88E1000_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
-#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
-#define M88E1000_PSSR_10MBS 0x0000 /* 00=10Mbs */
-#define M88E1000_PSSR_100MBS 0x4000 /* 01=100Mbs */
-#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
-
-#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
-#define M88E1000_PSSR_DOWNSHIFT_SHIFT 5
-#define M88E1000_PSSR_MDIX_SHIFT 6
-#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
-
-/* M88E1000 Extended PHY Specific Control Register */
-#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */
-#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 /* 1=Lost lock detect enabled.
- * Will assert lost lock and bring
- * link down if idle not seen
- * within 1ms in 1000BASE-T
- */
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the master */
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X 0x0400
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X 0x0800
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X 0x0C00
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the slave */
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS 0x0000
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X 0x0200
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X 0x0300
-#define M88E1000_EPSCR_TX_CLK_2_5 0x0060 /* 2.5 MHz TX_CLK */
-#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
-#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
-
-/* IGP01E1000 Specific Port Config Register - R/W */
-#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT 0x0010
-#define IGP01E1000_PSCFR_PRE_EN 0x0020
-#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
-#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK 0x0100
-#define IGP01E1000_PSCFR_DISABLE_JABBER 0x0400
-#define IGP01E1000_PSCFR_DISABLE_TRANSMIT 0x2000
-
-/* IGP01E1000 Specific Port Status Register - R/O */
-#define IGP01E1000_PSSR_AUTONEG_FAILED 0x0001 /* RO LH SC */
-#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
-#define IGP01E1000_PSSR_CABLE_LENGTH 0x007C
-#define IGP01E1000_PSSR_FULL_DUPLEX 0x0200
-#define IGP01E1000_PSSR_LINK_UP 0x0400
-#define IGP01E1000_PSSR_MDIX 0x0800
-#define IGP01E1000_PSSR_SPEED_MASK 0xC000 /* speed bits mask */
-#define IGP01E1000_PSSR_SPEED_10MBPS 0x4000
-#define IGP01E1000_PSSR_SPEED_100MBPS 0x8000
-#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
-#define IGP01E1000_PSSR_CABLE_LENGTH_SHIFT 0x0002 /* shift right 2 */
-#define IGP01E1000_PSSR_MDIX_SHIFT 0x000B /* shift right 11 */
-
-/* IGP01E1000 Specific Port Control Register - R/W */
-#define IGP01E1000_PSCR_TP_LOOPBACK 0x0010
-#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR 0x0200
-#define IGP01E1000_PSCR_TEN_CRS_SELECT 0x0400
-#define IGP01E1000_PSCR_FLIP_CHIP 0x0800
-#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
-#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0-MDI, 1-MDIX */
-
-/* IGP01E1000 Specific Port Link Health Register */
-#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
-#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR 0x4000
-#define IGP01E1000_PLHR_MASTER_FAULT 0x2000
-#define IGP01E1000_PLHR_MASTER_RESOLUTION 0x1000
-#define IGP01E1000_PLHR_GIG_REM_RCVR_NOK 0x0800 /* LH */
-#define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW 0x0400 /* LH */
-#define IGP01E1000_PLHR_DATA_ERR_1 0x0200 /* LH */
-#define IGP01E1000_PLHR_DATA_ERR_0 0x0100
-#define IGP01E1000_PLHR_AUTONEG_FAULT 0x0040
-#define IGP01E1000_PLHR_AUTONEG_ACTIVE 0x0010
-#define IGP01E1000_PLHR_VALID_CHANNEL_D 0x0008
-#define IGP01E1000_PLHR_VALID_CHANNEL_C 0x0004
-#define IGP01E1000_PLHR_VALID_CHANNEL_B 0x0002
-#define IGP01E1000_PLHR_VALID_CHANNEL_A 0x0001
-
-/* IGP01E1000 Channel Quality Register */
-#define IGP01E1000_MSE_CHANNEL_D 0x000F
-#define IGP01E1000_MSE_CHANNEL_C 0x00F0
-#define IGP01E1000_MSE_CHANNEL_B 0x0F00
-#define IGP01E1000_MSE_CHANNEL_A 0xF000
-
-#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
-#define IGP02E1000_PM_D3_LPLU 0x0004 /* Enable LPLU in non-D0a modes */
-#define IGP02E1000_PM_D0_LPLU 0x0002 /* Enable LPLU in D0a mode */
-
-/* IGP01E1000 DSP reset macros */
-#define DSP_RESET_ENABLE 0x0
-#define DSP_RESET_DISABLE 0x2
-#define E1000_MAX_DSP_RESETS 10
-
-/* IGP01E1000 & IGP02E1000 AGC Registers */
-
-#define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */
-#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Coarse - 15:13, Fine - 12:9 */
-
-/* IGP02E1000 AGC Register Length 9-bit mask */
-#define IGP02E1000_AGC_LENGTH_MASK 0x7F
-
-/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
-#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
-#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128
-
-/* The precision error of the cable length is +/- 10 meters */
-#define IGP01E1000_AGC_RANGE 10
-#define IGP02E1000_AGC_RANGE 10
-
-/* IGP01E1000 PCS Initialization register */
-/* bits 3:6 in the PCS registers stores the channels polarity */
-#define IGP01E1000_PHY_POLARITY_MASK 0x0078
-
-/* IGP01E1000 GMII FIFO Register */
-#define IGP01E1000_GMII_FLEX_SPD 0x10 /* Enable flexible speed
- * on Link-Up */
-#define IGP01E1000_GMII_SPD 0x20 /* Enable SPD */
-
-/* IGP01E1000 Analog Register */
-#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x20D1
-#define IGP01E1000_ANALOG_FUSE_STATUS 0x20D0
-#define IGP01E1000_ANALOG_FUSE_CONTROL 0x20DC
-#define IGP01E1000_ANALOG_FUSE_BYPASS 0x20DE
-
-#define IGP01E1000_ANALOG_FUSE_POLY_MASK 0xF000
-#define IGP01E1000_ANALOG_FUSE_FINE_MASK 0x0F80
-#define IGP01E1000_ANALOG_FUSE_COARSE_MASK 0x0070
-#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED 0x0100
-#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL 0x0002
-
-#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
-
-
-/* Bit definitions for valid PHY IDs. */
-/* I = Integrated
- * E = External
- */
-#define M88E1000_E_PHY_ID 0x01410C50
-#define M88E1000_I_PHY_ID 0x01410C30
-#define M88E1011_I_PHY_ID 0x01410C20
-#define IGP01E1000_I_PHY_ID 0x02A80380
-#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
-#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
-#define M88E1011_I_REV_4 0x04
-#define M88E1111_I_PHY_ID 0x01410CC0
-#define L1LXT971A_PHY_ID 0x001378E0
-
-/* Miscellaneous PHY bit definitions. */
-#define PHY_PREAMBLE 0xFFFFFFFF
-#define PHY_SOF 0x01
-#define PHY_OP_READ 0x02
-#define PHY_OP_WRITE 0x01
-#define PHY_TURNAROUND 0x02
-#define PHY_PREAMBLE_SIZE 32
-#define MII_CR_SPEED_1000 0x0040
-#define MII_CR_SPEED_100 0x2000
-#define MII_CR_SPEED_10 0x0000
-#define E1000_PHY_ADDRESS 0x01
-#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
-#define PHY_FORCE_TIME 20 /* 2.0 Seconds */
-#define PHY_REVISION_MASK 0xFFFFFFF0
-#define DEVICE_SPEED_MASK 0x00000300 /* Device Ctrl Reg Speed Mask */
-#define REG4_SPEED_MASK 0x01E0
-#define REG9_SPEED_MASK 0x0300
-#define ADVERTISE_10_HALF 0x0001
-#define ADVERTISE_10_FULL 0x0002
-#define ADVERTISE_100_HALF 0x0004
-#define ADVERTISE_100_FULL 0x0008
-#define ADVERTISE_1000_HALF 0x0010
-#define ADVERTISE_1000_FULL 0x0020
-#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */
-#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds*/
-#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds*/
-
-#endif /* _EM_HW_H_ */
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_osdep.h b/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_osdep.h
deleted file mode 100644
index 4bc5843a73..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_osdep.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/**************************************************************************
-
-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:
-
- 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: /repoman/r/ncvs/src/sys/dev/em/if_em_osdep.h,v 1.14 2005/05/26 23:32:02 tackerman Exp $*/
-
-#ifndef _RTEMS_OS_H_
-#define _RTEMS_OS_H_
-
-#include <rtems.h>
-#include "../porting/rtemscompat.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 <bsp/pci.h>
-
-/* Eventually, we should include this
-#include <rtems/rtems-mii-ioctl.h>
-*/
-#define IFM_LINK_OK IFM_FLAG0
-#define IFM_ANEG_DIS IFM_FLAG1
-
-#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);
-#if 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 bootverbose (1)
- #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 bootverbose (0)
- #define DEBUGOUT7(S,A,B,C,D,E,F,G)
-#endif
-
-#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
-#define PCI_COMMAND_REGISTER PCIR_COMMAND
-
-struct em_osdep
-{
- unsigned mem_bus_space_handle;
- device_t dev;
-};
-
-struct rtems_ifmedia {
- int ifm_media;
-};
-
-#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)
-
-#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)
-
-#endif /* _FREEBSD_OS_H_ */
-
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_rtems.c b/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_rtems.c
deleted file mode 100644
index fde1de7dc7..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/if_em_rtems.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#include "rtemscompat_defs.h"
-#include "../porting/if_xxx_rtems.c"
-#include <bsp/early_enet_link_status.h>
-#include <bsp/if_em_pub.h>
-
-/* Provide a routine to check link status early,
- * i.e., before the network is really running.
- * In case someone wants to decide whether to use/configure
- * this interface at all :-)
- *
- * NOTE: this routine tries to enable autonegotiation!
- *
- * unit: unit number starting with 1 (usual BSDNET convention)
- *
- * RETURNS: Phy status register contents (1<<2 means link up).
- * or -1 on error.
- */
-
-/*
- * Authorship
- * ----------
- * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
- * created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
- * Stanford Linear Accelerator Center, Stanford University.
- *
- * Acknowledgement of sponsorship
- * ------------------------------
- * The 'beatnik' BSP was produced by
- * the Stanford Linear Accelerator Center, Stanford University,
- * under Contract DE-AC03-76SFO0515 with the Department of Energy.
- *
- * Government disclaimer of liability
- * ----------------------------------
- * Neither the United States nor the United States Department of Energy,
- * nor any of their employees, makes any warranty, express or implied, or
- * assumes any legal liability or responsibility for the accuracy,
- * completeness, or usefulness of any data, apparatus, product, or process
- * disclosed, or represents that its use would not infringe privately owned
- * rights.
- *
- * Stanford disclaimer of liability
- * --------------------------------
- * Stanford University makes no representations or warranties, express or
- * implied, nor assumes any liability for the use of this software.
- *
- * Stanford disclaimer of copyright
- * --------------------------------
- * Stanford University, owner of the copyright, hereby disclaims its
- * copyright and all other rights in this software. Hence, anyone may
- * freely use it for any purpose without restriction.
- *
- * Maintenance of notices
- * ----------------------
- * In the interest of clarity regarding the origin and status of this
- * SLAC software, this and all the preceding Stanford University notices
- * are to remain affixed to any copy or derivative of this software made
- * or distributed by the recipient and are to be affixed to any copy of
- * software made or distributed by the recipient that contains a copy or
- * derivative of this software.
- *
- * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
- */
-
-static int
-em_early_init(int idx)
-{
- if ( idx < 0 || idx >= NETDRIVER_SLOTS )
- return -1;
- return em_hw_early_init(&the_em_devs[idx]);
-}
-
-static int
-em_early_read_phy(int idx, unsigned reg)
-{
-unsigned short data;
- if ( idx < 0 || idx >= NETDRIVER_SLOTS )
- return -1;
- /* Bizarre - I always have to read PHY_STATUS twice until a good link
- * status is read
- */
- if ( em_read_phy_reg(&the_em_devs[idx].d_softc.hw, reg, &data) )
- return -1;
- if ( PHY_STATUS == reg ) {
- /* read again */
- if ( em_read_phy_reg(&the_em_devs[idx].d_softc.hw, PHY_STATUS, &data) )
- return -1;
- }
- return data;
-}
-
-static int
-em_early_write_phy(int idx, unsigned reg, unsigned val)
-{
- if ( idx < 0 || idx >= NETDRIVER_SLOTS )
- return -1;
- return em_write_phy_reg(&the_em_devs[idx].d_softc.hw, reg, val);
-}
-
-rtems_bsdnet_early_link_check_ops
-rtems_em_early_link_check_ops = {
- init: em_early_init,
- read_phy: em_early_read_phy,
- write_phy: em_early_write_phy,
- name: NETDRIVER,
- num_slots: NETDRIVER_SLOTS
-};
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/rtemscompat_defs.h b/c/src/lib/libbsp/powerpc/beatnik/network/if_em/rtemscompat_defs.h
deleted file mode 100644
index 6a132a1b26..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_em/rtemscompat_defs.h
+++ /dev/null
@@ -1,198 +0,0 @@
-#ifndef RTEMS_COMPAT_DEFS_H
-#define RTEMS_COMPAT_DEFS_H
-
-/* Number of device instances the driver should support
- * - may be limited to 1 depending on IRQ API
- * (braindamaged PC586 and powerpc)
- */
-#define NETDRIVER_SLOTS 1
-
-/* String name to print with error messages */
-#define NETDRIVER "em"
-/* Name snippet used to make global symbols unique to this driver */
-#define NETDRIVER_PREFIX em
-
-#define adapter em_softc
-#define interface_data arpcom
-
-/* Define according to endianness of the *ethernet*chip*
- * (not the CPU - most probably are LE)
- * This must be either NET_CHIP_LE or NET_CHIP_BE
- */
-
-#define NET_CHIP_LE
-#undef NET_CHIP_BE
-
-/* Define either NET_CHIP_MEM_IO or NET_CHIP_PORT_IO,
- * depending whether the CPU sees it in memory address space
- * or (e.g. x86) uses special I/O instructions.
- */
-#define NET_CHIP_MEM_IO
-#undef NET_CHIP_PORT_IO
-
-/* The name of the hijacked 'bus handle' field in the softc
- * structure. We use this field to store the chip's base address.
- */
-#define NET_SOFTC_BHANDLE_FIELD osdep.mem_bus_space_handle
-
-/* define the names of the 'if_XXXreg.h' and 'if_XXXvar.h' headers
- * (only if present, i.e., if the BSDNET driver has no respective
- * header, leave this undefined).
- *
- */
-#define IF_REG_HEADER "../if_em/if_em.h"
-#undef IF_VAR_HEADER
-
-/* define if a pci device */
-#define NETDRIVER_PCI <bsp/pci.h>
-
-/* Macros to disable and enable interrupts, respectively.
- * The 'disable' macro is expanded in the ISR, the 'enable'
- * macro is expanded in the driver task.
- * The global network semaphore usually provides mutex
- * protection of the device registers.
- * Special care must be taken when coding the 'disable' macro,
- * however to MAKE SURE THERE ARE NO OTHER SIDE EFFECTS such
- * as:
- * - macro must not clear any status flags
- * - macro must save/restore any context information
- * (e.g., a address register pointer or a bank switch register)
- *
- * ARGUMENT: the macro arg is a pointer to the driver's 'softc' structure
- */
-
-#define NET_ENABLE_IRQS(sc) do { \
- E1000_WRITE_REG(&sc->hw, IMS, (IMS_ENABLE_MASK)); \
- } while (0)
-
-#define NET_DISABLE_IRQS(sc) do { \
- E1000_WRITE_REG(&sc->hw, IMC, 0xffffffff); \
- } while (0)
-
-#define KASSERT(a...) do {} while (0)
-
-/* dmamap stuff; these are defined just to work with the current version
- * of this driver and the implementation must be carefully checked if
- * a newer version is merged.!
- *
- * The more cumbersome routines have been commented in the source, the
- * simpler ones are defined to be NOOPs here so the source gets less
- * cluttered...
- *
- * ASSUMPTIONS:
- *
- * -> dmamap_sync cannot sync caches; assume we have HW snooping
- *
- */
-
-typedef unsigned bus_size_t;
-typedef unsigned bus_addr_t;
-
-typedef struct {
- unsigned ds_addr;
- unsigned ds_len;
-} bus_dma_segment_t;
-
-#define bus_dma_tag_destroy(args...) do {} while(0)
-
-#define bus_dmamap_destroy(args...) do {} while(0)
-
-#define bus_dmamap_unload(args...) do {} while (0)
-
-#ifdef __PPC__
-#define bus_dmamap_sync(args...) do { __asm__ volatile("sync":::"memory"); } while (0)
-#else
-#define bus_dmamap_sync(args...) do {} while (0)
-#endif
-
-#define BUS_DMA_NOWAIT 0xdeadbeef /* unused */
-
-#define em_adapter_list _bsd_em_adapter_list
-#define em_arc_subsystem_valid _bsd_em_arc_subsystem_valid
-#define em_check_downshift _bsd_em_check_downshift
-#define em_check_for_link _bsd_em_check_for_link
-#define em_check_mng_mode _bsd_em_check_mng_mode
-#define em_check_phy_reset_block _bsd_em_check_phy_reset_block
-#define em_check_polarity _bsd_em_check_polarity
-#define em_cleanup_led _bsd_em_cleanup_led
-#define em_clear_hw_cntrs _bsd_em_clear_hw_cntrs
-#define em_clear_vfta _bsd_em_clear_vfta
-#define em_commit_shadow_ram _bsd_em_commit_shadow_ram
-#define em_config_collision_dist _bsd_em_config_collision_dist
-#define em_config_dsp_after_link_change _bsd_em_config_dsp_after_link_change
-#define em_config_fc_after_link_up _bsd_em_config_fc_after_link_up
-#define em_dbg_config _bsd_em_dbg_config
-#define em_detect_gig_phy _bsd_em_detect_gig_phy
-#define em_disable_pciex_master _bsd_em_disable_pciex_master
-#define em_display_debug_stats _bsd_em_display_debug_stats
-#define em_driver_version _bsd_em_driver_version
-#define em_enable_mng_pass_thru _bsd_em_enable_mng_pass_thru
-#define em_enable_pciex_master _bsd_em_enable_pciex_master
-#define em_enable_tx_pkt_filtering _bsd_em_enable_tx_pkt_filtering
-#define em_force_mac_fc _bsd_em_force_mac_fc
-#define em_get_auto_rd_done _bsd_em_get_auto_rd_done
-#define em_get_bus_info _bsd_em_get_bus_info
-#define em_get_cable_length _bsd_em_get_cable_length
-#define em_get_hw_eeprom_semaphore _bsd_em_get_hw_eeprom_semaphore
-#define em_get_phy_cfg_done _bsd_em_get_phy_cfg_done
-#define em_get_speed_and_duplex _bsd_em_get_speed_and_duplex
-#define em_hash_mc_addr _bsd_em_hash_mc_addr
-#define em_hw_early_init _bsd_em_hw_early_init
-#define em_id_led_init _bsd_em_id_led_init
-#define em_init_eeprom_params _bsd_em_init_eeprom_params
-#define em_init_hw _bsd_em_init_hw
-#define em_init_rx_addrs _bsd_em_init_rx_addrs
-#define em_io_read _bsd_em_io_read
-#define em_io_write _bsd_em_io_write
-#define em_is_onboard_nvm_eeprom _bsd_em_is_onboard_nvm_eeprom
-#define em_led_off _bsd_em_led_off
-#define em_led_on _bsd_em_led_on
-#define em_mc_addr_list_update _bsd_em_mc_addr_list_update
-#define em_mng_enable_host_if _bsd_em_mng_enable_host_if
-#define em_mng_host_if_write _bsd_em_mng_host_if_write
-#define em_mng_write_cmd_header _bsd_em_mng_write_cmd_header
-#define em_mng_write_commit _bsd_em_mng_write_commit
-#define em_mng_write_dhcp_info _bsd_em_mng_write_dhcp_info
-#define em_mta_set _bsd_em_mta_set
-#define em_pci_clear_mwi _bsd_em_pci_clear_mwi
-#define em_pci_set_mwi _bsd_em_pci_set_mwi
-#define em_phy_get_info _bsd_em_phy_get_info
-#define em_phy_hw_reset _bsd_em_phy_hw_reset
-#define em_phy_igp_get_info _bsd_em_phy_igp_get_info
-#define em_phy_m88_get_info _bsd_em_phy_m88_get_info
-#define em_phy_reset _bsd_em_phy_reset
-#define em_phy_setup_autoneg _bsd_em_phy_setup_autoneg
-#define em_poll_eerd_eewr_done _bsd_em_poll_eerd_eewr_done
-#define em_put_hw_eeprom_semaphore _bsd_em_put_hw_eeprom_semaphore
-#define em_rar_set _bsd_em_rar_set
-#define em_read_eeprom _bsd_em_read_eeprom
-#define em_read_eeprom_eerd _bsd_em_read_eeprom_eerd
-#define em_read_mac_addr _bsd_em_read_mac_addr
-#define em_read_part_num _bsd_em_read_part_num
-#define em_read_pci_cfg _bsd_em_read_pci_cfg
-#define em_read_phy_reg _bsd_em_read_phy_reg
-#define em_read_reg_io _bsd_em_read_reg_io
-#define em_reset_adaptive _bsd_em_reset_adaptive
-#define em_reset_hw _bsd_em_reset_hw
-#define em_set_d0_lplu_state _bsd_em_set_d0_lplu_state
-#define em_set_d3_lplu_state _bsd_em_set_d3_lplu_state
-#define em_set_mac_type _bsd_em_set_mac_type
-#define em_set_media_type _bsd_em_set_media_type
-#define em_set_pci_express_master_disable _bsd_em_set_pci_express_master_disable
-#define em_setup_led _bsd_em_setup_led
-#define em_setup_link _bsd_em_setup_link
-#define em_tbi_adjust_stats _bsd_em_tbi_adjust_stats
-#define em_update_adaptive _bsd_em_update_adaptive
-#define em_update_eeprom_checksum _bsd_em_update_eeprom_checksum
-#define em_validate_eeprom_checksum _bsd_em_validate_eeprom_checksum
-#define em_validate_mdi_setting _bsd_em_validate_mdi_setting
-#define em_wait_autoneg _bsd_em_wait_autoneg
-#define em_write_eeprom _bsd_em_write_eeprom
-#define em_write_eeprom_eewr _bsd_em_write_eeprom_eewr
-#define em_write_pci_cfg _bsd_em_write_pci_cfg
-#define em_write_phy_reg _bsd_em_write_phy_reg
-#define em_write_reg_io _bsd_em_write_reg_io
-#define em_write_vfta _bsd_em_write_vfta
-#define the_em_devs _bsd_the_em_devs
-
-#endif
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/gtethreg.h b/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/gtethreg.h
deleted file mode 100644
index d571eecd34..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/gtethreg.h
+++ /dev/null
@@ -1,854 +0,0 @@
-/* $NetBSD: gtethreg.h,v 1.2.10.1 2005/04/29 11:28:55 kent Exp $ */
-
-/*
- * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Allegro Networks, Inc., and Wasabi Systems, Inc.
- * 4. The name of Allegro Networks, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * 5. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
- * WASABI SYSTEMS, INC. ``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 EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
- * 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.
- */
-
-#ifndef _DEV_GTETHREG_H_
-#define _DEV_GTETHREG_H_
-
-#define ETH__BIT(bit) (1U << (bit))
-#define ETH__LLBIT(bit) (1LLU << (bit))
-#define ETH__MASK(bit) (ETH__BIT(bit) - 1)
-#define ETH__LLMASK(bit) (ETH__LLBIT(bit) - 1)
-#define ETH__GEN(n, off) (0x2400+((n) << 10)+(ETH__ ## off))
-#define ETH__EXT(data, bit, len) (((data) >> (bit)) & ETH__MASK(len))
-#define ETH__LLEXT(data, bit, len) (((data) >> (bit)) & ETH__LLMASK(len))
-#define ETH__CLR(data, bit, len) ((data) &= ~(ETH__MASK(len) << (bit)))
-#define ETH__INS(new, bit) ((new) << (bit))
-#define ETH__LLINS(new, bit) ((uint64_t)(new) << (bit))
-
-/*
- * Descriptors used for both receive & transmit data. Note that the descriptor
- * must start on a 4LW boundary. Since the GT accesses the descriptor as
- * two 64-bit quantities, we must present them 32bit quantities in the right
- * order based on endianess.
- */
-
-struct gt_eth_desc {
-#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
- u_int32_t ed_lencnt; /* length is hi 16 bits; count (rx) is lo 16 */
- u_int32_t ed_cmdsts; /* command (hi16)/status (lo16) bits */
- u_int32_t ed_nxtptr; /* next descriptor (must be 4LW aligned) */
- u_int32_t ed_bufptr; /* pointer to packet buffer */
-#endif
-#if defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
- u_int32_t ed_cmdsts; /* command (hi16)/status (lo16) bits */
- u_int32_t ed_lencnt; /* length is hi 16 bits; count (rx) is lo 16 */
- u_int32_t ed_bufptr; /* pointer to packet buffer */
- u_int32_t ed_nxtptr; /* next descriptor (must be 4LW aligned) */
-#endif
-};
-
-/* Table 578: Ethernet TX Descriptor - Command/Status word
- * All bits except F, EI, AM, O are only valid if TX_CMD_L is also set,
- * otherwise should be 0 (tx).
- */
-#define TX_STS_LC ETH__BIT(5) /* Late Collision */
-#define TX_STS_UR ETH__BIT(6) /* Underrun error */
-#define TX_STS_RL ETH__BIT(8) /* Retransmit Limit (excession coll) */
-#define TX_STS_COL ETH__BIT(9) /* Collision Occurred */
-#define TX_STS_RC(v) ETH__GETBITS(v, 10, 4) /* Retransmit Count */
-#define TX_STS_ES ETH__BIT(15) /* Error Summary (LC|UR|RL) */
-#define TX_CMD_L ETH__BIT(16) /* Last - End Of Packet */
-#define TX_CMD_F ETH__BIT(17) /* First - Start Of Packet */
-#define TX_CMD_P ETH__BIT(18) /* Pad Packet */
-#define TX_CMD_GC ETH__BIT(22) /* Generate CRC */
-#define TX_CMD_EI ETH__BIT(23) /* Enable Interrupt */
-#define TX_CMD_AM ETH__BIT(30) /* Auto Mode */
-#define TX_CMD_O ETH__BIT(31) /* Ownership (1=GT 0=CPU) */
-
-#define TX_CMD_FIRST (TX_CMD_F|TX_CMD_O)
-#define TX_CMD_LAST (TX_CMD_L|TX_CMD_GC|TX_CMD_P|TX_CMD_O)
-
-/* Table 582: Ethernet RX Descriptor - Command/Status Word
- * All bits except F, EI, AM, O are only valid if RX_CMD_L is also set,
- * otherwise should be ignored (rx).
- */
-#define RX_STS_CE ETH__BIT(0) /* CRC Error */
-#define RX_STS_COL ETH__BIT(1) /* Collision sensed during reception */
-#define RX_STS_LC ETH__BIT(5) /* Late Collision (Reserved) */
-#define RX_STS_OR ETH__BIT(6) /* Overrun Error */
-#define RX_STS_MFL ETH__BIT(7) /* Max Frame Len Error */
-#define RX_STS_SF ETH__BIT(8) /* Short Frame Error (< 64 bytes) */
-#define RX_STS_FT ETH__BIT(11) /* Frame Type (1 = 802.3) */
-#define RX_STS_M ETH__BIT(12) /* Missed Frame */
-#define RX_STS_HE ETH__BIT(13) /* Hash Expired (manual match) */
-#define RX_STS_IGMP ETH__BIT(14) /* IGMP Packet */
-#define RX_STS_ES ETH__BIT(15) /* Error Summary (CE|COL|LC|OR|MFL|SF) */
-#define RX_CMD_L ETH__BIT(16) /* Last - End Of Packet */
-#define RX_CMD_F ETH__BIT(17) /* First - Start Of Packet */
-#define RX_CMD_EI ETH__BIT(23) /* Enable Interrupt */
-#define RX_CMD_AM ETH__BIT(30) /* Auto Mode */
-#define RX_CMD_O ETH__BIT(31) /* Ownership (1=GT 0=CPU) */
-
-/* Table 586: Hash Table Entry Fields
- */
-#define HSH_V ETH__LLBIT(0) /* Entry is valid */
-#define HSH_S ETH__LLBIT(1) /* Skip this entry */
-#define HSH_RD ETH__LLBIT(2) /* Receive(1) / Discard (0) */
-#define HSH_R ETH__LLBIT(2) /* Receive(1) */
-#define HSH_PRIO_GET(v) ETH__LLEXT(v, 51, 2)
-#define HSH_PRIO_INS(v) ETH__LLINS(v, 51)
-#define HSH_ADDR_MASK 0x7fffff8LLU
-#define HSH_LIMIT 12
-
-
-#define ETH_EPAR 0x2000 /* PHY Address Register */
-#define ETH_ESMIR 0x2010 /* SMI Register */
-
-#define ETH_BASE_ETH0 0x2400 /* Ethernet0 Register Base */
-#define ETH_BASE_ETH1 0x2800 /* Ethernet1 Register Base */
-#define ETH_BASE_ETH2 0x2c00 /* Ethernet2 Register Base */
-#define ETH_SIZE 0x0400 /* Register Space */
-
-#define ETH__EBASE 0x0000 /* Base of Registers */
-#define ETH__EPCR 0x0000 /* Port Config. Register */
-#define ETH__EPCXR 0x0008 /* Port Config. Extend Reg */
-#define ETH__EPCMR 0x0010 /* Port Command Register */
-#define ETH__EPSR 0x0018 /* Port Status Register */
-#define ETH__ESPR 0x0020 /* Port Serial Parameters Reg */
-#define ETH__EHTPR 0x0028 /* Port Hash Table Pointer Reg*/
-#define ETH__EFCSAL 0x0030 /* Flow Control Src Addr Low */
-#define ETH__EFCSAH 0x0038 /* Flow Control Src Addr High */
-#define ETH__ESDCR 0x0040 /* SDMA Configuration Reg */
-#define ETH__ESDCMR 0x0048 /* SDMA Command Register */
-#define ETH__EICR 0x0050 /* Interrupt Cause Register */
-#define ETH__EIMR 0x0058 /* Interrupt Mask Register */
-#define ETH__EFRDP0 0x0080 /* First Rx Desc Pointer 0 */
-#define ETH__EFRDP1 0x0084 /* First Rx Desc Pointer 1 */
-#define ETH__EFRDP2 0x0088 /* First Rx Desc Pointer 2 */
-#define ETH__EFRDP3 0x008c /* First Rx Desc Pointer 3 */
-#define ETH__ECRDP0 0x00a0 /* Current Rx Desc Pointer 0 */
-#define ETH__ECRDP1 0x00a4 /* Current Rx Desc Pointer 1 */
-#define ETH__ECRDP2 0x00a8 /* Current Rx Desc Pointer 2 */
-#define ETH__ECRDP3 0x00ac /* Current Rx Desc Pointer 3 */
-#define ETH__ECTDP0 0x00e0 /* Current Tx Desc Pointer 0 */
-#define ETH__ECTDP1 0x00e4 /* Current Tx Desc Pointer 1 */
-#define ETH__EDSCP2P0L 0x0060 /* IP Differentiated Services
- CodePoint to Priority0 low */
-#define ETH__EDSCP2P0H 0x0064 /* IP Differentiated Services
- CodePoint to Priority0 high*/
-#define ETH__EDSCP2P1L 0x0068 /* IP Differentiated Services
- CodePoint to Priority1 low */
-#define ETH__EDSCP2P1H 0x006c /* IP Differentiated Services
- CodePoint to Priority1 high*/
-#define ETH__EVPT2P 0x0068 /* VLAN Prio. Tag to Priority */
-#define ETH__EMIBCTRS 0x0100 /* MIB Counters */
-
-#define ETH_BASE(n) ETH__GEN(n, EBASE)
-#define ETH_EPCR(n) ETH__GEN(n, EPCR) /* Port Config. Register */
-#define ETH_EPCXR(n) ETH__GEN(n, EPCXR) /* Port Config. Extend Reg */
-#define ETH_EPCMR(n) ETH__GEN(n, EPCMR) /* Port Command Register */
-#define ETH_EPSR(n) ETH__GEN(n, EPSR) /* Port Status Register */
-#define ETH_ESPR(n) ETH__GEN(n, ESPR) /* Port Serial Parameters Reg */
-#define ETH_EHTPR(n) ETH__GEN(n, EHPTR) /* Port Hash Table Pointer Reg*/
-#define ETH_EFCSAL(n) ETH__GEN(n, EFCSAL) /* Flow Control Src Addr Low */
-#define ETH_EFCSAH(n) ETH__GEN(n, EFCSAH) /* Flow Control Src Addr High */
-#define ETH_ESDCR(n) ETH__GEN(n, ESDCR) /* SDMA Configuration Reg */
-#define ETH_ESDCMR(n) ETH__GEN(n, ESDCMR) /* SDMA Command Register */
-#define ETH_EICR(n) ETH__GEN(n, EICR) /* Interrupt Cause Register */
-#define ETH_EIMR(n) ETH__GEN(n, EIMR) /* Interrupt Mask Register */
-#define ETH_EFRDP0(n) ETH__GEN(n, EFRDP0) /* First Rx Desc Pointer 0 */
-#define ETH_EFRDP1(n) ETH__GEN(n, EFRDP1) /* First Rx Desc Pointer 1 */
-#define ETH_EFRDP2(n) ETH__GEN(n, EFRDP2) /* First Rx Desc Pointer 2 */
-#define ETH_EFRDP3(n) ETH__GEN(n, EFRDP3) /* First Rx Desc Pointer 3 */
-#define ETH_ECRDP0(n) ETH__GEN(n, ECRDP0) /* Current Rx Desc Pointer 0 */
-#define ETH_ECRDP1(n) ETH__GEN(n, ECRDP1) /* Current Rx Desc Pointer 1 */
-#define ETH_ECRDP2(n) ETH__GEN(n, ECRDP2) /* Current Rx Desc Pointer 2 */
-#define ETH_ECRDP3(n) ETH__GEN(n, ECRDP3) /* Current Rx Desc Pointer 3 */
-#define ETH_ECTDP0(n) ETH__GEN(n, ECTDP0) /* Current Tx Desc Pointer 0 */
-#define ETH_ECTDP1(n) ETH__GEN(n, ECTDP1) /* Current Tx Desc Pointer 1 */
-#define ETH_EDSCP2P0L(n) ETH__GEN(n, EDSCP2P0L) /* IP Differentiated Services
- CodePoint to Priority0 low */
-#define ETH_EDSCP2P0H(n) ETH__GEN(n, EDSCP2P0H) /* IP Differentiated Services
- CodePoint to Priority0 high*/
-#define ETH_EDSCP2P1L(n) ETH__GEN(n, EDSCP2P1L) /* IP Differentiated Services
- CodePoint to Priority1 low */
-#define ETH_EDSCP2P1H(n) ETH__GEN(n, EDSCP1P1H) /* IP Differentiated Services
- CodePoint to Priority1 high*/
-#define ETH_EVPT2P(n) ETH__GEN(n, EVPT2P) /* VLAN Prio. Tag to Priority */
-#define ETH_EMIBCTRS(n) ETH__GEN(n, EMIBCTRS) /* MIB Counters */
-
-#define ETH_EPAR_PhyAD_GET(v, n) (((v) >> ((n) * 5)) & 0x1f)
-
-#define ETH_ESMIR_READ(phy, reg) (ETH__INS(phy, 16)|\
- ETH__INS(reg, 21)|\
- ETH_ESMIR_ReadOpcode)
-#define ETH_ESMIR_WRITE(phy, reg, val) (ETH__INS(phy, 16)|\
- ETH__INS(reg, 21)|\
- ETH__INS(val, 0)|\
- ETH_ESMIR_WriteOpcode)
-#define ETH_ESMIR_Value_GET(v) ETH__EXT(v, 0, 16)
-#define ETH_ESMIR_WriteOpcode 0
-#define ETH_ESMIR_ReadOpcode ETH__BIT(26)
-#define ETH_ESMIR_ReadValid ETH__BIT(27)
-#define ETH_ESMIR_Busy ETH__BIT(28)
-
-/*
- * Table 597: Port Configuration Register (PCR)
- * 00:00 PM Promiscuous mode
- * 0: Normal mode (Frames are only received if the
- * destination address is found in the hash
- * table)
- * 1: Promiscuous mode (Frames are received
- * regardless of their destination address.
- * Errored frames are discarded unless the Port
- * Configuration register's PBF bit is set)
- * 01:01 RBM Reject Broadcast Mode
- * 0: Receive broadcast address
- * 1: Reject frames with broadcast address
- * Overridden by the promiscuous mode.
- * 02:02 PBF Pass Bad Frames
- * (0: Normal mode, 1: Pass bad Frames)
- * The Ethernet receiver passes to the CPU errored
- * frames (like fragments and collided packets)
- * that are normally rejected.
- * NOTE: Frames are only passed if they
- * successfully pass address filtering.
- * 06:03 Reserved
- * 07:07 EN Enable (0: Disabled, 1: Enable)
- * When enabled, the ethernet port is ready to
- * transmit/receive.
- * 09:08 LPBK Loop Back Mode
- * 00: Normal mode
- * 01: Internal loop back mode (TX data is looped
- * back to the RX lines. No transition is seen
- * on the interface pins)
- * 10: External loop back mode (TX data is looped
- * back to the RX lines and also transmitted
- * out to the MII interface pins)
- * 11: Reserved
- * 10:10 FC Force Collision
- * 0: Normal mode.
- * 1: Force Collision on any TX frame.
- * For RXM test (in Loopback mode).
- * 11:11 Reserved.
- * 12:12 HS Hash Size
- * 0: 8K address filtering
- * (256KB of memory space required).
- * 1: 512 address filtering
- * ( 16KB of memory space required).
- * 13:13 HM Hash Mode (0: Hash Func. 0; 1: Hash Func. 1)
- * 14:14 HDM Hash Default Mode
- * 0: Discard addresses not found in address table
- * 1: Pass addresses not found in address table
- * 15:15 HD Duplex Mode (0: Half Duplex, 1: Full Duplex)
- * NOTE: Valid only when auto-negotiation for
- * duplex mode is disabled.
- * 30:16 Reserved
- * 31:31 ACCS Accelerate Slot Time
- * (0: Normal mode, 1: Reserved)
- */
-#define ETH_EPCR_PM ETH__BIT(0)
-#define ETH_EPCR_RBM ETH__BIT(1)
-#define ETH_EPCR_PBF ETH__BIT(2)
-#define ETH_EPCR_EN ETH__BIT(7)
-#define ETH_EPCR_LPBK_GET(v) ETH__BIT(v, 8, 2)
-#define ETH_EPCR_LPBK_Normal 0
-#define ETH_EPCR_LPBK_Internal 1
-#define ETH_EPCR_LPBK_External 2
-#define ETH_EPCR_FC ETH__BIT(10)
-
-#define ETH_EPCR_HS ETH__BIT(12)
-#define ETH_EPCR_HS_8K 0
-#define ETH_EPCR_HS_512 ETH_EPCR_HS
-
-#define ETH_EPCR_HM ETH__BIT(13)
-#define ETH_EPCR_HM_0 0
-#define ETH_EPCR_HM_1 ETH_EPCR_HM
-
-#define ETH_EPCR_HDM ETH__BIT(14)
-#define ETH_EPCR_HDM_Discard 0
-#define ETH_EPCR_HDM_Pass ETH_EPCR_HDM
-
-#define ETH_EPCR_HD_Half 0
-#define ETH_EPCR_HD_Full ETH_EPCR_HD_Full
-
-#define ETH_EPCR_ACCS ETH__BIT(31)
-
-
-
-/*
- * Table 598: Port Configuration Extend Register (PCXR)
- * 00:00 IGMP IGMP Packets Capture Enable
- * 0: IGMP packets are treated as normal Multicast
- * packets.
- * 1: IGMP packets on IPv4/Ipv6 over Ethernet/802.3
- * are trapped and sent to high priority RX
- * queue.
- * 01:01 SPAN Spanning Tree Packets Capture Enable
- * 0: BPDU (Bridge Protocol Data Unit) packets are
- * treated as normal Multicast packets.
- * 1: BPDU packets are trapped and sent to high
- * priority RX queue.
- * 02:02 PAR Partition Enable (0: Normal, 1: Partition)
- * When more than 61 collisions occur while
- * transmitting, the port enters Partition mode.
- * It waits for the first good packet from the
- * wire and then goes back to Normal mode. Under
- * Partition mode it continues transmitting, but
- * it does not receive.
- * 05:03 PRIOtx Priority weight in the round-robin between high
- * and low priority TX queues.
- * 000: 1 pkt from HIGH, 1 pkt from LOW.
- * 001: 2 pkt from HIGH, 1 pkt from LOW.
- * 010: 4 pkt from HIGH, 1 pkt from LOW.
- * 011: 6 pkt from HIGH, 1 pkt from LOW.
- * 100: 8 pkt from HIGH, 1 pkt from LOW.
- * 101: 10 pkt from HIGH, 1 pkt from LOW.
- * 110: 12 pkt from HIGH, 1 pkt from LOW.
- * 111: All pkt from HIGH, 0 pkt from LOW. LOW is
- * served only if HIGH is empty.
- * NOTE: If the HIGH queue is emptied before
- * finishing the count, the count is reset
- * until the next first HIGH comes in.
- * 07:06 PRIOrx Default Priority for Packets Received on this
- * Port (00: Lowest priority, 11: Highest priority)
- * 08:08 PRIOrx_Override Override Priority for Packets Received on this
- * Port (0: Do not override, 1: Override with
- * <PRIOrx> field)
- * 09:09 DPLXen Enable Auto-negotiation for Duplex Mode
- * (0: Enable, 1: Disable)
- * 11:10 FCTLen Enable Auto-negotiation for 802.3x Flow-control
- * 0: Enable; When enabled, 1 is written (through
- * SMI access) to the PHY's register 4 bit 10
- * to advertise flow-control capability.
- * 1: Disable; Only enables flow control after the
- * PHY address is set by the CPU. When changing
- * the PHY address the flow control
- * auto-negotiation must be disabled.
- * 11:11 FLP Force Link Pass
- * (0: Force Link Pass, 1: Do NOT Force Link pass)
- * 12:12 FCTL 802.3x Flow-Control Mode (0: Enable, 1: Disable)
- * NOTE: Only valid when auto negotiation for flow
- * control is disabled.
- * 13:13 Reserved
- * 15:14 MFL Max Frame Length
- * Maximum packet allowed for reception (including
- * CRC): 00: 1518 bytes, 01: 1536 bytes,
- * 10: 2048 bytes, 11: 64K bytes
- * 16:16 MIBclrMode MIB Counters Clear Mode (0: Clear, 1: No effect)
- * 17:17 MIBctrMode Reserved. (MBZ)
- * 18:18 Speed Port Speed (0: 10Mbit/Sec, 1: 100Mbit/Sec)
- * NOTE: Only valid if SpeedEn bit is set.
- * 19:19 SpeedEn Enable Auto-negotiation for Speed
- * (0: Enable, 1: Disable)
- * 20:20 RMIIen RMII enable
- * 0: Port functions as MII port
- * 1: Port functions as RMII port
- * 21:21 DSCPen DSCP enable
- * 0: IP DSCP field decoding is disabled.
- * 1: IP DSCP field decoding is enabled.
- * 31:22 Reserved
- */
-#define ETH_EPCXR_IGMP ETH__BIT(0)
-#define ETH_EPCXR_SPAN ETH__BIT(1)
-#define ETH_EPCXR_PAR ETH__BIT(2)
-#define ETH_EPCXR_PRIOtx_GET(v) ETH__EXT(v, 3, 3)
-#define ETH_EPCXR_PRIOrx_GET(v) ETH__EXT(v, 3, 3)
-#define ETH_EPCXR_PRIOrx_Override ETH__BIT(8)
-#define ETH_EPCXR_DLPXen ETH__BIT(9)
-#define ETH_EPCXR_FCTLen ETH__BIT(10)
-#define ETH_EPCXR_FLP ETH__BIT(11)
-#define ETH_EPCXR_FCTL ETH__BIT(12)
-#define ETH_EPCXR_MFL_GET(v) ETH__EXT(v, 14, 2)
-#define ETH_EPCXR_MFL_1518 0
-#define ETH_EPCXR_MFL_1536 1
-#define ETH_EPCXR_MFL_2084 2
-#define ETH_EPCXR_MFL_64K 3
-#define ETH_EPCXR_MIBclrMode ETH__BIT(16)
-#define ETH_EPCXR_MIBctrMode ETH__BIT(17)
-#define ETH_EPCXR_Speed ETH__BIT(18)
-#define ETH_EPCXR_SpeedEn ETH__BIT(19)
-#define ETH_EPCXR_RMIIEn ETH__BIT(20)
-#define ETH_EPCXR_DSCPEn ETH__BIT(21)
-
-
-
-/*
- * Table 599: Port Command Register (PCMR)
- * 14:00 Reserved
- * 15:15 FJ Force Jam / Flow Control
- * When in half-duplex mode, the CPU uses this bit
- * to force collisions on the Ethernet segment.
- * When the CPU recognizes that it is going to run
- * out of receive buffers, it can force the
- * transmitter to send jam frames, forcing
- * collisions on the wire. To allow transmission
- * on the Ethernet segment, the CPU must clear the
- * FJ bit when more resources are available. When
- * in full-duplex and flow-control is enabled, this
- * bit causes the port's transmitter to send
- * flow-control PAUSE packets. The CPU must reset
- * this bit when more resources are available.
- * 31:16 Reserved
- */
-
-#define ETH_EPCMR_FJ ETH__BIT(15)
-
-
-/*
- * Table 600: Port Status Register (PSR) -- Read Only
- * 00:00 Speed Indicates Port Speed (0: 10Mbs, 1: 100Mbs)
- * 01:01 Duplex Indicates Port Duplex Mode (0: Half, 1: Full)
- * 02:02 Fctl Indicates Flow-control Mode
- * (0: enabled, 1: disabled)
- * 03:03 Link Indicates Link Status (0: down, 1: up)
- * 04:04 Pause Indicates that the port is in flow-control
- * disabled state. This bit is set when an IEEE
- * 802.3x flow-control PAUSE (XOFF) packet is
- * received (assuming that flow-control is
- * enabled and the port is in full-duplex mode).
- * Reset when XON is received, or when the XOFF
- * timer has expired.
- * 05:05 TxLow Tx Low Priority Status
- * Indicates the status of the low priority
- * transmit queue: (0: Stopped, 1: Running)
- * 06:06 TxHigh Tx High Priority Status
- * Indicates the status of the high priority
- * transmit queue: (0: Stopped, 1: Running)
- * 07:07 TXinProg TX in Progress
- * Indicates that the port's transmitter is in an
- * active transmission state.
- * 31:08 Reserved
- */
-#define ETH_EPSR_Speed ETH__BIT(0)
-#define ETH_EPSR_Duplex ETH__BIT(1)
-#define ETH_EPSR_Fctl ETH__BIT(2)
-#define ETH_EPSR_Link ETH__BIT(3)
-#define ETH_EPSR_Pause ETH__BIT(4)
-#define ETH_EPSR_TxLow ETH__BIT(5)
-#define ETH_EPSR_TxHigh ETH__BIT(6)
-#define ETH_EPSR_TXinProg ETH__BIT(7)
-
-
-/*
- * Table 601: Serial Parameters Register (SPR)
- * 01:00 JAM_LENGTH Two bits to determine the JAM Length
- * (in Backpressure) as follows:
- * 00 = 12K bit-times
- * 01 = 24K bit-times
- * 10 = 32K bit-times
- * 11 = 48K bit-times
- * 06:02 JAM_IPG Five bits to determine the JAM IPG.
- * The step is four bit-times. The value may vary
- * between 4 bit time to 124.
- * 11:07 IPG_JAM_TO_DATA Five bits to determine the IPG JAM to DATA.
- * The step is four bit-times. The value may vary
- * between 4 bit time to 124.
- * 16:12 IPG_DATA Inter-Packet Gap (IPG)
- * The step is four bit-times. The value may vary
- * between 12 bit time to 124.
- * NOTE: These bits may be changed only when the
- * Ethernet ports is disabled.
- * 21:17 Data_Blind Data Blinder
- * The number of nibbles from the beginning of the
- * IPG, in which the IPG counter is restarted when
- * detecting a carrier activity. Following this
- * value, the port enters the Data Blinder zone and
- * does not reset the IPG counter. This ensures
- * fair access to the medium.
- * The default is 10 hex (64 bit times - 2/3 of the
- * default IPG). The step is 4 bit-times. Valid
- * range is 3 to 1F hex nibbles.
- * NOTE: These bits may be only changed when the
- * Ethernet port is disabled.
- * 22:22 Limit4 The number of consecutive packet collisions that
- * occur before the collision counter is reset.
- * 0: The port resets its collision counter after
- * 16 consecutive retransmit trials and
- * restarts the Backoff algorithm.
- * 1: The port resets its collision counter and
- * restarts the Backoff algorithm after 4
- * consecutive transmit trials.
- * 31:23 Reserved
- */
-#define ETH_ESPR_JAM_LENGTH_GET(v) ETH__EXT(v, 0, 2)
-#define ETH_ESPR_JAM_IPG_GET(v) ETH__EXT(v, 2, 5)
-#define ETH_ESPR_IPG_JAM_TO_DATA_GET(v) ETH__EXT(v, 7, 5)
-#define ETH_ESPR_IPG_DATA_GET(v) ETH__EXT(v, 12, 5)
-#define ETH_ESPR_Data_Bilnd_GET(v) ETH__EXT(v, 17, 5)
-#define ETH_ESPR_Limit4(v) ETH__BIT(22)
-
-/*
- * Table 602: Hash Table Pointer Register (HTPR)
- * 31:00 HTP 32-bit pointer to the address table.
- * Bits [2:0] must be set to zero.
- */
-
-/*
- * Table 603: Flow Control Source Address Low (FCSAL)
- * 15:0 SA[15:0] Source Address
- * The least significant bits of the source
- * address for the port. This address is used for
- * Flow Control.
- * 31:16 Reserved
- */
-
-/*
- * Table 604: Flow Control Source Address High (FCSAH)
- * 31:0 SA[47:16] Source Address
- * The most significant bits of the source address
- * for the port. This address is used for Flow
- * Control.
- */
-
-
-/*
- * Table 605: SDMA Configuration Register (SDCR)
- * 01:00 Reserved
- * 05:02 RC Retransmit Count
- * Sets the maximum number of retransmits per
- * packet. After executing retransmit for RC
- * times, the TX SDMA closes the descriptor with a
- * Retransmit Limit error indication and processes
- * the next packet. When RC is set to 0, the
- * number of retransmits is unlimited. In this
- * case, the retransmit process is only terminated
- * if CPU issues an Abort command.
- * 06:06 BLMR Big/Little Endian Receive Mode
- * The DMA supports Big or Little Endian
- * configurations on a per channel basis. The BLMR
- * bit only affects data transfer to memory.
- * 0: Big Endian
- * 1: Little Endian
- * 07:07 BLMT Big/Little Endian Transmit Mode
- * The DMA supports Big or Little Endian
- * configurations on a per channel basis. The BLMT
- * bit only affects data transfer from memory.
- * 0: Big Endian
- * 1: Little Endian
- * 08:08 POVR PCI Override
- * When set, causes the SDMA to direct all its
- * accesses in PCI_0 direction and overrides
- * normal address decoding process.
- * 09:09 RIFB Receive Interrupt on Frame Boundaries
- * When set, the SDMA Rx generates interrupts only
- * on frame boundaries (i.e. after writing the
- * frame status to the descriptor).
- * 11:10 Reserved
- * 13:12 BSZ Burst Size
- * Sets the maximum burst size for SDMA
- * transactions:
- * 00: Burst is limited to 1 64bit words.
- * 01: Burst is limited to 2 64bit words.
- * 10: Burst is limited to 4 64bit words.
- * 11: Burst is limited to 8 64bit words.
- * 31:14 Reserved
- */
-#define ETH_ESDCR_RC_GET(v) ETH__EXT(v, 2, 4)
-#define ETH_ESDCR_BLMR ETH__BIT(6)
-#define ETH_ESDCR_BLMT ETH__BIT(7)
-#define ETH_ESDCR_POVR ETH__BIT(8)
-#define ETH_ESDCR_RIFB ETH__BIT(9)
-#define ETH_ESDCR_BSZ_GET(v) ETH__EXT(v, 12, 2)
-#define ETH_ESDCR_BSZ_SET(v, n) (ETH__CLR(v, 12, 2),\
- (v) |= ETH__INS(n, 12))
-#define ETH_ESDCR_BSZ_1 0
-#define ETH_ESDCR_BSZ_2 1
-#define ETH_ESDCR_BSZ_4 2
-#define ETH_ESDCR_BSZ_8 3
-
-#define ETH_ESDCR_BSZ_Strings { "1 64-bit word", "2 64-bit words", \
- "4 64-bit words", "8 64-bit words" }
-
-/*
- * Table 606: SDMA Command Register (SDCMR)
- * 06:00 Reserved
- * 07:07 ERD Enable RX DMA.
- * Set to 1 by the CPU to cause the SDMA to start
- * a receive process. Cleared when the CPU issues
- * an Abort Receive command.
- * 14:08 Reserved
- * 15:15 AR Abort Receive
- * Set to 1 by the CPU to abort a receive SDMA
- * operation. When the AR bit is set, the SDMA
- * aborts its current operation and moves to IDLE.
- * No descriptor is closed. The AR bit is cleared
- * upon entering IDLE. After setting the AR bit,
- * the CPU must poll the bit to verify that the
- * abort sequence is completed.
- * 16:16 STDH Stop TX High
- * Set to 1 by the CPU to stop the transmission
- * process from the high priority queue at the end
- * of the current frame. An interrupt is generated
- * when the stop command has been executed.
- * Writing 1 to STDH resets TXDH bit.
- * Writing 0 to this bit has no effect.
- * 17:17 STDL Stop TX Low
- * Set to 1 by the CPU to stop the transmission
- * process from the low priority queue at the end
- * of the current frame. An interrupt is generated
- * when the stop command has been executed.
- * Writing 1 to STDL resets TXDL bit.
- * Writing 0 to this bit has no effect.
- * 22:18 Reserved
- * 23:23 TXDH Start Tx High
- * Set to 1 by the CPU to cause the SDMA to fetch
- * the first descriptor and start a transmit
- * process from the high priority Tx queue.
- * Writing 1 to TXDH resets STDH bit.
- * Writing 0 to this bit has no effect.
- * 24:24 TXDL Start Tx Low
- * Set to 1 by the CPU to cause the SDMA to fetch
- * the first descriptor and start a transmit
- * process from the low priority Tx queue.
- * Writing 1 to TXDL resets STDL bit.
- * Writing 0 to this bit has no effect.
- * 30:25 Reserved
- * 31:31 AT Abort Transmit
- * Set to 1 by the CPU to abort a transmit DMA
- * operation. When the AT bit is set, the SDMA
- * aborts its current operation and moves to IDLE.
- * No descriptor is closed. Cleared upon entering
- * IDLE. After setting AT bit, the CPU must poll
- * it in order to verify that the abort sequence
- * is completed.
- */
-#define ETH_ESDCMR_ERD ETH__BIT(7)
-#define ETH_ESDCMR_AR ETH__BIT(15)
-#define ETH_ESDCMR_STDH ETH__BIT(16)
-#define ETH_ESDCMR_STDL ETH__BIT(17)
-#define ETH_ESDCMR_TXDH ETH__BIT(23)
-#define ETH_ESDCMR_TXDL ETH__BIT(24)
-#define ETH_ESDCMR_AT ETH__BIT(31)
-
-/*
- * Table 607: Interrupt Cause Register (ICR)
- * 00:00 RxBuffer Rx Buffer Return
- * Indicates an Rx buffer returned to CPU ownership
- * or that the port finished reception of a Rx
- * frame in either priority queues.
- * NOTE: In order to get a Rx Buffer return per
- * priority queue, use bit 19:16. This bit is
- * set upon closing any Rx descriptor which
- * has its EI bit set. To limit the
- * interrupts to frame (rather than buffer)
- * boundaries, the user must set SDMA
- * Configuration register's RIFB bit. When
- * the RIFB bit is set, an interrupt
- * generates only upon closing the first
- * descriptor of a received packet, if this
- * descriptor has it EI bit set.
- * 01:01 Reserved
- * 02:02 TxBufferHigh Tx Buffer for High priority Queue
- * Indicates a Tx buffer returned to CPU ownership
- * or that the port finished transmission of a Tx
- * frame.
- * NOTE: This bit is set upon closing any Tx
- * descriptor which has its EI bit set. To
- * limit the interrupts to frame (rather than
- * buffer) boundaries, the user must set EI
- * only in the last descriptor.
- * 03:03 TxBufferLow Tx Buffer for Low Priority Queue
- * Indicates a Tx buffer returned to CPU ownership
- * or that the port finished transmission of a Tx
- * frame.
- * NOTE: This bit is set upon closing any Tx
- * descriptor which has its EI bit set. To
- * limit the interrupts to frame (rather than
- * buffer) boundaries, the user must set EI
- * only in the last descriptor.
- * 05:04 Reserved
- * 06:06 TxEndHigh Tx End for High Priority Queue
- * Indicates that the Tx DMA stopped processing the
- * high priority queue after stop command, or that
- * it reached the end of the high priority
- * descriptor chain.
- * 07:07 TxEndLow Tx End for Low Priority Queue
- * Indicates that the Tx DMA stopped processing the
- * low priority queue after stop command, or that
- * it reached the end of the low priority
- * descriptor chain.
- * 08:08 RxError Rx Resource Error
- * Indicates a Rx resource error event in one of
- * the priority queues.
- * NOTE: To get a Rx Resource Error Indication per
- * priority queue, use bit 23:20.
- * 09:09 Reserved
- * 10:10 TxErrorHigh Tx Resource Error for High Priority Queue
- * Indicates a Tx resource error event during
- * packet transmission from the high priority queue
- * 11:11 TxErrorLow Tx Resource Error for Low Priority Queue
- * Indicates a Tx resource error event during
- * packet transmission from the low priority queue
- * 12:12 RxOVR Rx Overrun
- * Indicates an overrun event that occurred during
- * reception of a packet.
- * 13:13 TxUdr Tx Underrun
- * Indicates an underrun event that occurred during
- * transmission of packet from either queue.
- * 15:14 Reserved
- * 16:16 RxBuffer-Queue[0] Rx Buffer Return in Priority Queue[0]
- * Indicates a Rx buffer returned to CPU ownership
- * or that the port completed reception of a Rx
- * frame in a receive priority queue[0]
- * 17:17 RxBuffer-Queue[1] Rx Buffer Return in Priority Queue[1]
- * Indicates a Rx buffer returned to CPU ownership
- * or that the port completed reception of a Rx
- * frame in a receive priority queue[1].
- * 18:18 RxBuffer-Queue[2] Rx Buffer Return in Priority Queue[2]
- * Indicates a Rx buffer returned to CPU ownership
- * or that the port completed reception of a Rx
- * frame in a receive priority queue[2].
- * 19:19 RxBuffer-Queue[3] Rx Buffer Return in Priority Queue[3]
- * Indicates a Rx buffer returned to CPU ownership
- * or that the port completed reception of a Rx
- * frame in a receive priority queue[3].
- * 20:20 RxError-Queue[0] Rx Resource Error in Priority Queue[0]
- * Indicates a Rx resource error event in receive
- * priority queue[0].
- * 21:21 RxError-Queue[1] Rx Resource Error in Priority Queue[1]
- * Indicates a Rx resource error event in receive
- * priority queue[1].
- * 22:22 RxError-Queue[2] Rx Resource Error in Priority Queue[2]
- * Indicates a Rx resource error event in receive
- * priority queue[2].
- * 23:23 RxError-Queue[3] Rx Resource Error in Priority Queue[3]
- * Indicates a Rx resource error event in receive
- * priority queue[3].
- * 27:24 Reserved
- * 28:29 MIIPhySTC MII PHY Status Change
- * Indicates a status change reported by the PHY
- * connected to this port. Set when the MII
- * management interface block identifies a change
- * in PHY's register 1.
- * 29:29 SMIdone SMI Command Done
- * Indicates that the SMI completed a MII
- * management command (either read or write) that
- * was initiated by the CPU writing to the SMI
- * register.
- * 30:30 Reserved
- * 31:31 EtherIntSum Ethernet Interrupt Summary
- * This bit is a logical OR of the (unmasked) bits
- * [30:04] in the Interrupt Cause register.
- */
-
-#define ETH_IR_RxBuffer ETH__BIT(0)
-#define ETH_IR_TxBufferHigh ETH__BIT(2)
-#define ETH_IR_TxBufferLow ETH__BIT(3)
-#define ETH_IR_TxEndHigh ETH__BIT(6)
-#define ETH_IR_TxEndLow ETH__BIT(7)
-#define ETH_IR_RxError ETH__BIT(8)
-#define ETH_IR_TxErrorHigh ETH__BIT(10)
-#define ETH_IR_TxErrorLow ETH__BIT(11)
-#define ETH_IR_RxOVR ETH__BIT(12)
-#define ETH_IR_TxUdr ETH__BIT(13)
-#define ETH_IR_RxBuffer_0 ETH__BIT(16)
-#define ETH_IR_RxBuffer_1 ETH__BIT(17)
-#define ETH_IR_RxBuffer_2 ETH__BIT(18)
-#define ETH_IR_RxBuffer_3 ETH__BIT(19)
-#define ETH_IR_RxBuffer_GET(v) ETH__EXT(v, 16, 4)
-#define ETH_IR_RxError_0 ETH__BIT(20)
-#define ETH_IR_RxError_1 ETH__BIT(21)
-#define ETH_IR_RxError_2 ETH__BIT(22)
-#define ETH_IR_RxError_3 ETH__BIT(23)
-#define ETH_IR_RxError_GET(v) ETH__EXT(v, 20, 4)
-#define ETH_IR_RxBits (ETH_IR_RxBuffer_0|\
- ETH_IR_RxBuffer_1|\
- ETH_IR_RxBuffer_2|\
- ETH_IR_RxBuffer_3|\
- ETH_IR_RxError_0|\
- ETH_IR_RxError_1|\
- ETH_IR_RxError_2|\
- ETH_IR_RxError_3)
-#define ETH_IR_MIIPhySTC ETH__BIT(28)
-#define ETH_IR_SMIdone ETH__BIT(29)
-#define ETH_IR_EtherIntSum ETH__BIT(31)
-#define ETH_IR_Summary ETH__BIT(31)
-
-/*
- * Table 608: Interrupt Mask Register (IMR)
- * 31:00 Various Mask bits for the Interrupt Cause register.
- */
-
-/*
- * Table 609: IP Differentiated Services CodePoint to Priority0 low (DSCP2P0L),
- * 31:00 Priority0_low The LSB priority bits for DSCP[31:0] entries.
- */
-
-/*
- * Table 610: IP Differentiated Services CodePoint to Priority0 high (DSCP2P0H)
- * 31:00 Priority0_high The LSB priority bits for DSCP[63:32] entries.
- */
-
-/*
- * Table 611: IP Differentiated Services CodePoint to Priority1 low (DSCP2P1L)
- * 31:00 Priority1_low The MSB priority bits for DSCP[31:0] entries.
- */
-
-/*
- * Table 612: IP Differentiated Services CodePoint to Priority1 high (DSCP2P1H)
- * 31:00 Priority1_high The MSB priority bit for DSCP[63:32] entries.
- */
-
-/*
- * Table 613: VLAN Priority Tag to Priority (VPT2P)
- * 07:00 Priority0 The LSB priority bits for VLAN Priority[7:0]
- * entries.
- * 15:08 Priority1 The MSB priority bits for VLAN Priority[7:0]
- * entries.
- * 31:16 Reserved
- */
-
-/* Address control registers -- these are offsets from the GT base
- * and NOT from the ethernet port base. <tss>
- */
-#define ETH_ACTL_0_LO 0xf200
-
-/* Enable hardware cache snooping;
- * Copyright Shuchen K. Feng <feng1@bnl.gov>, 2004
- */
-
-/* Ethernet address control (Low) snoop bits */
-#define RxBSnoopEn ETH__BIT(6) /* Rx buffer snoop enable,1=enable*/
-#define TxBSnoopEn ETH__BIT(14) /* Tx buffer snoop enable */
-#define RxDSnoopEn ETH__BIT(22) /* Rx descriptor snoop enable */
-#define TxDSnoopEn ETH__BIT(30) /* Tx descriptor snoop enable */
-
-#define ETH_ACTL_0_HI 0xf204
-/* Ethernet address control (High), snoop bits */
-#define HashSnoopEn ETH__BIT(6) /* Hash Table snoop enable */
-
-
-#define ETH_ACTL_1_LO 0xf220
-#define ETH_ACTL_1_HI 0xf224
-#define ETH_ACTL_2_LO 0xf240
-#define ETH_ACTL_2_HI 0xf244
-
-
-#endif /* _DEV_GTETHREG_H_ */
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/gtvar.h b/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/gtvar.h
deleted file mode 100644
index 00d72bfa3a..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/gtvar.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* $NetBSD: gtvar.h,v 1.7.4.1 2005/04/29 11:28:56 kent Exp $ */
-
-/*
- * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Allegro Networks, Inc., and Wasabi Systems, Inc.
- * 4. The name of Allegro Networks, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * 5. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
- * WASABI SYSTEMS, INC. ``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 EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
- * 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.
- */
-
-/*
- * gtvar.h -- placeholder for GT system controller driver
- */
-#ifndef _DISCOVERY_DEV_GTVAR_H_
-#define _DISCOVERY_DEV_GTVAR_H_
-
-#include <sys/systm.h>
-
-struct gt_softc {
-#ifndef __rtems__
- struct device gt_dev;
- bus_dma_tag_t gt_dmat;
- bus_space_tag_t gt_memt; /* the GT itself */
- bus_space_tag_t gt_pci0_memt; /* PCI0 mem space */
- bus_space_tag_t gt_pci0_iot; /* PCI0 i/o space */
- boolean_t gt_pci0_host; /* We're host on PCI0 if TRUE */
- bus_space_tag_t gt_pci1_memt; /* PCI1 mem space */
- bus_space_tag_t gt_pci1_iot; /* PCI1 i/o space */
- boolean_t gt_pci1_host; /* We're host on PCI1 if TRUE */
-
- bus_space_handle_t gt_memh; /* to access the GT registers */
-#else
- unsigned gt_memh;
-#endif
- int gt_childmask; /* what children are present */
-};
-
-#define GT_CHILDOK(gt, ga, cd, pos, max) \
- (((ga)->ga_unit) < (max) && \
- !((gt)->gt_childmask & (1 << (((ga)->ga_unit) + (pos)))) && \
- !strcmp((ga)->ga_name, (cd)->cd_name))
-
-#define GT_MPSCOK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 0, 2)
-#define GT_PCIOK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 2, 2)
-#define GT_ETHEROK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 4, 3)
-#define GT_OBIOOK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 7, 5)
-#define GT_I2COK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 12, 1)
-
-#define GT_CHILDFOUND(gt, ga, pos) \
- ((void)(((gt)->gt_childmask |= (1 << (((ga)->ga_unit) + (pos))))))
-
-#define GT_MPSCFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 0)
-#define GT_PCIFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 2)
-#define GT_ETHERFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 4)
-#define GT_OBIOFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 7)
-#define GT_I2CFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 12)
-
-#ifndef __rtems__
-struct gt_attach_args {
- const char *ga_name; /* class name of device */
- bus_dma_tag_t ga_dmat; /* dma tag */
- bus_space_tag_t ga_memt; /* GT bus space tag */
- bus_space_handle_t ga_memh; /* GT bus space handle */
- int ga_unit; /* instance of ga_name */
-};
-
-struct obio_attach_args {
- const char *oa_name; /* call name of device */
- bus_space_tag_t oa_memt; /* bus space tag */
- bus_addr_t oa_offset; /* offset (absolute) to device */
- bus_size_t oa_size; /* size (strided) of device */
- int oa_irq; /* irq */
-};
-#endif
-
-#ifdef _KERNEL
-#ifndef __rtems__
-#include "locators.h"
-#endif
-
-#ifdef DEBUG
-extern int gtpci_debug;
-#endif
-
-/*
- * Locators for GT private devices, as specified to config.
- */
-#define GT_UNK_UNIT GTCF_UNIT_DEFAULT /* wcarded 'function' */
-
-#define OBIO_UNK_OFFSET OBIOCF_OFFSET_DEFAULT /* wcarded 'offset' */
-
-#define OBIO_UNK_SIZE OBIOCF_SIZE_DEFAULT /* wcarded 'size' */
-
-#define OBIO_UNK_IRQ OBIOCF_IRQ_DEFAULT /* wcarded 'irq' */
-
-void gt_attach_common(struct gt_softc *);
-uint32_t gt_read_mpp(void);
-int gt_cfprint(void *, const char *);
-
-#ifndef __rtems__
-/* int gt_bs_extent_init(struct discovery_bus_space *, char *); AKB */
-int gt_mii_read(struct device *, struct device *, int, int);
-void gt_mii_write(struct device *, struct device *, int, int, int);
-int gtget_macaddr(struct gt_softc *,int, char *);
-
-void gt_watchdog_service(void);
-bus_addr_t gt_dma_phys_to_bus_mem(bus_dma_tag_t, bus_addr_t);
-bus_addr_t gt_dma_bus_mem_to_phys(bus_dma_tag_t, bus_addr_t);
-
-#define gt_read(gt,o) \
- bus_space_read_4((gt)->gt_memt, (gt)->gt_memh, (o))
-#define gt_write(gt,o,v) \
- bus_space_write_4((gt)->gt_memt, (gt)->gt_memh, (o), (v))
-#else
-#endif
-
-#if defined(__powerpc__)
-static __inline volatile int
-atomic_add(volatile int *p, int v)
-{
- int rv;
- int rtmp;
-
- __asm __volatile(
- "1: lwarx %0,0,%3\n"
- " add %1,%4,%0\n"
- " stwcx. %1,0,%3\n"
- " bne- 1b\n"
- " sync"
- : "=&r"(rv), "=&r"(rtmp), "=m"(*p)
- : "r"(p), "r"(v), "m"(*p)
- : "cc");
-
- return rv;
-}
-
-#endif /* __powerpc__ */
-
-#endif /* _KERNEL */
-
-#endif /* _DISCOVERY_DEV_GTVAR_H_ */
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfe.c b/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfe.c
deleted file mode 100644
index e642636d1e..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfe.c
+++ /dev/null
@@ -1,2642 +0,0 @@
-/* $NetBSD: if_gfe.c,v 1.13.8.1 2005/04/29 11:28:56 kent Exp $ */
-
-/*
- * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Copyright 2004: Enable hardware cache snooping. Kate Feng <feng1@bnl.gov>
- *
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Allegro Networks, Inc., and Wasabi Systems, Inc.
- * 4. The name of Allegro Networks, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * 5. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
- * WASABI SYSTEMS, INC. ``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 EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
- * 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.
- */
-
-/*
- * if_gfe.c -- GT ethernet MAC driver
- */
-
-/* Enable hardware cache snooping;
- * Copyright Shuchen K. Feng <feng1@bnl.gov>, 2004
- */
-
-#ifdef __rtems__
-#include "rtemscompat_defs.h"
-#include "../porting/rtemscompat.h"
-#include <string.h>
-#include <stdio.h>
-#include <inttypes.h>
-#endif
-
-#include <sys/cdefs.h>
-#ifndef __rtems__
-__KERNEL_RCSID(0, "$NetBSD: if_gfe.c,v 1.13.8.1 2005/04/29 11:28:56 kent Exp $");
-
-#include "opt_inet.h"
-#include "bpfilter.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/types.h>
-#ifndef __rtems__
-#include <sys/inttypes.h>
-#include <sys/queue.h>
-#endif
-
-#ifndef __rtems__
-#include <uvm/uvm_extern.h>
-
-#include <sys/callout.h>
-#include <sys/device.h>
-#endif
-#include <sys/errno.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#ifndef __rtems__
-#include <machine/bus.h>
-#endif
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#ifndef __rtems__
-#include <net/if_ether.h>
-#else
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <net/ethernet.h>
-#include <rtems/rtems_mii_ioctl.h>
-#endif
-
-#ifdef INET
-#include <netinet/in.h>
-#ifndef __rtems__
-#include <netinet/if_inarp.h>
-#endif
-#endif
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#endif
-
-#ifndef __rtems__
-#include <dev/mii/miivar.h>
-
-#include <dev/marvell/gtintrreg.h>
-#include <dev/marvell/gtethreg.h>
-
-#include <dev/marvell/gtvar.h>
-#include <dev/marvell/if_gfevar.h>
-#else
-#include <bsp/gtintrreg.h>
-#include <bsp/gtreg.h>
-#include "gtethreg.h"
-
-#include "gtvar.h"
-#include "if_gfevar.h"
-#include "../porting/rtemscompat1.h"
-#define ether_sprintf ether_sprintf_macro
-#endif
-
-#define GE_READ(sc, reg) \
- bus_space_read_4((sc)->sc_gt_memt, (sc)->sc_memh, ETH__ ## reg)
-#define GE_WRITE(sc, reg, v) \
- bus_space_write_4((sc)->sc_gt_memt, (sc)->sc_memh, ETH__ ## reg, (v))
-
-#define GT_READ(sc, reg) \
- bus_space_read_4((sc)->sc_gt_memt, (sc)->sc_gt_memh, reg)
-#define GT_WRITE(sc, reg, v) \
- bus_space_write_4((sc)->sc_gt_memt, (sc)->sc_gt_memh, reg, (v))
-
-#define GE_DEBUG
-#if 0
-#define GE_NOHASH
-#define GE_NORX
-#endif
-
-#ifdef GE_DEBUG
-#define GE_DPRINTF(sc, a) do \
- if ((sc)->sc_ec.ec_if.if_flags & IFF_DEBUG) \
- printf a; \
- while (0)
-#define GE_FUNC_ENTER(sc, func) GE_DPRINTF(sc, ("[" func))
-#define GE_FUNC_EXIT(sc, str) GE_DPRINTF(sc, (str "]"))
-#else
-#define GE_DPRINTF(sc, a) do { } while (0)
-#define GE_FUNC_ENTER(sc, func) do { } while (0)
-#define GE_FUNC_EXIT(sc, str) do { } while (0)
-#endif
-enum gfe_whack_op {
- GE_WHACK_START, GE_WHACK_RESTART,
- GE_WHACK_CHANGE, GE_WHACK_STOP
-};
-
-enum gfe_hash_op {
- GE_HASH_ADD, GE_HASH_REMOVE,
-};
-
-
-#if 1
-#define htogt32(a) htobe32(a)
-#define gt32toh(a) be32toh(a)
-#else
-#define htogt32(a) htole32(a)
-#define gt32toh(a) le32toh(a)
-#endif
-
-#ifdef __rtems__
-#define htobe32 htonl
-#define be32toh ntohl
-#endif
-
-#define GE_RXDSYNC(sc, rxq, n, ops) \
- bus_dmamap_sync((sc)->sc_dmat, (rxq)->rxq_desc_mem.gdm_map, \
- (n) * sizeof((rxq)->rxq_descs[0]), sizeof((rxq)->rxq_descs[0]), \
- (ops))
-#define GE_RXDPRESYNC(sc, rxq, n) \
- GE_RXDSYNC(sc, rxq, n, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
-#define GE_RXDPOSTSYNC(sc, rxq, n) \
- GE_RXDSYNC(sc, rxq, n, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
-
-#define GE_TXDSYNC(sc, txq, n, ops) \
- bus_dmamap_sync((sc)->sc_dmat, (txq)->txq_desc_mem.gdm_map, \
- (n) * sizeof((txq)->txq_descs[0]), sizeof((txq)->txq_descs[0]), \
- (ops))
-#define GE_TXDPRESYNC(sc, txq, n) \
- GE_TXDSYNC(sc, txq, n, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
-#define GE_TXDPOSTSYNC(sc, txq, n) \
- GE_TXDSYNC(sc, txq, n, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
-
-#define STATIC
-
-#ifndef __rtems__
-STATIC int gfe_match (struct device *, struct cfdata *, void *);
-STATIC void gfe_attach (struct device *, struct device *, void *);
-#else
-STATIC int gfe_probe (device_t);
-STATIC int gfe_attach (device_t);
-STATIC void gfe_init (void*);
-#endif
-
-STATIC int gfe_dmamem_alloc(struct gfe_softc *, struct gfe_dmamem *, int,
- size_t, int);
-STATIC void gfe_dmamem_free(struct gfe_softc *, struct gfe_dmamem *);
-
-#ifndef __rtems__
-STATIC int gfe_ifioctl (struct ifnet *, u_long, caddr_t);
-#else
-STATIC int gfe_ifioctl (struct ifnet *, ioctl_command_t, caddr_t);
-#endif
-STATIC void gfe_ifstart (struct ifnet *);
-STATIC void gfe_ifwatchdog (struct ifnet *);
-
-#ifndef __rtems__
-STATIC int gfe_mii_mediachange (struct ifnet *);
-STATIC void gfe_mii_mediastatus (struct ifnet *, struct ifmediareq *);
-STATIC int gfe_mii_read (struct device *, int, int);
-STATIC void gfe_mii_write (struct device *, int, int, int);
-STATIC void gfe_mii_statchg (struct device *);
-#endif
-
-STATIC void gfe_tick(void *arg);
-
-STATIC void gfe_tx_restart(void *);
-STATIC int gfe_tx_enqueue(struct gfe_softc *, enum gfe_txprio);
-STATIC uint32_t gfe_tx_done(struct gfe_softc *, enum gfe_txprio, uint32_t);
-STATIC void gfe_tx_cleanup(struct gfe_softc *, enum gfe_txprio, int);
-STATIC int gfe_tx_txqalloc(struct gfe_softc *, enum gfe_txprio);
-STATIC int gfe_tx_start(struct gfe_softc *, enum gfe_txprio);
-STATIC void gfe_tx_stop(struct gfe_softc *, enum gfe_whack_op);
-
-STATIC void gfe_rx_cleanup(struct gfe_softc *, enum gfe_rxprio);
-STATIC void gfe_rx_get(struct gfe_softc *, enum gfe_rxprio);
-STATIC int gfe_rx_prime(struct gfe_softc *);
-STATIC uint32_t gfe_rx_process(struct gfe_softc *, uint32_t, uint32_t);
-STATIC int gfe_rx_rxqalloc(struct gfe_softc *, enum gfe_rxprio);
-STATIC int gfe_rx_rxqinit(struct gfe_softc *, enum gfe_rxprio);
-STATIC void gfe_rx_stop(struct gfe_softc *, enum gfe_whack_op);
-
-STATIC int gfe_intr(void *);
-
-STATIC int gfe_whack(struct gfe_softc *, enum gfe_whack_op);
-
-STATIC int gfe_hash_compute(struct gfe_softc *, const uint8_t [ETHER_ADDR_LEN]);
-STATIC int gfe_hash_entry_op(struct gfe_softc *, enum gfe_hash_op,
- enum gfe_rxprio, const uint8_t [ETHER_ADDR_LEN]);
-#ifndef __rtems__
-STATIC int gfe_hash_multichg(struct ethercom *, const struct ether_multi *,
- u_long);
-#endif
-STATIC int gfe_hash_fill(struct gfe_softc *);
-STATIC int gfe_hash_alloc(struct gfe_softc *);
-
-#ifndef __rtems__
-/* Linkup to the rest of the kernel */
-CFATTACH_DECL(gfe, sizeof(struct gfe_softc),
- gfe_match, gfe_attach, NULL, NULL);
-#else
-net_drv_tbl_t METHODS = {
- n_probe : gfe_probe,
- n_attach : gfe_attach,
- n_detach : 0,
- n_intr : (void (*)(void*))gfe_intr,
-};
-
-int
-gfe_mii_read(int phy, void *arg, unsigned reg, uint32_t *pval);
-int
-gfe_mii_write(int phy, void *arg, unsigned reg, uint32_t val);
-
-struct rtems_mdio_info
-gfe_mdio_access = {
- mdio_r: gfe_mii_read,
- mdio_w: gfe_mii_write,
- has_gmii: 0
-};
-
-#endif
-
-extern struct cfdriver gfe_cd;
-
-#ifndef __rtems__
-int
-gfe_match(struct device *parent, struct cfdata *cf, void *aux)
-{
- struct gt_softc *gt = (struct gt_softc *) parent;
- struct gt_attach_args *ga = aux;
- uint8_t enaddr[6];
-
- if (!GT_ETHEROK(gt, ga, &gfe_cd))
- return 0;
-
- if (gtget_macaddr(gt, ga->ga_unit, enaddr) < 0)
- return 0;
-
- if (enaddr[0] == 0 && enaddr[1] == 0 && enaddr[2] == 0 &&
- enaddr[3] == 0 && enaddr[4] == 0 && enaddr[5] == 0)
- return 0;
-
- return 1;
-}
-#else
-int
-gfe_probe(device_t dev)
-{
- switch ( BSP_getDiscoveryVersion(0) ) {
- case GT_64260_A:
- case GT_64260_B:
- return 0;
- default:
- break;
- }
- return -1;
-}
-
-void
-gfe_init(void *arg)
-{
-struct gfe_softc *sc = arg;
- if ( sc->sc_ec.ec_if.if_flags & IFF_RUNNING )
- gfe_whack(sc, GE_WHACK_RESTART);
- else
- gfe_whack(sc, GE_WHACK_START);
-}
-#endif
-
-/*
- * Attach this instance, and then all the sub-devices
- */
-#ifndef __rtems__
-void
-gfe_attach(struct device *parent, struct device *self, void *aux)
-#else
-int
-gfe_attach(device_t dev)
-#endif
-{
-#ifndef __rtems__
- struct gt_attach_args * const ga = aux;
- struct gt_softc * const gt = (struct gt_softc *) parent;
- struct gfe_softc * const sc = (struct gfe_softc *) self;
-#else
- struct gfe_softc * const sc = device_get_softc(dev);
-#endif
- struct ifnet * const ifp = &sc->sc_ec.ec_if;
- uint32_t data;
- uint8_t enaddr[6];
- int phyaddr;
- uint32_t sdcr;
- int error;
-#ifdef __rtems__
- SPRINTFVARDECL;
-#endif
-
-#ifndef __rtems__
- GT_ETHERFOUND(gt, ga);
-
- sc->sc_gt_memt = ga->ga_memt;
- sc->sc_gt_memh = ga->ga_memh;
- sc->sc_dmat = ga->ga_dmat;
- sc->sc_macno = ga->ga_unit;
-
- if (bus_space_subregion(sc->sc_gt_memt, sc->sc_gt_memh,
- ETH_BASE(sc->sc_macno), ETH_SIZE, &sc->sc_memh)) {
- aprint_error(": failed to map registers\n");
- }
-
- callout_init(&sc->sc_co);
-#else
- /* sc_macno, irq_no and sc_gt_memh must be filled in by 'setup' */
-
- /* make ring sizes even numbers so that we have always multiple
- * cache lines (paranoia)
- */
- if ( (sc->num_rxdesc = dev->d_ifconfig->rbuf_count) & 1 )
- sc->num_rxdesc++;
- if ( 0 == sc->num_rxdesc )
- sc->num_rxdesc = 64;
-
- if ( (sc->num_txdesc = dev->d_ifconfig->xbuf_count) & 1 )
- sc->num_txdesc++;
- if ( 0 == sc->num_txdesc )
- sc->num_txdesc = 256;
-
- /* Enable hardware cache snooping;
- * Copyright Shuchen K. Feng <feng1@bnl.gov>, 2004
- */
- /* regs are eth0: 0xf200/0xf204, eth1 0xf220/0xf224, eth2: 0xf240/0xf244 */
- {
- uint32_t v;
- v = GT_READ(sc, ETH_ACTL_0_LO + (sc->sc_macno<<5));
- v |= RxBSnoopEn|TxBSnoopEn|RxDSnoopEn|TxDSnoopEn;
- GT_WRITE(sc, ETH_ACTL_0_LO + (sc->sc_macno<<5), v);
-
- v = GT_READ(sc, ETH_ACTL_0_HI + (sc->sc_macno<<5));
- v |= HashSnoopEn;
- GT_WRITE(sc, ETH_ACTL_0_HI + (sc->sc_macno<<5), v);
- }
-
-#endif
-
- data = bus_space_read_4(sc->sc_gt_memt, sc->sc_gt_memh, ETH_EPAR);
-#ifdef __rtems__
- sc->sc_phyaddr =
-#endif
- phyaddr = ETH_EPAR_PhyAD_GET(data, sc->sc_macno);
-
-#ifndef __rtems__
- gtget_macaddr(gt, sc->sc_macno, enaddr);
-#else
- memset( enaddr, 0, ETHER_ADDR_LEN );
- if ( !memcmp(enaddr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN) ) {
- aprint_error(": MAC address not set (pass to rtems_gfe_setup())\n");
- return -1;
- }
- /* mac address needs to be provided by 'setup' */
- memcpy(enaddr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
-#endif
-
- sc->sc_pcr = GE_READ(sc, EPCR);
- sc->sc_pcxr = GE_READ(sc, EPCXR);
- sc->sc_intrmask = GE_READ(sc, EIMR) | ETH_IR_MIIPhySTC;
-
- aprint_normal(": address %s", ether_sprintf(enaddr));
-
-#if defined(DEBUG)
- aprint_normal(", pcr %#x, pcxr %#x", sc->sc_pcr, sc->sc_pcxr);
-#endif
-
- sc->sc_pcxr &= ~ETH_EPCXR_PRIOrx_Override;
-#ifndef __rtems__
- if (sc->sc_dev.dv_cfdata->cf_flags & 1) {
- aprint_normal(", phy %d (rmii)", phyaddr);
- sc->sc_pcxr |= ETH_EPCXR_RMIIEn;
- } else
-#endif
- {
- aprint_normal(", phy %d (mii)", phyaddr);
- sc->sc_pcxr &= ~ETH_EPCXR_RMIIEn;
- }
-#ifndef __rtems__
- if (sc->sc_dev.dv_cfdata->cf_flags & 2)
- sc->sc_flags |= GE_NOFREE;
-#endif
- sc->sc_pcxr &= ~(3 << 14);
- sc->sc_pcxr |= (ETH_EPCXR_MFL_1536 << 14);
-
- if (sc->sc_pcr & ETH_EPCR_EN) {
- int tries = 1000;
- /*
- * Abort transmitter and receiver and wait for them to quiese
- */
- GE_WRITE(sc, ESDCMR, ETH_ESDCMR_AR|ETH_ESDCMR_AT);
- do {
- delay(100);
- } while (tries-- > 0 && (GE_READ(sc, ESDCMR) & (ETH_ESDCMR_AR|ETH_ESDCMR_AT)));
- }
-
- sc->sc_pcr &= ~(ETH_EPCR_EN | ETH_EPCR_RBM | ETH_EPCR_PM | ETH_EPCR_PBF);
-
-#if defined(DEBUG)
- aprint_normal(", pcr %#x, pcxr %#x", sc->sc_pcr, sc->sc_pcxr);
-#endif
-
- /*
- * Now turn off the GT. If it didn't quiese, too ***ing bad.
- */
- GE_WRITE(sc, EPCR, sc->sc_pcr);
-#ifndef __rtems__
- GE_WRITE(sc, EIMR, sc->sc_intrmask);
-#else
- GE_WRITE(sc, EICR, 0);
- GE_WRITE(sc, EIMR, 0);
-#endif
- sdcr = GE_READ(sc, ESDCR);
- ETH_ESDCR_BSZ_SET(sdcr, ETH_ESDCR_BSZ_4);
- sdcr |= ETH_ESDCR_RIFB;
- GE_WRITE(sc, ESDCR, sdcr);
- sc->sc_max_frame_length = 1536;
-
- aprint_normal("\n");
-#ifndef __rtems__
- sc->sc_mii.mii_ifp = ifp;
- sc->sc_mii.mii_readreg = gfe_mii_read;
- sc->sc_mii.mii_writereg = gfe_mii_write;
- sc->sc_mii.mii_statchg = gfe_mii_statchg;
-
- ifmedia_init(&sc->sc_mii.mii_media, 0, gfe_mii_mediachange,
- gfe_mii_mediastatus);
-
- mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, phyaddr,
- MII_OFFSET_ANY, MIIF_NOISOLATE);
- if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
- ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
- ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
- } else {
- ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
- }
-
- strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
-#else
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_mtu = ETHERMTU;
- ifp->if_output = ether_output;
- ifp->if_init = gfe_init;
- ifp->if_snd.ifq_maxlen = GE_TXDESC_MAX - 1;
- ifp->if_baudrate = 10000000;
-#endif
- ifp->if_softc = sc;
- /* ifp->if_mowner = &sc->sc_mowner; */
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-#if 0
- ifp->if_flags |= IFF_DEBUG;
-#endif
- ifp->if_ioctl = gfe_ifioctl;
- ifp->if_start = gfe_ifstart;
- ifp->if_watchdog = gfe_ifwatchdog;
-
- if (sc->sc_flags & GE_NOFREE) {
- error = gfe_rx_rxqalloc(sc, GE_RXPRIO_HI);
- if (!error)
- error = gfe_rx_rxqalloc(sc, GE_RXPRIO_MEDHI);
- if (!error)
- error = gfe_rx_rxqalloc(sc, GE_RXPRIO_MEDLO);
- if (!error)
- error = gfe_rx_rxqalloc(sc, GE_RXPRIO_LO);
- if (!error)
- error = gfe_tx_txqalloc(sc, GE_TXPRIO_HI);
- if (!error)
- error = gfe_hash_alloc(sc);
- if (error)
- aprint_error(
- "%s: failed to allocate resources: %d\n",
- ifp->if_xname, error);
- }
-
- if_attach(ifp);
-#ifndef __rtems__
- ether_ifattach(ifp, enaddr);
-#else
- ether_ifattach(ifp);
-#endif
-#if NBPFILTER > 0
- bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
-#endif
-#if NRND > 0
- rnd_attach_source(&sc->sc_rnd_source, self->dv_xname, RND_TYPE_NET, 0);
-#endif
-#ifndef __rtems__
- intr_establish(IRQ_ETH0 + sc->sc_macno, IST_LEVEL, IPL_NET,
- gfe_intr, sc);
-#else
- return 0;
-#endif
-}
-
-int
-gfe_dmamem_alloc(struct gfe_softc *sc, struct gfe_dmamem *gdm, int maxsegs,
- size_t size, int flags)
-{
- int error = 0;
- GE_FUNC_ENTER(sc, "gfe_dmamem_alloc");
-
- KASSERT(gdm->gdm_kva == NULL);
- gdm->gdm_size = size;
- gdm->gdm_maxsegs = maxsegs;
-
-#ifndef __rtems__
- error = bus_dmamem_alloc(sc->sc_dmat, gdm->gdm_size, PAGE_SIZE,
- gdm->gdm_size, gdm->gdm_segs, gdm->gdm_maxsegs, &gdm->gdm_nsegs,
- BUS_DMA_NOWAIT);
- if (error)
- goto fail;
-
- error = bus_dmamem_map(sc->sc_dmat, gdm->gdm_segs, gdm->gdm_nsegs,
- gdm->gdm_size, &gdm->gdm_kva, flags | BUS_DMA_NOWAIT);
- if (error)
- goto fail;
-
- error = bus_dmamap_create(sc->sc_dmat, gdm->gdm_size, gdm->gdm_nsegs,
- gdm->gdm_size, 0, BUS_DMA_ALLOCNOW|BUS_DMA_NOWAIT, &gdm->gdm_map);
- if (error)
- goto fail;
-
- error = bus_dmamap_load(sc->sc_dmat, gdm->gdm_map, gdm->gdm_kva,
- gdm->gdm_size, NULL, BUS_DMA_NOWAIT);
- if (error)
- goto fail;
-#else
- gdm->gdm_segs[0].ds_len = size;
-
- /* FIXME: probably we can relax the alignment */
- if ( ! ( gdm->gdm_unaligned_buf = malloc( size + PAGE_SIZE - 1, M_DEVBUF, M_NOWAIT ) ) )
- goto fail;
-
- gdm->gdm_map = gdm;
- gdm->gdm_nsegs = 1;
- gdm->gdm_kva = (caddr_t)(gdm->gdm_segs[0].ds_addr = _DO_ALIGN(gdm->gdm_unaligned_buf, PAGE_SIZE));
-#endif
-
- /* invalidate from cache */
- bus_dmamap_sync(sc->sc_dmat, gdm->gdm_map, 0, gdm->gdm_size,
- BUS_DMASYNC_PREREAD);
-fail:
- if (error) {
- gfe_dmamem_free(sc, gdm);
- GE_DPRINTF(sc, (":err=%d", error));
- }
- GE_DPRINTF(sc, (":kva=%p/%#x,map=%p,nsegs=%d,pa=%" PRIx32 "/%" PRIx32,
- gdm->gdm_kva, gdm->gdm_size, gdm->gdm_map, gdm->gdm_map->dm_nsegs,
- gdm->gdm_map->dm_segs->ds_addr, gdm->gdm_map->dm_segs->ds_len));
- GE_FUNC_EXIT(sc, "");
- return error;
-}
-
-void
-gfe_dmamem_free(struct gfe_softc *sc, struct gfe_dmamem *gdm)
-{
- GE_FUNC_ENTER(sc, "gfe_dmamem_free");
-#ifndef __rtems__
- if (gdm->gdm_map)
- bus_dmamap_destroy(sc->sc_dmat, gdm->gdm_map);
- if (gdm->gdm_kva)
- bus_dmamem_unmap(sc->sc_dmat, gdm->gdm_kva, gdm->gdm_size);
- if (gdm->gdm_nsegs > 0)
- bus_dmamem_free(sc->sc_dmat, gdm->gdm_segs, gdm->gdm_nsegs);
-#else
- if (gdm->gdm_nsegs > 0)
- free(gdm->gdm_unaligned_buf, M_DEVBUF);
-#endif
- gdm->gdm_map = NULL;
- gdm->gdm_kva = NULL;
- gdm->gdm_nsegs = 0;
- GE_FUNC_EXIT(sc, "");
-}
-
-#ifndef __rtems__
-int
-gfe_ifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-#else
-int
-gfe_ifioctl(struct ifnet *ifp, ioctl_command_t cmd, caddr_t data)
-#endif
-{
- struct gfe_softc * const sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *) data;
-#ifndef __rtems__
- struct ifaddr *ifa = (struct ifaddr *) data;
-#endif
- int s, error = 0;
-
- GE_FUNC_ENTER(sc, "gfe_ifioctl");
- s = splnet();
-
- switch (cmd) {
-#ifndef __rtems__
- case SIOCSIFADDR:
- ifp->if_flags |= IFF_UP;
- switch (ifa->ifa_addr->sa_family) {
-#ifdef INET
- case AF_INET:
- error = gfe_whack(sc, GE_WHACK_START);
- if (error == 0)
- arp_ifinit(ifp, ifa);
- break;
-#endif
- default:
- error = gfe_whack(sc, GE_WHACK_START);
- break;
- }
- break;
-#endif
-
- case SIOCSIFFLAGS:
- if ((sc->sc_ec.ec_if.if_flags & IFF_PROMISC) == 0)
- sc->sc_pcr &= ~ETH_EPCR_PM;
- else
- sc->sc_pcr |= ETH_EPCR_PM;
- switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
- case IFF_UP|IFF_RUNNING:/* active->active, update */
- error = gfe_whack(sc, GE_WHACK_CHANGE);
- break;
- case IFF_RUNNING: /* not up, so we stop */
- error = gfe_whack(sc, GE_WHACK_STOP);
- break;
- case IFF_UP: /* not running, so we start */
- error = gfe_whack(sc, GE_WHACK_START);
- break;
- case 0: /* idle->idle: do nothing */
- break;
- }
- break;
-
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- error = (cmd == SIOCADDMULTI)
- ? ether_addmulti(ifr, &sc->sc_ec)
- : ether_delmulti(ifr, &sc->sc_ec);
- if (error == ENETRESET) {
- if (ifp->if_flags & IFF_RUNNING)
-#if !defined(__rtems__)
- error = gfe_whack(sc, GE_WHACK_CHANGE);
-#else
- /* doing GE_WHACK_CHANGE seems wrong - that
- * doesn't do anything to the hash table.
- * Therefore we perform a stop/start sequence.
- */
- {
- error = gfe_whack(sc, GE_WHACK_STOP);
- if ( error )
- break;
- error = gfe_whack(sc, GE_WHACK_START);
- }
-#endif
- else
- error = 0;
- }
- break;
-
- case SIOCSIFMTU:
- if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
- error = EINVAL;
- break;
- }
- ifp->if_mtu = ifr->ifr_mtu;
- break;
-
- case SIOCSIFMEDIA:
- case SIOCGIFMEDIA:
-#ifndef __rtems__
- error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
-#else
- error = rtems_mii_ioctl(&gfe_mdio_access, sc, cmd, &ifr->ifr_media);
-#endif
- break;
-
- default:
-#ifndef __rtems__
- error = EINVAL;
-#else
- error = ether_ioctl(ifp, cmd, data);
-#endif
- break;
- }
- splx(s);
- GE_FUNC_EXIT(sc, "");
- return error;
-}
-
-void
-gfe_ifstart(struct ifnet *ifp)
-{
- struct gfe_softc * const sc = ifp->if_softc;
- struct mbuf *m;
-
- GE_FUNC_ENTER(sc, "gfe_ifstart");
-
- if ((ifp->if_flags & IFF_RUNNING) == 0) {
- GE_FUNC_EXIT(sc, "$");
- return;
- }
-
- for (;;) {
- IF_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL) {
- ifp->if_flags &= ~IFF_OACTIVE;
- GE_FUNC_EXIT(sc, "");
- return;
- }
-
- /*
- * No space in the pending queue? try later.
- */
- if (IF_QFULL(&sc->sc_txq[GE_TXPRIO_HI].txq_pendq))
- break;
-
- /*
- * Try to enqueue a mbuf to the device. If that fails, we
- * can always try to map the next mbuf.
- */
- IF_ENQUEUE(&sc->sc_txq[GE_TXPRIO_HI].txq_pendq, m);
- GE_DPRINTF(sc, (">"));
-#ifndef GE_NOTX
- (void) gfe_tx_enqueue(sc, GE_TXPRIO_HI);
-#endif
- }
-
- /*
- * Attempt to queue the mbuf for send failed.
- */
- IF_PREPEND(&ifp->if_snd, m);
- ifp->if_flags |= IFF_OACTIVE;
- GE_FUNC_EXIT(sc, "%%");
-}
-
-void
-gfe_ifwatchdog(struct ifnet *ifp)
-{
- struct gfe_softc * const sc = ifp->if_softc;
- struct gfe_txqueue * const txq = &sc->sc_txq[GE_TXPRIO_HI];
-
- GE_FUNC_ENTER(sc, "gfe_ifwatchdog");
- printf("%s: device timeout", sc->sc_dev.dv_xname);
- if (ifp->if_flags & IFF_RUNNING) {
- uint32_t curtxdnum = (bus_space_read_4(sc->sc_gt_memt, sc->sc_gt_memh, txq->txq_ectdp) - txq->txq_desc_busaddr) / sizeof(txq->txq_descs[0]);
- GE_TXDPOSTSYNC(sc, txq, txq->txq_fi);
- GE_TXDPOSTSYNC(sc, txq, curtxdnum);
- printf(" (fi=%d(%#" PRIx32 "),lo=%d,cur=%" PRIx32 "(%#" PRIx32 "),icm=%#" PRIx32 ") ",
- txq->txq_fi, txq->txq_descs[txq->txq_fi].ed_cmdsts,
- txq->txq_lo, curtxdnum, txq->txq_descs[curtxdnum].ed_cmdsts,
- GE_READ(sc, EICR));
- GE_TXDPRESYNC(sc, txq, txq->txq_fi);
- GE_TXDPRESYNC(sc, txq, curtxdnum);
- }
- printf("\n");
- ifp->if_oerrors++;
- (void) gfe_whack(sc, GE_WHACK_RESTART);
- GE_FUNC_EXIT(sc, "");
-}
-
-#ifdef __rtems__
-static struct mbuf *
-gfe_newbuf(struct mbuf *m)
-{
- if ( !m ) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if ( !m )
- return 0;
- MCLGET(m, M_DONTWAIT);
- if ( !(M_EXT & m->m_flags) ) {
- m_freem(m);
- return 0;
- }
- } else {
- m->m_data = m->m_ext.ext_buf;
- }
- m->m_len = m->m_pkthdr.len = MCLBYTES;
-#if 0
- m_adj(m, 2); /* so payload is 16-byte aligned */
-#endif
- return m;
-}
-#endif
-
-int
-gfe_rx_rxqalloc(struct gfe_softc *sc, enum gfe_rxprio rxprio)
-{
- struct gfe_rxqueue * const rxq = &sc->sc_rxq[rxprio];
- int error;
-
- GE_FUNC_ENTER(sc, "gfe_rx_rxqalloc");
- GE_DPRINTF(sc, ("(%d)", rxprio));
-
- error = gfe_dmamem_alloc(sc, &rxq->rxq_desc_mem, 1,
- GE_RXDESC_MEMSIZE, BUS_DMA_NOCACHE);
- if (error) {
- GE_FUNC_EXIT(sc, "!!");
- return error;
- }
-
-#ifndef __rtems__
- error = gfe_dmamem_alloc(sc, &rxq->rxq_buf_mem, GE_RXBUF_NSEGS,
- GE_RXBUF_MEMSIZE, 0);
-#else
- if ( ! (rxq->rxq_bufs = malloc( sizeof(*rxq->rxq_bufs) * GE_RXDESC_MAX, M_DEVBUF, M_NOWAIT ) ) ) {
- error = -1;
- } else {
- int i;
- for ( i = 0; i<GE_RXDESC_MAX; i++ ) {
- if ( !(rxq->rxq_bufs[i] = gfe_newbuf(0)) ) {
- fprintf(stderr,"gfe: Not enough mbuf clusters to initialize RX ring!\n");
- while (--i >=0 ) {
- m_freem(rxq->rxq_bufs[i]);
- }
- free(rxq->rxq_bufs, M_DEVBUF);
- rxq->rxq_bufs = 0;
- error = -1;
- break;
- }
- }
- }
-#endif
- if (error) {
- GE_FUNC_EXIT(sc, "!!!");
- return error;
- }
- GE_FUNC_EXIT(sc, "");
- return error;
-}
-
-int
-gfe_rx_rxqinit(struct gfe_softc *sc, enum gfe_rxprio rxprio)
-{
- struct gfe_rxqueue * const rxq = &sc->sc_rxq[rxprio];
- volatile struct gt_eth_desc *rxd;
-#ifndef __rtems__
- const bus_dma_segment_t *ds;
-#endif
- int idx;
- bus_addr_t nxtaddr;
-#ifndef __rtems__
- bus_size_t boff;
-#endif
-
- GE_FUNC_ENTER(sc, "gfe_rx_rxqinit");
- GE_DPRINTF(sc, ("(%d)", rxprio));
-
- if ((sc->sc_flags & GE_NOFREE) == 0) {
- int error = gfe_rx_rxqalloc(sc, rxprio);
- if (error) {
- GE_FUNC_EXIT(sc, "!");
- return error;
- }
- } else {
- KASSERT(rxq->rxq_desc_mem.gdm_kva != NULL);
-#ifndef __rtems__
- KASSERT(rxq->rxq_buf_mem.gdm_kva != NULL);
-#else
- KASSERT(rxq->rxq_bufs != NULL);
-#endif
- }
-
- memset(rxq->rxq_desc_mem.gdm_kva, 0, GE_RXDESC_MEMSIZE);
-
- rxq->rxq_descs =
- (volatile struct gt_eth_desc *) rxq->rxq_desc_mem.gdm_kva;
- rxq->rxq_desc_busaddr = rxq->rxq_desc_mem.gdm_map->dm_segs[0].ds_addr;
-#ifndef __rtems__
- rxq->rxq_bufs = (struct gfe_rxbuf *) rxq->rxq_buf_mem.gdm_kva;
-#endif
- rxq->rxq_fi = 0;
- rxq->rxq_active = GE_RXDESC_MAX;
- for (idx = 0, rxd = rxq->rxq_descs,
-#ifndef __rtems__
- boff = 0, ds = rxq->rxq_buf_mem.gdm_map->dm_segs,
-#endif
- nxtaddr = rxq->rxq_desc_busaddr + sizeof(*rxd);
- idx < GE_RXDESC_MAX;
- idx++, rxd++, nxtaddr += sizeof(*rxd)) {
-#ifndef __rtems__
- rxd->ed_lencnt = htogt32(GE_RXBUF_SIZE << 16);
-#else
- rxd->ed_lencnt = htogt32(MCLBYTES << 16);
-#endif
- rxd->ed_cmdsts = htogt32(RX_CMD_F|RX_CMD_L|RX_CMD_O|RX_CMD_EI);
-#ifndef __rtems__
- rxd->ed_bufptr = htogt32(ds->ds_addr + boff);
-#else
- rxd->ed_bufptr = htogt32(mtod(rxq->rxq_bufs[idx], uint32_t));
-#endif
- /*
- * update the nxtptr to point to the next txd.
- */
- if (idx == GE_RXDESC_MAX - 1)
- nxtaddr = rxq->rxq_desc_busaddr;
- rxd->ed_nxtptr = htogt32(nxtaddr);
-#ifndef __rtems__
- boff += GE_RXBUF_SIZE;
- if (boff == ds->ds_len) {
- ds++;
- boff = 0;
- }
-#endif
- }
- bus_dmamap_sync(sc->sc_dmat, rxq->rxq_desc_mem.gdm_map, 0,
- rxq->rxq_desc_mem.gdm_map->dm_mapsize,
- BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-#ifndef __rtems__
- bus_dmamap_sync(sc->sc_dmat, rxq->rxq_buf_mem.gdm_map, 0,
- rxq->rxq_buf_mem.gdm_map->dm_mapsize,
- BUS_DMASYNC_PREREAD);
-#else
- /* FIXME: we leave this call in here so compilation fails
- * if bus_dmamap_sync() is ever fleshed-out to implement
- * software cache coherency...
- */
- bus_dmamap_sync(sc->sc_dmat, rxq->rxq_buf_mem.gdm_map, 0,
- rxq->rxq_buf_mem.gdm_map->dm_mapsize,
- BUS_DMASYNC_PREREAD);
-#endif
-
- rxq->rxq_intrbits = ETH_IR_RxBuffer|ETH_IR_RxError;
- switch (rxprio) {
- case GE_RXPRIO_HI:
- rxq->rxq_intrbits |= ETH_IR_RxBuffer_3|ETH_IR_RxError_3;
- rxq->rxq_efrdp = ETH_EFRDP3(sc->sc_macno);
- rxq->rxq_ecrdp = ETH_ECRDP3(sc->sc_macno);
- break;
- case GE_RXPRIO_MEDHI:
- rxq->rxq_intrbits |= ETH_IR_RxBuffer_2|ETH_IR_RxError_2;
- rxq->rxq_efrdp = ETH_EFRDP2(sc->sc_macno);
- rxq->rxq_ecrdp = ETH_ECRDP2(sc->sc_macno);
- break;
- case GE_RXPRIO_MEDLO:
- rxq->rxq_intrbits |= ETH_IR_RxBuffer_1|ETH_IR_RxError_1;
- rxq->rxq_efrdp = ETH_EFRDP1(sc->sc_macno);
- rxq->rxq_ecrdp = ETH_ECRDP1(sc->sc_macno);
- break;
- case GE_RXPRIO_LO:
- rxq->rxq_intrbits |= ETH_IR_RxBuffer_0|ETH_IR_RxError_0;
- rxq->rxq_efrdp = ETH_EFRDP0(sc->sc_macno);
- rxq->rxq_ecrdp = ETH_ECRDP0(sc->sc_macno);
- break;
- }
- GE_FUNC_EXIT(sc, "");
- return 0;
-}
-
-void
-gfe_rx_get(struct gfe_softc *sc, enum gfe_rxprio rxprio)
-{
- struct ifnet * const ifp = &sc->sc_ec.ec_if;
- struct gfe_rxqueue * const rxq = &sc->sc_rxq[rxprio];
-#ifndef __rtems__
- struct mbuf *m = rxq->rxq_curpkt;
-#else
- struct mbuf *m;
-#endif
-
- GE_FUNC_ENTER(sc, "gfe_rx_get");
- GE_DPRINTF(sc, ("(%d)", rxprio));
-
- while (rxq->rxq_active > 0) {
- volatile struct gt_eth_desc *rxd = &rxq->rxq_descs[rxq->rxq_fi];
-#ifndef __rtems__
- struct gfe_rxbuf *rxb = &rxq->rxq_bufs[rxq->rxq_fi];
-#else
- struct mbuf **rxb = &rxq->rxq_bufs[rxq->rxq_fi];
-#endif
- const struct ether_header *eh;
- unsigned int cmdsts;
- size_t buflen;
-
- GE_RXDPOSTSYNC(sc, rxq, rxq->rxq_fi);
- cmdsts = gt32toh(rxd->ed_cmdsts);
- GE_DPRINTF(sc, (":%d=%#x", rxq->rxq_fi, cmdsts));
- rxq->rxq_cmdsts = cmdsts;
- /*
- * Sometimes the GE "forgets" to reset the ownership bit.
- * But if the length has been rewritten, the packet is ours
- * so pretend the O bit is set.
- */
- buflen = gt32toh(rxd->ed_lencnt) & 0xffff;
- if ((cmdsts & RX_CMD_O) && buflen == 0) {
- GE_RXDPRESYNC(sc, rxq, rxq->rxq_fi);
- break;
- }
-
- /*
- * If this is not a single buffer packet with no errors
- * or for some reason it's bigger than our frame size,
- * ignore it and go to the next packet.
- */
- if ((cmdsts & (RX_CMD_F|RX_CMD_L|RX_STS_ES)) !=
- (RX_CMD_F|RX_CMD_L) ||
- buflen > sc->sc_max_frame_length) {
- GE_DPRINTF(sc, ("!"));
- --rxq->rxq_active;
- ifp->if_ipackets++;
- ifp->if_ierrors++;
-
- *rxb = gfe_newbuf(*rxb);
- goto give_it_back;
- }
-
- /* CRC is included with the packet; trim it off. */
- buflen -= ETHER_CRC_LEN;
-
-#ifndef __rtems__
- if (m == NULL) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- GE_DPRINTF(sc, ("?"));
- break;
- }
- }
- if ((m->m_flags & M_EXT) == 0 && buflen > MHLEN - 2) {
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0) {
- GE_DPRINTF(sc, ("?"));
- break;
- }
- }
- m->m_data += 2;
- m->m_len = 0;
- m->m_pkthdr.len = 0;
- m->m_pkthdr.rcvif = ifp;
-#else
- if ( ! (m=gfe_newbuf(0)) ) {
- /* recycle old buffer */
- *rxb = gfe_newbuf(*rxb);
- goto give_it_back;
- }
- /* swap mbufs */
- {
- struct mbuf *tmp = *rxb;
- *rxb = m;
- m = tmp;
- rxd->ed_bufptr = htogt32(mtod(*rxb, uint32_t));
- }
-#endif
- rxq->rxq_cmdsts = cmdsts;
- --rxq->rxq_active;
-
-#ifdef __rtems__
- /* FIXME: we leave this call in here so compilation fails
- * if bus_dmamap_sync() is ever fleshed-out to implement
- * software cache coherency...
- */
- bus_dmamap_sync(sc->sc_dmat, rxq->rxq_buf_mem.gdm_map,
- rxq->rxq_fi * sizeof(*rxb), buflen, BUS_DMASYNC_POSTREAD);
-#else
- bus_dmamap_sync(sc->sc_dmat, rxq->rxq_buf_mem.gdm_map,
- rxq->rxq_fi * sizeof(*rxb), buflen, BUS_DMASYNC_POSTREAD);
-
- KASSERT(m->m_len == 0 && m->m_pkthdr.len == 0);
- memcpy(m->m_data + m->m_len, rxb->rb_data, buflen);
-#endif
-
- m->m_len = buflen;
- m->m_pkthdr.len = buflen;
-
- ifp->if_ipackets++;
-#if NBPFILTER > 0
- if (ifp->if_bpf != NULL)
- bpf_mtap(ifp->if_bpf, m);
-#endif
-
- eh = (const struct ether_header *) m->m_data;
- if ((ifp->if_flags & IFF_PROMISC) ||
- (rxq->rxq_cmdsts & RX_STS_M) == 0 ||
- (rxq->rxq_cmdsts & RX_STS_HE) ||
- (eh->ether_dhost[0] & 1) != 0 ||
- memcmp(eh->ether_dhost,
-#ifndef __rtems__
- LLADDR(ifp->if_sadl),
-#else
- sc->sc_ec.ac_enaddr,
-#endif
- ETHER_ADDR_LEN) == 0) {
-#ifndef __rtems__
- (*ifp->if_input)(ifp, m);
- m = NULL;
-#else
- DO_ETHER_INPUT_SKIPPING_ETHER_HEADER(ifp,m);
-#endif
- GE_DPRINTF(sc, (">"));
- } else {
-#ifndef __rtems__
- m->m_len = 0;
- m->m_pkthdr.len = 0;
-#else
- m_freem(m);
-#endif
- GE_DPRINTF(sc, ("+"));
- }
- rxq->rxq_cmdsts = 0;
-
- give_it_back:
- rxd->ed_lencnt &= ~0xffff; /* zero out length */
- rxd->ed_cmdsts = htogt32(RX_CMD_F|RX_CMD_L|RX_CMD_O|RX_CMD_EI);
-#if 0
- GE_DPRINTF(sc, ("([%d]->%08lx.%08lx.%08lx.%08lx)",
- rxq->rxq_fi,
- ((unsigned long *)rxd)[0], ((unsigned long *)rxd)[1],
- ((unsigned long *)rxd)[2], ((unsigned long *)rxd)[3]));
-#endif
- GE_RXDPRESYNC(sc, rxq, rxq->rxq_fi);
- if (++rxq->rxq_fi == GE_RXDESC_MAX)
- rxq->rxq_fi = 0;
- rxq->rxq_active++;
- }
-#ifndef __rtems__
- rxq->rxq_curpkt = m;
-#endif
- GE_FUNC_EXIT(sc, "");
-}
-
-uint32_t
-gfe_rx_process(struct gfe_softc *sc, uint32_t cause, uint32_t intrmask)
-{
- struct ifnet * const ifp = &sc->sc_ec.ec_if;
- struct gfe_rxqueue *rxq;
- uint32_t rxbits;
-#define RXPRIO_DECODER 0xffffaa50
- GE_FUNC_ENTER(sc, "gfe_rx_process");
-
- rxbits = ETH_IR_RxBuffer_GET(cause);
- while (rxbits) {
- enum gfe_rxprio rxprio = (RXPRIO_DECODER >> (rxbits * 2)) & 3;
- GE_DPRINTF(sc, ("%1" PRIx32, rxbits));
- rxbits &= ~(1 << rxprio);
- gfe_rx_get(sc, rxprio);
- }
-
- rxbits = ETH_IR_RxError_GET(cause);
- while (rxbits) {
- enum gfe_rxprio rxprio = (RXPRIO_DECODER >> (rxbits * 2)) & 3;
- uint32_t masks[(GE_RXDESC_MAX + 31) / 32];
- int idx;
- rxbits &= ~(1 << rxprio);
- rxq = &sc->sc_rxq[rxprio];
- sc->sc_idlemask |= (rxq->rxq_intrbits & ETH_IR_RxBits);
- intrmask &= ~(rxq->rxq_intrbits & ETH_IR_RxBits);
- if ((sc->sc_tickflags & GE_TICK_RX_RESTART) == 0) {
- sc->sc_tickflags |= GE_TICK_RX_RESTART;
- callout_reset(&sc->sc_co, 1, gfe_tick, sc);
- }
- ifp->if_ierrors++;
- GE_DPRINTF(sc, ("%s: rx queue %d filled at %u\n",
- sc->sc_dev.dv_xname, rxprio, rxq->rxq_fi));
- memset(masks, 0, sizeof(masks));
- bus_dmamap_sync(sc->sc_dmat, rxq->rxq_desc_mem.gdm_map,
- 0, rxq->rxq_desc_mem.gdm_size,
- BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
- for (idx = 0; idx < GE_RXDESC_MAX; idx++) {
- volatile struct gt_eth_desc *rxd = &rxq->rxq_descs[idx];
-
- if (RX_CMD_O & gt32toh(rxd->ed_cmdsts))
- masks[idx/32] |= 1 << (idx & 31);
- }
- bus_dmamap_sync(sc->sc_dmat, rxq->rxq_desc_mem.gdm_map,
- 0, rxq->rxq_desc_mem.gdm_size,
- BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-#if defined(DEBUG)
- printf("%s: rx queue %d filled at %u=%#x(%#x/%#x)\n",
- sc->sc_dev.dv_xname, rxprio, rxq->rxq_fi,
- rxq->rxq_cmdsts, masks[0], masks[1]);
-#endif
- }
- if ((intrmask & ETH_IR_RxBits) == 0)
- intrmask &= ~(ETH_IR_RxBuffer|ETH_IR_RxError);
-
- GE_FUNC_EXIT(sc, "");
- return intrmask;
-}
-
-int
-gfe_rx_prime(struct gfe_softc *sc)
-{
- struct gfe_rxqueue *rxq;
- int error;
-
- GE_FUNC_ENTER(sc, "gfe_rx_prime");
-
- error = gfe_rx_rxqinit(sc, GE_RXPRIO_HI);
- if (error)
- goto bail;
- rxq = &sc->sc_rxq[GE_RXPRIO_HI];
- if ((sc->sc_flags & GE_RXACTIVE) == 0) {
- GE_WRITE(sc, EFRDP3, rxq->rxq_desc_busaddr);
- GE_WRITE(sc, ECRDP3, rxq->rxq_desc_busaddr);
- }
- sc->sc_intrmask |= rxq->rxq_intrbits;
-
- error = gfe_rx_rxqinit(sc, GE_RXPRIO_MEDHI);
- if (error)
- goto bail;
- if ((sc->sc_flags & GE_RXACTIVE) == 0) {
- rxq = &sc->sc_rxq[GE_RXPRIO_MEDHI];
- GE_WRITE(sc, EFRDP2, rxq->rxq_desc_busaddr);
- GE_WRITE(sc, ECRDP2, rxq->rxq_desc_busaddr);
- sc->sc_intrmask |= rxq->rxq_intrbits;
- }
-
- error = gfe_rx_rxqinit(sc, GE_RXPRIO_MEDLO);
- if (error)
- goto bail;
- if ((sc->sc_flags & GE_RXACTIVE) == 0) {
- rxq = &sc->sc_rxq[GE_RXPRIO_MEDLO];
- GE_WRITE(sc, EFRDP1, rxq->rxq_desc_busaddr);
- GE_WRITE(sc, ECRDP1, rxq->rxq_desc_busaddr);
- sc->sc_intrmask |= rxq->rxq_intrbits;
- }
-
- error = gfe_rx_rxqinit(sc, GE_RXPRIO_LO);
- if (error)
- goto bail;
- if ((sc->sc_flags & GE_RXACTIVE) == 0) {
- rxq = &sc->sc_rxq[GE_RXPRIO_LO];
- GE_WRITE(sc, EFRDP0, rxq->rxq_desc_busaddr);
- GE_WRITE(sc, ECRDP0, rxq->rxq_desc_busaddr);
- sc->sc_intrmask |= rxq->rxq_intrbits;
- }
-
- bail:
- GE_FUNC_EXIT(sc, "");
- return error;
-}
-
-void
-gfe_rx_cleanup(struct gfe_softc *sc, enum gfe_rxprio rxprio)
-{
- struct gfe_rxqueue *rxq = &sc->sc_rxq[rxprio];
- GE_FUNC_ENTER(sc, "gfe_rx_cleanup");
- if (rxq == NULL) {
- GE_FUNC_EXIT(sc, "");
- return;
- }
-
-#ifndef __rtems__
- if (rxq->rxq_curpkt)
- m_freem(rxq->rxq_curpkt);
-#endif
- if ((sc->sc_flags & GE_NOFREE) == 0) {
- gfe_dmamem_free(sc, &rxq->rxq_desc_mem);
-#ifndef __rtems__
- gfe_dmamem_free(sc, &rxq->rxq_buf_mem);
-#else
- if ( rxq->rxq_bufs ) {
- int i;
- for ( i=0; i<GE_RXDESC_MAX; i++ ) {
- if ( rxq->rxq_bufs[i] ) {
- m_freem(rxq->rxq_bufs[i]);
- }
- }
- free(rxq->rxq_bufs, M_DEVBUF);
- }
-#endif
- }
- GE_FUNC_EXIT(sc, "");
-}
-
-void
-gfe_rx_stop(struct gfe_softc *sc, enum gfe_whack_op op)
-{
- GE_FUNC_ENTER(sc, "gfe_rx_stop");
- sc->sc_flags &= ~GE_RXACTIVE;
- sc->sc_idlemask &= ~(ETH_IR_RxBits|ETH_IR_RxBuffer|ETH_IR_RxError);
- sc->sc_intrmask &= ~(ETH_IR_RxBits|ETH_IR_RxBuffer|ETH_IR_RxError);
- GE_WRITE(sc, EIMR, sc->sc_intrmask);
- GE_WRITE(sc, ESDCMR, ETH_ESDCMR_AR);
- do {
- delay(10);
- } while (GE_READ(sc, ESDCMR) & ETH_ESDCMR_AR);
- gfe_rx_cleanup(sc, GE_RXPRIO_HI);
- gfe_rx_cleanup(sc, GE_RXPRIO_MEDHI);
- gfe_rx_cleanup(sc, GE_RXPRIO_MEDLO);
- gfe_rx_cleanup(sc, GE_RXPRIO_LO);
- GE_FUNC_EXIT(sc, "");
-}
-
-void
-gfe_tick(void *arg)
-{
- struct gfe_softc * const sc = arg;
- uint32_t intrmask;
- unsigned int tickflags;
- int s;
-
- GE_FUNC_ENTER(sc, "gfe_tick");
-
- s = splnet();
-
- tickflags = sc->sc_tickflags;
- sc->sc_tickflags = 0;
- intrmask = sc->sc_intrmask;
- if (tickflags & GE_TICK_TX_IFSTART)
- gfe_ifstart(&sc->sc_ec.ec_if);
- if (tickflags & GE_TICK_RX_RESTART) {
- intrmask |= sc->sc_idlemask;
- if (sc->sc_idlemask & (ETH_IR_RxBuffer_3|ETH_IR_RxError_3)) {
- struct gfe_rxqueue *rxq = &sc->sc_rxq[GE_RXPRIO_HI];
- rxq->rxq_fi = 0;
- GE_WRITE(sc, EFRDP3, rxq->rxq_desc_busaddr);
- GE_WRITE(sc, ECRDP3, rxq->rxq_desc_busaddr);
- }
- if (sc->sc_idlemask & (ETH_IR_RxBuffer_2|ETH_IR_RxError_2)) {
- struct gfe_rxqueue *rxq = &sc->sc_rxq[GE_RXPRIO_MEDHI];
- rxq->rxq_fi = 0;
- GE_WRITE(sc, EFRDP2, rxq->rxq_desc_busaddr);
- GE_WRITE(sc, ECRDP2, rxq->rxq_desc_busaddr);
- }
- if (sc->sc_idlemask & (ETH_IR_RxBuffer_1|ETH_IR_RxError_1)) {
- struct gfe_rxqueue *rxq = &sc->sc_rxq[GE_RXPRIO_MEDLO];
- rxq->rxq_fi = 0;
- GE_WRITE(sc, EFRDP1, rxq->rxq_desc_busaddr);
- GE_WRITE(sc, ECRDP1, rxq->rxq_desc_busaddr);
- }
- if (sc->sc_idlemask & (ETH_IR_RxBuffer_0|ETH_IR_RxError_0)) {
- struct gfe_rxqueue *rxq = &sc->sc_rxq[GE_RXPRIO_LO];
- rxq->rxq_fi = 0;
- GE_WRITE(sc, EFRDP0, rxq->rxq_desc_busaddr);
- GE_WRITE(sc, ECRDP0, rxq->rxq_desc_busaddr);
- }
- sc->sc_idlemask = 0;
- }
- if (intrmask != sc->sc_intrmask) {
- sc->sc_intrmask = intrmask;
- GE_WRITE(sc, EIMR, sc->sc_intrmask);
- }
- gfe_intr(sc);
- splx(s);
-
- GE_FUNC_EXIT(sc, "");
-}
-
-static int
-gfe_free_slots(struct gfe_softc *sc, struct gfe_txqueue *const txq)
-{
- struct ifnet * const ifp = &sc->sc_ec.ec_if;
-#ifndef __rtems__
- const int dcache_line_size = curcpu()->ci_ci.dcache_line_size;
-#endif
- int got = 0;
- int fi = txq->txq_fi;
- volatile struct gt_eth_desc *txd = &txq->txq_descs[fi];
- uint32_t cmdsts;
-#ifndef __rtems__
- size_t pktlen;
-#endif
-
- GE_FUNC_ENTER(sc, "gfe_free_slots");
-
-#ifdef __rtems__
- do {
-#endif
- GE_TXDPOSTSYNC(sc, txq, fi);
- if ((cmdsts = gt32toh(txd->ed_cmdsts)) & TX_CMD_O) {
- int nextin;
-
- if (txq->txq_nactive == 1) {
- GE_TXDPRESYNC(sc, txq, fi);
- GE_FUNC_EXIT(sc, "");
- return -1;
- }
- /*
- * Sometimes the Discovery forgets to update the
- * ownership bit in the descriptor. See if we own the
- * descriptor after it (since we know we've turned
- * that to the Discovery and if we own it now then the
- * Discovery gave it back). If we do, we know the
- * Discovery gave back this one but forgot to mark it
- * as ours.
- */
- nextin = fi + 1;
- if (nextin == GE_TXDESC_MAX)
- nextin = 0;
- GE_TXDPOSTSYNC(sc, txq, nextin);
- if (gt32toh(txq->txq_descs[nextin].ed_cmdsts) & TX_CMD_O) {
- GE_TXDPRESYNC(sc, txq, fi);
- GE_TXDPRESYNC(sc, txq, nextin);
- GE_FUNC_EXIT(sc, "");
- return -1;
- }
-#ifdef DEBUG
- printf("%s: gfe_free_slots: transmitter resynced at %d\n",
- sc->sc_dev.dv_xname, fi);
-#endif
- }
- got++;
-#ifdef __rtems__
- txd++;
- fi++;
- } while ( ! ( TX_CMD_LAST & cmdsts ) );
-
- { struct mbuf *m;
- IF_DEQUEUE(&txq->txq_sentq, m);
- m_freem(m);
- }
-#endif
-#if 0
- GE_DPRINTF(sc, ("([%d]<-%08lx.%08lx.%08lx.%08lx)",
- txq->txq_lo,
- ((unsigned long *)txd)[0], ((unsigned long *)txd)[1],
- ((unsigned long *)txd)[2], ((unsigned long *)txd)[3]));
-#endif
- GE_DPRINTF(sc, ("(%d)", fi));
- txq->txq_fi = fi;
- if ( txq->txq_fi >= GE_TXDESC_MAX)
- txq->txq_fi -= GE_TXDESC_MAX;
-#ifndef __rtems__
- txq->txq_inptr = gt32toh(txd->ed_bufptr) - txq->txq_buf_busaddr;
- pktlen = (gt32toh(txd->ed_lencnt) >> 16) & 0xffff;
- bus_dmamap_sync(sc->sc_dmat, txq->txq_buf_mem.gdm_map,
- txq->txq_inptr, pktlen, BUS_DMASYNC_POSTWRITE);
- txq->txq_inptr += roundup(pktlen, dcache_line_size);
-#endif
-
- /* statistics */
- ifp->if_opackets++;
-#ifdef __rtems__
- /* FIXME: should we check errors on every fragment? */
-#endif
- if (cmdsts & TX_STS_ES)
- ifp->if_oerrors++;
-
- /* txd->ed_bufptr = 0; */
-
- txq->txq_nactive -= got;
-
- GE_FUNC_EXIT(sc, "");
-
- return got;
-}
-
-#ifndef __rtems__
-int
-gfe_tx_enqueue(struct gfe_softc *sc, enum gfe_txprio txprio)
-{
-#ifndef __rtems__
- const int dcache_line_size = curcpu()->ci_ci.dcache_line_size;
-#else
-#ifndef PPC_CACHE_ALIGNMENT
-#error "Unknown cache alignment for your CPU"
-#endif
- const int dcache_line_size = PPC_CACHE_ALIGNMENT;
-#endif
- struct ifnet * const ifp = &sc->sc_ec.ec_if;
- struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
- volatile struct gt_eth_desc * const txd = &txq->txq_descs[txq->txq_lo];
- uint32_t intrmask = sc->sc_intrmask;
- size_t buflen;
- struct mbuf *m;
-
- GE_FUNC_ENTER(sc, "gfe_tx_enqueue");
-
- /*
- * Anything in the pending queue to enqueue? if not, punt. Likewise
- * if the txq is not yet created.
- * otherwise grab its dmamap.
- */
- if (txq == NULL || (m = txq->txq_pendq.ifq_head) == NULL) {
- GE_FUNC_EXIT(sc, "-");
- return 0;
- }
-
- /*
- * Have we [over]consumed our limit of descriptors?
- * Do we have enough free descriptors?
- */
- if (GE_TXDESC_MAX == txq->txq_nactive + 2) {
- if ( gfe_free_slots(sc, txq) <= 0 )
- return 0;
- }
-
- buflen = roundup(m->m_pkthdr.len, dcache_line_size);
-
- /*
- * If this packet would wrap around the end of the buffer, reset back
- * to the beginning.
- */
- if (txq->txq_outptr + buflen > GE_TXBUF_SIZE) {
- txq->txq_ei_gapcount += GE_TXBUF_SIZE - txq->txq_outptr;
- txq->txq_outptr = 0;
- }
-
- /*
- * Make sure the output packet doesn't run over the beginning of
- * what we've already given the GT.
- */
- if (txq->txq_nactive > 0 && txq->txq_outptr <= txq->txq_inptr &&
- txq->txq_outptr + buflen > txq->txq_inptr) {
- intrmask |= txq->txq_intrbits &
- (ETH_IR_TxBufferHigh|ETH_IR_TxBufferLow);
- if (sc->sc_intrmask != intrmask) {
- sc->sc_intrmask = intrmask;
- GE_WRITE(sc, EIMR, sc->sc_intrmask);
- }
- GE_FUNC_EXIT(sc, "#");
- return 0;
- }
-
- /*
- * The end-of-list descriptor we put on last time is the starting point
- * for this packet. The GT is supposed to terminate list processing on
- * a NULL nxtptr but that currently is broken so a CPU-owned descriptor
- * must terminate the list.
- */
- intrmask = sc->sc_intrmask;
-
- m_copydata(m, 0, m->m_pkthdr.len,
- txq->txq_buf_mem.gdm_kva + txq->txq_outptr);
- bus_dmamap_sync(sc->sc_dmat, txq->txq_buf_mem.gdm_map,
- txq->txq_outptr, buflen, BUS_DMASYNC_PREWRITE);
- txd->ed_bufptr = htogt32(txq->txq_buf_busaddr + txq->txq_outptr);
- txd->ed_lencnt = htogt32(m->m_pkthdr.len << 16);
- GE_TXDPRESYNC(sc, txq, txq->txq_lo);
-
- /*
- * Request a buffer interrupt every 2/3 of the way thru the transmit
- * buffer.
- */
- txq->txq_ei_gapcount += buflen;
- if (txq->txq_ei_gapcount > 2 * GE_TXBUF_SIZE / 3) {
- txd->ed_cmdsts = htogt32(TX_CMD_FIRST|TX_CMD_LAST|TX_CMD_EI);
- txq->txq_ei_gapcount = 0;
- } else {
- txd->ed_cmdsts = htogt32(TX_CMD_FIRST|TX_CMD_LAST);
- }
-#if 0
- GE_DPRINTF(sc, ("([%d]->%08lx.%08lx.%08lx.%08lx)", txq->txq_lo,
- ((unsigned long *)txd)[0], ((unsigned long *)txd)[1],
- ((unsigned long *)txd)[2], ((unsigned long *)txd)[3]));
-#endif
- GE_TXDPRESYNC(sc, txq, txq->txq_lo);
-
- txq->txq_outptr += buflen;
- /*
- * Tell the SDMA engine to "Fetch!"
- */
- GE_WRITE(sc, ESDCMR,
- txq->txq_esdcmrbits & (ETH_ESDCMR_TXDH|ETH_ESDCMR_TXDL));
-
- GE_DPRINTF(sc, ("(%d)", txq->txq_lo));
-
- /*
- * Update the last out appropriately.
- */
- txq->txq_nactive++;
- if (++txq->txq_lo == GE_TXDESC_MAX)
- txq->txq_lo = 0;
-
- /*
- * Move mbuf from the pending queue to the snd queue.
- */
- IF_DEQUEUE(&txq->txq_pendq, m);
-#if NBPFILTER > 0
- if (ifp->if_bpf != NULL)
- bpf_mtap(ifp->if_bpf, m);
-#endif
- m_freem(m);
- ifp->if_flags &= ~IFF_OACTIVE;
-
- /*
- * Since we have put an item into the packet queue, we now want
- * an interrupt when the transmit queue finishes processing the
- * list. But only update the mask if needs changing.
- */
- intrmask |= txq->txq_intrbits & (ETH_IR_TxEndHigh|ETH_IR_TxEndLow);
- if (sc->sc_intrmask != intrmask) {
- sc->sc_intrmask = intrmask;
- GE_WRITE(sc, EIMR, sc->sc_intrmask);
- }
- if (ifp->if_timer == 0)
- ifp->if_timer = 5;
- GE_FUNC_EXIT(sc, "*");
- return 1;
-}
-
-#else
-
-#ifdef __PPC__
-static inline void membarrier(void)
-{
- asm volatile("sync":::"memory");
-}
-#else
-#error "memory synchronization for your CPU not implemented"
-#endif
-
-
-void
-gfe_assign_desc(volatile struct gt_eth_desc *const d, struct mbuf *m, uint32_t flags)
-{
- d->ed_cmdsts = htogt32(flags | TX_CMD_GC | TX_CMD_P);
- d->ed_bufptr = htogt32(mtod(m, uint32_t));
- d->ed_lencnt = htogt32(m->m_len << 16);
-}
-
-int
-gfe_tx_enqueue(struct gfe_softc *sc, enum gfe_txprio txprio)
-{
- struct ifnet * const ifp = &sc->sc_ec.ec_if;
- struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
- volatile struct gt_eth_desc * const txd = &txq->txq_descs[txq->txq_lo];
-#define NEXT_TXD(d) ((d)+1 < &txq->txq_descs[GE_TXDESC_MAX] ? (d)+1 : txq->txq_descs)
- volatile struct gt_eth_desc *l,*d;
- uint32_t intrmask = sc->sc_intrmask;
- struct mbuf *m_head,*m,*m1;
- int avail, used;
-
- GE_FUNC_ENTER(sc, "gfe_tx_enqueue");
-
- /*
- * Anything in the pending queue to enqueue? if not, punt. Likewise
- * if the txq is not yet created.
- * otherwise grab its dmamap.
- */
- if (txq == NULL || (m_head = txq->txq_pendq.ifq_head) == NULL) {
- GE_FUNC_EXIT(sc, "-");
- return 0;
- }
-
- /* find 1st mbuf with actual data; m_head is not NULL at this point */
- for ( m1=m_head; 0 == m1->m_len; ) {
- if ( ! (m1=m1->m_next) ) {
- /* nothing to send */
- IF_DEQUEUE(&txq->txq_pendq, m_head);
- m_freem(m_head);
- return 0;
- }
- }
-
- avail = GE_TXDESC_MAX - 1 - txq->txq_nactive;
-
- if ( avail < 1 && (avail += gfe_free_slots(sc, txq)) < 1 )
- return 0;
-
- avail--;
-
- l = txd;
- d = NEXT_TXD(txd);
-
- for ( m=m1->m_next, used = 1; m; m=m->m_next ) {
- if ( 0 == m->m_len )
- continue; /* skip empty mbufs */
-
- if ( avail < 1 && (avail += gfe_free_slots(sc, txq)) < 1 ) {
- /* not enough descriptors; cleanup */
- for ( l = NEXT_TXD(txd); l!=d; l = NEXT_TXD(l) ) {
- l->ed_cmdsts = 0;
- avail++;
- }
- avail++;
- if ( used >= GE_TXDESC_MAX-1 )
- panic("mbuf chain (#%i) longer than TX ring (#%i); configuration error!",
- used, GE_TXDESC_MAX-1);
- return 0;
- }
- used++;
- avail--;
-
- /* fill this slot */
- gfe_assign_desc(d, m, TX_CMD_O);
-
- bus_dmamap_sync(sc->sc_dmat, /* TODO */,
- mtod(m, uint32_t), m->m_len, BUS_DMASYNC_PREWRITE);
-
- l = d;
- d = NEXT_TXD(d);
-
- GE_TXDPRESYNC(sc, txq, l - txq->txq_descs);
- }
-
- /* fill first slot */
- gfe_assign_desc(txd, m1, TX_CMD_F);
-
- bus_dmamap_sync(sc->sc_dmat, /* TODO */,
- mtod(m1, uint32_t), m1->m_len, BUS_DMASYNC_PREWRITE);
-
- /* tag last slot; this covers where 1st = last */
- l->ed_cmdsts |= htonl(TX_CMD_L | TX_CMD_EI);
-
- GE_TXDPRESYNC(sc, txq, l - txq->txq_descs);
-
- /*
- * The end-of-list descriptor we put on last time is the starting point
- * for this packet. The GT is supposed to terminate list processing on
- * a NULL nxtptr but that currently is broken so a CPU-owned descriptor
- * must terminate the list.
- */
- d = NEXT_TXD(l);
-
- out_be32((uint32_t*)&d->ed_cmdsts,0);
-
- GE_TXDPRESYNC(sc, txq, d - txq->txq_descs);
-
- membarrier();
-
- /* turn over the whole chain by flipping the ownership of the first desc */
- txd->ed_cmdsts |= htonl(TX_CMD_O);
-
- GE_TXDPRESYNC(sc, txq, txq->txq_lo);
-
-
- intrmask = sc->sc_intrmask;
-
-#if 0
- GE_DPRINTF(sc, ("([%d]->%08lx.%08lx.%08lx.%08lx)", txq->txq_lo,
- ((unsigned long *)txd)[0], ((unsigned long *)txd)[1],
- ((unsigned long *)txd)[2], ((unsigned long *)txd)[3]));
-#endif
-
- membarrier();
-
- /*
- * Tell the SDMA engine to "Fetch!"
- */
- GE_WRITE(sc, ESDCMR,
- txq->txq_esdcmrbits & (ETH_ESDCMR_TXDH|ETH_ESDCMR_TXDL));
-
- GE_DPRINTF(sc, ("(%d)", txq->txq_lo));
-
- /*
- * Update the last out appropriately.
- */
- txq->txq_nactive += used;
- txq->txq_lo += used;
- if ( txq->txq_lo >= GE_TXDESC_MAX )
- txq->txq_lo -= GE_TXDESC_MAX;
-
- /*
- * Move mbuf from the pending queue to the snd queue.
- */
- IF_DEQUEUE(&txq->txq_pendq, m_head);
-
- IF_ENQUEUE(&txq->txq_sentq, m_head);
-
-#if NBPFILTER > 0
- if (ifp->if_bpf != NULL)
- bpf_mtap(ifp->if_bpf, m_head);
-#endif
- ifp->if_flags &= ~IFF_OACTIVE;
-
- /*
- * Since we have put an item into the packet queue, we now want
- * an interrupt when the transmit queue finishes processing the
- * list. But only update the mask if needs changing.
- */
- intrmask |= txq->txq_intrbits & (ETH_IR_TxEndHigh|ETH_IR_TxEndLow);
- if (sc->sc_intrmask != intrmask) {
- sc->sc_intrmask = intrmask;
- GE_WRITE(sc, EIMR, sc->sc_intrmask);
- }
- if (ifp->if_timer == 0)
- ifp->if_timer = 5;
- GE_FUNC_EXIT(sc, "*");
- return 1;
-}
-#endif
-
-uint32_t
-gfe_tx_done(struct gfe_softc *sc, enum gfe_txprio txprio, uint32_t intrmask)
-{
- struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
- struct ifnet * const ifp = &sc->sc_ec.ec_if;
-
- GE_FUNC_ENTER(sc, "gfe_tx_done");
-
- if (txq == NULL) {
- GE_FUNC_EXIT(sc, "");
- return intrmask;
- }
-
- while (txq->txq_nactive > 0) {
- if ( gfe_free_slots(sc, txq) < 0 )
- return intrmask;
- ifp->if_timer = 5;
- }
- if (txq->txq_nactive != 0)
- panic("%s: transmit fifo%d empty but active count (%d) not 0!",
- sc->sc_dev.dv_xname, txprio, txq->txq_nactive);
- ifp->if_timer = 0;
- intrmask &= ~(txq->txq_intrbits & (ETH_IR_TxEndHigh|ETH_IR_TxEndLow));
- intrmask &= ~(txq->txq_intrbits & (ETH_IR_TxBufferHigh|ETH_IR_TxBufferLow));
- GE_FUNC_EXIT(sc, "");
- return intrmask;
-}
-
-int
-gfe_tx_txqalloc(struct gfe_softc *sc, enum gfe_txprio txprio)
-{
- struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
- int error;
-
- GE_FUNC_ENTER(sc, "gfe_tx_txqalloc");
-
- error = gfe_dmamem_alloc(sc, &txq->txq_desc_mem, 1,
- GE_TXDESC_MEMSIZE, BUS_DMA_NOCACHE);
- if (error) {
- GE_FUNC_EXIT(sc, "");
- return error;
- }
-#ifndef __rtems__
- error = gfe_dmamem_alloc(sc, &txq->txq_buf_mem, 1, GE_TXBUF_SIZE, 0);
- if (error) {
- gfe_dmamem_free(sc, &txq->txq_desc_mem);
- GE_FUNC_EXIT(sc, "");
- return error;
- }
-#endif
- GE_FUNC_EXIT(sc, "");
- return 0;
-}
-
-int
-gfe_tx_start(struct gfe_softc *sc, enum gfe_txprio txprio)
-{
- struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
- volatile struct gt_eth_desc *txd;
- unsigned int i;
- bus_addr_t addr;
-
- GE_FUNC_ENTER(sc, "gfe_tx_start");
-
- sc->sc_intrmask &= ~(ETH_IR_TxEndHigh|ETH_IR_TxBufferHigh|
- ETH_IR_TxEndLow |ETH_IR_TxBufferLow);
-
- if (sc->sc_flags & GE_NOFREE) {
- KASSERT(txq->txq_desc_mem.gdm_kva != NULL);
-#ifndef __rtems__
- KASSERT(txq->txq_buf_mem.gdm_kva != NULL);
-#endif
- } else {
- int error = gfe_tx_txqalloc(sc, txprio);
- if (error) {
- GE_FUNC_EXIT(sc, "!");
- return error;
- }
- }
-
- txq->txq_descs =
- (volatile struct gt_eth_desc *) txq->txq_desc_mem.gdm_kva;
- txq->txq_desc_busaddr = txq->txq_desc_mem.gdm_map->dm_segs[0].ds_addr;
-#ifndef __rtems__
- txq->txq_buf_busaddr = txq->txq_buf_mem.gdm_map->dm_segs[0].ds_addr;
-#else
- /* never used */
- memset(&txq->txq_pendq,0,sizeof(txq->txq_pendq));
- memset(&txq->txq_sentq,0,sizeof(txq->txq_sentq));
- txq->txq_sentq.ifq_maxlen = 100000;
-#endif
-
- txq->txq_pendq.ifq_maxlen = 10;
-#ifndef __rtems__
- txq->txq_ei_gapcount = 0;
-#endif
- txq->txq_nactive = 0;
- txq->txq_fi = 0;
- txq->txq_lo = 0;
-#ifndef __rtems__
- txq->txq_ei_gapcount = 0;
- txq->txq_inptr = GE_TXBUF_SIZE;
- txq->txq_outptr = 0;
-#endif
- for (i = 0, txd = txq->txq_descs,
- addr = txq->txq_desc_busaddr + sizeof(*txd);
- i < GE_TXDESC_MAX - 1;
- i++, txd++, addr += sizeof(*txd)) {
- /*
- * update the nxtptr to point to the next txd.
- */
- txd->ed_cmdsts = 0;
- txd->ed_nxtptr = htogt32(addr);
- }
- txq->txq_descs[GE_TXDESC_MAX-1].ed_nxtptr =
- htogt32(txq->txq_desc_busaddr);
- bus_dmamap_sync(sc->sc_dmat, txq->txq_desc_mem.gdm_map, 0,
- GE_TXDESC_MEMSIZE, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-
- switch (txprio) {
- case GE_TXPRIO_HI:
- txq->txq_intrbits = ETH_IR_TxEndHigh|ETH_IR_TxBufferHigh;
- txq->txq_esdcmrbits = ETH_ESDCMR_TXDH;
- txq->txq_epsrbits = ETH_EPSR_TxHigh;
- txq->txq_ectdp = ETH_ECTDP1(sc->sc_macno);
- GE_WRITE(sc, ECTDP1, txq->txq_desc_busaddr);
- break;
-
- case GE_TXPRIO_LO:
- txq->txq_intrbits = ETH_IR_TxEndLow|ETH_IR_TxBufferLow;
- txq->txq_esdcmrbits = ETH_ESDCMR_TXDL;
- txq->txq_epsrbits = ETH_EPSR_TxLow;
- txq->txq_ectdp = ETH_ECTDP0(sc->sc_macno);
- GE_WRITE(sc, ECTDP0, txq->txq_desc_busaddr);
- break;
-
- case GE_TXPRIO_NONE:
- break;
- }
-#if 0
- GE_DPRINTF(sc, ("(ectdp=%#x", txq->txq_ectdp));
- gt_write(sc->sc_dev.dv_parent, txq->txq_ectdp, txq->txq_desc_busaddr);
- GE_DPRINTF(sc, (")"));
-#endif
-
- /*
- * If we are restarting, there may be packets in the pending queue
- * waiting to be enqueued. Try enqueuing packets from both priority
- * queues until the pending queue is empty or there no room for them
- * on the device.
- */
- while (gfe_tx_enqueue(sc, txprio))
- continue;
-
- GE_FUNC_EXIT(sc, "");
- return 0;
-}
-
-void
-gfe_tx_cleanup(struct gfe_softc *sc, enum gfe_txprio txprio, int flush)
-{
- struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
-
- GE_FUNC_ENTER(sc, "gfe_tx_cleanup");
- if (txq == NULL) {
- GE_FUNC_EXIT(sc, "");
- return;
- }
-
- if (!flush) {
- GE_FUNC_EXIT(sc, "");
- return;
- }
-
-#ifdef __rtems__
- /* reclaim mbufs that were never sent */
- {
- struct mbuf *m;
- while ( txq->txq_sentq.ifq_head ) {
- IF_DEQUEUE(&txq->txq_sentq, m);
- m_freem(m);
- }
- }
-#endif
-
- if ((sc->sc_flags & GE_NOFREE) == 0) {
- gfe_dmamem_free(sc, &txq->txq_desc_mem);
-#ifndef __rtems__
- gfe_dmamem_free(sc, &txq->txq_buf_mem);
-#endif
- }
- GE_FUNC_EXIT(sc, "-F");
-}
-
-void
-gfe_tx_stop(struct gfe_softc *sc, enum gfe_whack_op op)
-{
- GE_FUNC_ENTER(sc, "gfe_tx_stop");
-
- GE_WRITE(sc, ESDCMR, ETH_ESDCMR_STDH|ETH_ESDCMR_STDL);
-
- sc->sc_intrmask = gfe_tx_done(sc, GE_TXPRIO_HI, sc->sc_intrmask);
- sc->sc_intrmask = gfe_tx_done(sc, GE_TXPRIO_LO, sc->sc_intrmask);
- sc->sc_intrmask &= ~(ETH_IR_TxEndHigh|ETH_IR_TxBufferHigh|
- ETH_IR_TxEndLow |ETH_IR_TxBufferLow);
-
- gfe_tx_cleanup(sc, GE_TXPRIO_HI, op == GE_WHACK_STOP);
- gfe_tx_cleanup(sc, GE_TXPRIO_LO, op == GE_WHACK_STOP);
-
- sc->sc_ec.ec_if.if_timer = 0;
- GE_FUNC_EXIT(sc, "");
-}
-
-int
-gfe_intr(void *arg)
-{
- struct gfe_softc * const sc = arg;
- uint32_t cause;
- uint32_t intrmask = sc->sc_intrmask;
- int claim = 0;
- int cnt;
-
- GE_FUNC_ENTER(sc, "gfe_intr");
-
- for (cnt = 0; cnt < 4; cnt++) {
- if (sc->sc_intrmask != intrmask) {
- sc->sc_intrmask = intrmask;
- GE_WRITE(sc, EIMR, sc->sc_intrmask);
- }
- cause = GE_READ(sc, EICR);
- cause &= sc->sc_intrmask;
- GE_DPRINTF(sc, (".%#" PRIx32, cause));
- if (cause == 0)
- break;
-
- claim = 1;
-
- GE_WRITE(sc, EICR, ~cause);
-#ifndef GE_NORX
- if (cause & (ETH_IR_RxBuffer|ETH_IR_RxError))
- intrmask = gfe_rx_process(sc, cause, intrmask);
-#endif
-
-#ifndef GE_NOTX
- if (cause & (ETH_IR_TxBufferHigh|ETH_IR_TxEndHigh))
- intrmask = gfe_tx_done(sc, GE_TXPRIO_HI, intrmask);
- if (cause & (ETH_IR_TxBufferLow|ETH_IR_TxEndLow))
- intrmask = gfe_tx_done(sc, GE_TXPRIO_LO, intrmask);
-#endif
- if (cause & ETH_IR_MIIPhySTC) {
- sc->sc_flags |= GE_PHYSTSCHG;
- /* intrmask &= ~ETH_IR_MIIPhySTC; */
- }
- }
-
- while (gfe_tx_enqueue(sc, GE_TXPRIO_HI))
- continue;
- while (gfe_tx_enqueue(sc, GE_TXPRIO_LO))
- continue;
-
- GE_FUNC_EXIT(sc, "");
- return claim;
-}
-
-#ifndef __rtems__
-int
-gfe_mii_mediachange (struct ifnet *ifp)
-{
- struct gfe_softc *sc = ifp->if_softc;
-
- if (ifp->if_flags & IFF_UP)
- mii_mediachg(&sc->sc_mii);
-
- return (0);
-}
-void
-gfe_mii_mediastatus (struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct gfe_softc *sc = ifp->if_softc;
-
- if (sc->sc_flags & GE_PHYSTSCHG) {
- sc->sc_flags &= ~GE_PHYSTSCHG;
- mii_pollstat(&sc->sc_mii);
- }
- ifmr->ifm_status = sc->sc_mii.mii_media_status;
- ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-int
-gfe_mii_read (struct device *self, int phy, int reg)
-{
- return gt_mii_read(self, self->dv_parent, phy, reg);
-}
-
-void
-gfe_mii_write (struct device *self, int phy, int reg, int value)
-{
- gt_mii_write(self, self->dv_parent, phy, reg, value);
-}
-
-void
-gfe_mii_statchg (struct device *self)
-{
- /* struct gfe_softc *sc = (struct gfe_softc *) self; */
- /* do nothing? */
-}
-
-#else
-int
-gfe_mii_read(int phy, void *arg, unsigned reg, uint32_t *pval)
-{
- struct gfe_softc *sc = arg;
- uint32_t data;
- int count = 10000;
-
- if ( 0 != phy )
- return -1; /* invalid index */
-
- phy = sc->sc_phyaddr;
-
- do {
- DELAY(10);
- data = GT_READ(sc, ETH_ESMIR);
- } while ((data & ETH_ESMIR_Busy) && count-- > 0);
-
- if (count == 0) {
- fprintf(stderr,"%s: mii read for phy %d reg %d busied out\n",
- sc->sc_dev.dv_xname, phy, reg);
- *pval = ETH_ESMIR_Value_GET(data);
- return -1;
- }
-
- GT_WRITE(sc, ETH_ESMIR, ETH_ESMIR_READ(phy, reg));
-
- count = 10000;
- do {
- DELAY(10);
- data = GT_READ(sc, ETH_ESMIR);
- } while ((data & ETH_ESMIR_ReadValid) == 0 && count-- > 0);
-
- if (count == 0)
- printf("%s: mii read for phy %d reg %d timed out\n",
- sc->sc_dev.dv_xname, phy, reg);
-#if defined(GTMIIDEBUG)
- printf("%s: mii_read(%d, %d): %#x data %#x\n",
- sc->sc_dev.dv_xname, phy, reg,
- data, ETH_ESMIR_Value_GET(data));
-#endif
- *pval = ETH_ESMIR_Value_GET(data);
- return 0;
-}
-
-int
-gfe_mii_write(int phy, void *arg, unsigned reg, uint32_t value)
-{
- struct gfe_softc *sc = arg;
- uint32_t data;
- int count = 10000;
-
- if ( 0 != phy )
- return -1; /* invalid index */
-
- phy = sc->sc_phyaddr;
-
- do {
- DELAY(10);
- data = GT_READ(sc, ETH_ESMIR);
- } while ((data & ETH_ESMIR_Busy) && count-- > 0);
-
- if (count == 0) {
- fprintf(stderr, "%s: mii write for phy %d reg %d busied out (busy)\n",
- sc->sc_dev.dv_xname, phy, reg);
- return -1;
- }
-
- GT_WRITE(sc, ETH_ESMIR,
- ETH_ESMIR_WRITE(phy, reg, value));
-
- count = 10000;
- do {
- DELAY(10);
- data = GT_READ(sc, ETH_ESMIR);
- } while ((data & ETH_ESMIR_Busy) && count-- > 0);
-
- if (count == 0)
- printf("%s: mii write for phy %d reg %d timed out\n",
- sc->sc_dev.dv_xname, phy, reg);
-#if defined(GTMIIDEBUG)
- printf("%s: mii_write(%d, %d, %#x)\n",
- sc->sc_dev.dv_xname, phy, reg, value);
-#endif
- return 0;
-}
-
-#endif
-int
-gfe_whack(struct gfe_softc *sc, enum gfe_whack_op op)
-{
- int error = 0;
- GE_FUNC_ENTER(sc, "gfe_whack");
-
- switch (op) {
- case GE_WHACK_RESTART:
-#ifndef GE_NOTX
- gfe_tx_stop(sc, op);
-#endif
- /* sc->sc_ec.ec_if.if_flags &= ~IFF_RUNNING; */
- /* FALLTHROUGH */
- case GE_WHACK_START:
-#ifndef GE_NOHASH
- if (error == 0 && sc->sc_hashtable == NULL) {
- error = gfe_hash_alloc(sc);
- if (error)
- break;
- }
- if (op != GE_WHACK_RESTART)
- gfe_hash_fill(sc);
-#endif
-#ifndef GE_NORX
- if (op != GE_WHACK_RESTART) {
- error = gfe_rx_prime(sc);
- if (error)
- break;
- }
-#endif
-#ifndef GE_NOTX
- error = gfe_tx_start(sc, GE_TXPRIO_HI);
- if (error)
- break;
-#endif
- sc->sc_ec.ec_if.if_flags |= IFF_RUNNING;
- GE_WRITE(sc, EPCR, sc->sc_pcr | ETH_EPCR_EN);
- GE_WRITE(sc, EPCXR, sc->sc_pcxr);
- GE_WRITE(sc, EICR, 0);
- GE_WRITE(sc, EIMR, sc->sc_intrmask);
-#ifndef GE_NOHASH
- GE_WRITE(sc, EHTPR, sc->sc_hash_mem.gdm_map->dm_segs->ds_addr);
-#endif
-#ifndef GE_NORX
- GE_WRITE(sc, ESDCMR, ETH_ESDCMR_ERD);
- sc->sc_flags |= GE_RXACTIVE;
-#endif
- /* FALLTHROUGH */
- case GE_WHACK_CHANGE:
- GE_DPRINTF(sc, ("(pcr=%#" PRIx32 ",imr=%#" PRIx32 ")",
- GE_READ(sc, EPCR), GE_READ(sc, EIMR)));
- GE_WRITE(sc, EPCR, sc->sc_pcr | ETH_EPCR_EN);
- GE_WRITE(sc, EIMR, sc->sc_intrmask);
- gfe_ifstart(&sc->sc_ec.ec_if);
- GE_DPRINTF(sc, ("(ectdp0=%#" PRIx32 ", ectdp1=%#" PRIx32 ")",
- GE_READ(sc, ECTDP0), GE_READ(sc, ECTDP1)));
- GE_FUNC_EXIT(sc, "");
- return error;
- case GE_WHACK_STOP:
- break;
- }
-
-#ifdef GE_DEBUG
- if (error)
- GE_DPRINTF(sc, (" failed: %d\n", error));
-#endif
- GE_WRITE(sc, EPCR, sc->sc_pcr);
- GE_WRITE(sc, EIMR, 0);
- sc->sc_ec.ec_if.if_flags &= ~IFF_RUNNING;
-#ifndef GE_NOTX
- gfe_tx_stop(sc, GE_WHACK_STOP);
-#endif
-#ifndef GE_NORX
- gfe_rx_stop(sc, GE_WHACK_STOP);
-#endif
-#ifndef GE_NOHASH
- if ((sc->sc_flags & GE_NOFREE) == 0) {
- gfe_dmamem_free(sc, &sc->sc_hash_mem);
- sc->sc_hashtable = NULL;
- }
-#endif
-
- GE_FUNC_EXIT(sc, "");
- return error;
-}
-
-int
-gfe_hash_compute(struct gfe_softc *sc, const uint8_t eaddr[ETHER_ADDR_LEN])
-{
- uint32_t w0, add0, add1;
- uint32_t result;
-#ifdef __rtems__
- SPRINTFVARDECL;
-#endif
-
- GE_FUNC_ENTER(sc, "gfe_hash_compute");
- add0 = ((uint32_t) eaddr[5] << 0) |
- ((uint32_t) eaddr[4] << 8) |
- ((uint32_t) eaddr[3] << 16);
-
- add0 = ((add0 & 0x00f0f0f0) >> 4) | ((add0 & 0x000f0f0f) << 4);
- add0 = ((add0 & 0x00cccccc) >> 2) | ((add0 & 0x00333333) << 2);
- add0 = ((add0 & 0x00aaaaaa) >> 1) | ((add0 & 0x00555555) << 1);
-
- add1 = ((uint32_t) eaddr[2] << 0) |
- ((uint32_t) eaddr[1] << 8) |
- ((uint32_t) eaddr[0] << 16);
-
- add1 = ((add1 & 0x00f0f0f0) >> 4) | ((add1 & 0x000f0f0f) << 4);
- add1 = ((add1 & 0x00cccccc) >> 2) | ((add1 & 0x00333333) << 2);
- add1 = ((add1 & 0x00aaaaaa) >> 1) | ((add1 & 0x00555555) << 1);
-
- GE_DPRINTF(sc, ("%s=", ether_sprintf(eaddr)));
- /*
- * hashResult is the 15 bits Hash entry address.
- * ethernetADD is a 48 bit number, which is derived from the Ethernet
- * MAC address, by nibble swapping in every byte (i.e MAC address
- * of 0x123456789abc translates to ethernetADD of 0x21436587a9cb).
- */
-
- if ((sc->sc_pcr & ETH_EPCR_HM) == 0) {
- /*
- * hashResult[14:0] = hashFunc0(ethernetADD[47:0])
- *
- * hashFunc0 calculates the hashResult in the following manner:
- * hashResult[ 8:0] = ethernetADD[14:8,1,0]
- * XOR ethernetADD[23:15] XOR ethernetADD[32:24]
- */
- result = (add0 & 3) | ((add0 >> 6) & ~3);
- result ^= (add0 >> 15) ^ (add1 >> 0);
- result &= 0x1ff;
- /*
- * hashResult[14:9] = ethernetADD[7:2]
- */
- result |= (add0 & ~3) << 7; /* excess bits will be masked */
- GE_DPRINTF(sc, ("0(%#"PRIx32")", result & 0x7fff));
- } else {
-#define TRIBITFLIP 073516240 /* yes its in octal */
- /*
- * hashResult[14:0] = hashFunc1(ethernetADD[47:0])
- *
- * hashFunc1 calculates the hashResult in the following manner:
- * hashResult[08:00] = ethernetADD[06:14]
- * XOR ethernetADD[15:23] XOR ethernetADD[24:32]
- */
- w0 = ((add0 >> 6) ^ (add0 >> 15) ^ (add1)) & 0x1ff;
- /*
- * Now bitswap those 9 bits
- */
- result = 0;
- result |= ((TRIBITFLIP >> (((w0 >> 0) & 7) * 3)) & 7) << 6;
- result |= ((TRIBITFLIP >> (((w0 >> 3) & 7) * 3)) & 7) << 3;
- result |= ((TRIBITFLIP >> (((w0 >> 6) & 7) * 3)) & 7) << 0;
-
- /*
- * hashResult[14:09] = ethernetADD[00:05]
- */
- result |= ((TRIBITFLIP >> (((add0 >> 0) & 7) * 3)) & 7) << 12;
- result |= ((TRIBITFLIP >> (((add0 >> 3) & 7) * 3)) & 7) << 9;
- GE_DPRINTF(sc, ("1(%#"PRIx32")", result));
- }
- GE_FUNC_EXIT(sc, "");
- return result & ((sc->sc_pcr & ETH_EPCR_HS_512) ? 0x7ff : 0x7fff);
-}
-
-int
-gfe_hash_entry_op(struct gfe_softc *sc, enum gfe_hash_op op,
- enum gfe_rxprio prio, const uint8_t eaddr[ETHER_ADDR_LEN])
-{
- uint64_t he;
- uint64_t *maybe_he_p = NULL;
- int limit;
- int hash;
- int maybe_hash = 0;
-
- GE_FUNC_ENTER(sc, "gfe_hash_entry_op");
-
- hash = gfe_hash_compute(sc, eaddr);
-
- if (sc->sc_hashtable == NULL) {
- panic("%s:%d: hashtable == NULL!", sc->sc_dev.dv_xname,
- __LINE__);
- }
-
- /*
- * Assume we are going to insert so create the hash entry we
- * are going to insert. We also use it to match entries we
- * will be removing.
- */
- he = ((uint64_t) eaddr[5] << 43) |
- ((uint64_t) eaddr[4] << 35) |
- ((uint64_t) eaddr[3] << 27) |
- ((uint64_t) eaddr[2] << 19) |
- ((uint64_t) eaddr[1] << 11) |
- ((uint64_t) eaddr[0] << 3) |
- HSH_PRIO_INS(prio) | HSH_V | HSH_R;
-
- /*
- * The GT will search upto 12 entries for a hit, so we must mimic that.
- */
- hash &= sc->sc_hashmask / sizeof(he);
- for (limit = HSH_LIMIT; limit > 0 ; --limit) {
- /*
- * Does the GT wrap at the end, stop at the, or overrun the
- * end? Assume it wraps for now. Stash a copy of the
- * current hash entry.
- */
- uint64_t *he_p = &sc->sc_hashtable[hash];
- uint64_t thishe = *he_p;
-
- /*
- * If the hash entry isn't valid, that break the chain. And
- * this entry a good candidate for reuse.
- */
- if ((thishe & HSH_V) == 0) {
- maybe_he_p = he_p;
- break;
- }
-
- /*
- * If the hash entry has the same address we are looking for
- * then ... if we are removing and the skip bit is set, its
- * already been removed. if are adding and the skip bit is
- * clear, then its already added. In either return EBUSY
- * indicating the op has already been done. Otherwise flip
- * the skip bit and return 0.
- */
- if (((he ^ thishe) & HSH_ADDR_MASK) == 0) {
- if (((op == GE_HASH_REMOVE) && (thishe & HSH_S)) ||
- ((op == GE_HASH_ADD) && (thishe & HSH_S) == 0))
- return EBUSY;
- *he_p = thishe ^ HSH_S;
- bus_dmamap_sync(sc->sc_dmat, sc->sc_hash_mem.gdm_map,
- hash * sizeof(he), sizeof(he),
- BUS_DMASYNC_PREWRITE);
- GE_FUNC_EXIT(sc, "^");
- return 0;
- }
-
- /*
- * If we haven't found a slot for the entry and this entry
- * is currently being skipped, return this entry.
- */
- if (maybe_he_p == NULL && (thishe & HSH_S)) {
- maybe_he_p = he_p;
- maybe_hash = hash;
- }
-
- hash = (hash + 1) & (sc->sc_hashmask / sizeof(he));
- }
-
- /*
- * If we got here, then there was no entry to remove.
- */
- if (op == GE_HASH_REMOVE) {
- GE_FUNC_EXIT(sc, "?");
- return ENOENT;
- }
-
- /*
- * If we couldn't find a slot, return an error.
- */
- if (maybe_he_p == NULL) {
- GE_FUNC_EXIT(sc, "!");
- return ENOSPC;
- }
-
- /* Update the entry.
- */
- *maybe_he_p = he;
- bus_dmamap_sync(sc->sc_dmat, sc->sc_hash_mem.gdm_map,
- maybe_hash * sizeof(he), sizeof(he), BUS_DMASYNC_PREWRITE);
- GE_FUNC_EXIT(sc, "+");
- return 0;
-}
-
-#ifndef __rtems__
-int
-gfe_hash_multichg(struct ethercom *ec, const struct ether_multi *enm, u_long cmd)
-{
- struct gfe_softc * const sc = ec->ec_if.if_softc;
- int error;
- enum gfe_hash_op op;
- enum gfe_rxprio prio;
-#ifdef __rtems__
- SPRINTFVARDECL;
-#endif
-
- GE_FUNC_ENTER(sc, "hash_multichg");
- /*
- * Is this a wildcard entry? If so and its being removed, recompute.
- */
- if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
- if (cmd == SIOCDELMULTI) {
- GE_FUNC_EXIT(sc, "");
- return ENETRESET;
- }
-
- /*
- * Switch in
- */
- sc->sc_flags |= GE_ALLMULTI;
- if ((sc->sc_pcr & ETH_EPCR_PM) == 0) {
- sc->sc_pcr |= ETH_EPCR_PM;
- GE_WRITE(sc, EPCR, sc->sc_pcr);
- GE_FUNC_EXIT(sc, "");
- return 0;
- }
- GE_FUNC_EXIT(sc, "");
- return ENETRESET;
- }
-
- prio = GE_RXPRIO_MEDLO;
- op = (cmd == SIOCDELMULTI ? GE_HASH_REMOVE : GE_HASH_ADD);
-
- if (sc->sc_hashtable == NULL) {
- GE_FUNC_EXIT(sc, "");
- return 0;
- }
-
- error = gfe_hash_entry_op(sc, op, prio, enm->enm_addrlo);
- if (error == EBUSY) {
- printf("%s: multichg: tried to %s %s again\n",
- sc->sc_dev.dv_xname,
- cmd == SIOCDELMULTI ? "remove" : "add",
- ether_sprintf(enm->enm_addrlo));
- GE_FUNC_EXIT(sc, "");
- return 0;
- }
-
- if (error == ENOENT) {
- printf("%s: multichg: failed to remove %s: not in table\n",
- sc->sc_dev.dv_xname,
- ether_sprintf(enm->enm_addrlo));
- GE_FUNC_EXIT(sc, "");
- return 0;
- }
-
- if (error == ENOSPC) {
- printf("%s: multichg: failed to add %s: no space; regenerating table\n",
- sc->sc_dev.dv_xname,
- ether_sprintf(enm->enm_addrlo));
- GE_FUNC_EXIT(sc, "");
- return ENETRESET;
- }
- GE_DPRINTF(sc, ("%s: multichg: %s: %s succeeded\n",
- sc->sc_dev.dv_xname,
- cmd == SIOCDELMULTI ? "remove" : "add",
- ether_sprintf(enm->enm_addrlo)));
- GE_FUNC_EXIT(sc, "");
- return 0;
-}
-#endif
-
-int
-gfe_hash_fill(struct gfe_softc *sc)
-{
- struct ether_multistep step;
- struct ether_multi *enm;
- int error;
-
- GE_FUNC_ENTER(sc, "gfe_hash_fill");
-
-#ifndef __rtems__
- error = gfe_hash_entry_op(sc, GE_HASH_ADD, GE_RXPRIO_HI,
- LLADDR(sc->sc_ec.ec_if.if_sadl));
-#else
- error = gfe_hash_entry_op(sc, GE_HASH_ADD, GE_RXPRIO_HI, sc->sc_ec.ac_enaddr);
-#endif
- if (error) {
- GE_FUNC_EXIT(sc, "!");
- return error;
- }
-
- sc->sc_flags &= ~GE_ALLMULTI;
- if ((sc->sc_ec.ec_if.if_flags & IFF_PROMISC) == 0)
- sc->sc_pcr &= ~ETH_EPCR_PM;
- else
- sc->sc_pcr |= ETH_EPCR_PM;
- ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
- while (enm != NULL) {
- if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
- sc->sc_flags |= GE_ALLMULTI;
- sc->sc_pcr |= ETH_EPCR_PM;
- } else {
- error = gfe_hash_entry_op(sc, GE_HASH_ADD,
- GE_RXPRIO_MEDLO, enm->enm_addrlo);
- if (error == ENOSPC)
- break;
- }
- ETHER_NEXT_MULTI(step, enm);
- }
-
- GE_FUNC_EXIT(sc, "");
- return error;
-}
-
-int
-gfe_hash_alloc(struct gfe_softc *sc)
-{
- int error;
- GE_FUNC_ENTER(sc, "gfe_hash_alloc");
- sc->sc_hashmask = (sc->sc_pcr & ETH_EPCR_HS_512 ? 16 : 256)*1024 - 1;
- error = gfe_dmamem_alloc(sc, &sc->sc_hash_mem, 1, sc->sc_hashmask + 1,
- BUS_DMA_NOCACHE);
- if (error) {
- printf("%s: failed to allocate %d bytes for hash table: %d\n",
- sc->sc_dev.dv_xname, sc->sc_hashmask + 1, error);
- GE_FUNC_EXIT(sc, "");
- return error;
- }
- sc->sc_hashtable = (uint64_t *) sc->sc_hash_mem.gdm_kva;
- memset(sc->sc_hashtable, 0, sc->sc_hashmask + 1);
- bus_dmamap_sync(sc->sc_dmat, sc->sc_hash_mem.gdm_map,
- 0, sc->sc_hashmask + 1, BUS_DMASYNC_PREWRITE);
- GE_FUNC_EXIT(sc, "");
- return 0;
-}
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfe_rtems.c b/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfe_rtems.c
deleted file mode 100644
index 9ed814eb28..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfe_rtems.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* Author: T. Straumann <strauman@slac.stanford.edu>; see ../../LICENSE */
-#include "rtemscompat_defs.h"
-#include "../porting/rtemscompat.h"
-#include "gtethreg.h"
-
-#include <bsp/early_enet_link_status.h>
-#include <bsp/if_gfe_pub.h>
-#include <bsp/irq.h>
-
-/* from if_gfe.c */
-#define GE_READ(sc, reg) \
- bus_space_read_4((sc)->sc_gt_memt, (sc)->sc_memh, ETH__ ## reg)
-#define GE_WRITE(sc, reg, v) \
- bus_space_write_4((sc)->sc_gt_memt, (sc)->sc_memh, ETH__ ## reg, (v))
-
-#define GT_READ(sc, reg) \
- bus_space_read_4((sc)->sc_gt_memt, (sc)->sc_gt_memh, reg)
-#define GT_WRITE(sc, reg, v) \
- bus_space_write_4((sc)->sc_gt_memt, (sc)->sc_gt_memh, reg, (v))
-
-#include "../porting/if_xxx_rtems.c"
-
-#include <bsp.h>
-#include <libcpu/io.h>
-
-int
-NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_setup)(
- int unit,
- char *ea,
- uint32_t base_addr)
-{
-struct NET_SOFTC *sc;
-
- if ( !ea ) {
- fprintf(stderr,"Station address argument missing\n");
- return 0;
- }
-
- if ( !(sc=net_drv_check_unit(unit)) ) {
- fprintf(stderr,"Bad unit number -- (not enought driver slots?)\n");
- return 0;
- }
-
- unit--;
-
-#ifdef DEBUG_MODULAR
- if ( !METHODSPTR ) {
- fprintf(stderr,"Methods not set -- module not loaded?\n");
- return 0;
- }
-#endif
-
- if ( !base_addr ) {
-#ifdef BSP_MV64x60_BASE
- base_addr = BSP_MV64x60_BASE;
-#else
- fprintf(stderr,"Missing GT64260 base address\n");
- return 0;
-#endif
- }
- sc->sc_gt_memh = base_addr;
- /* must set this as well to indicate that the device is set up */
- sc->NET_SOFTC_BHANDLE_FIELD = base_addr + 0x2400 + (unit<<10);
- sc->sc_macno = unit;
- memcpy( sc->arpcom.ac_enaddr, ea, ETHER_ADDR_LEN);
-
- if ( 0 == METHODSPTR->n_probe(&THEDEVS[unit]) ) {
- printf(NETDRIVER": Unit %i set up\n", unit + 1);
- sc->irq_no = BSP_IRQ_ETH0 + unit;
- return 1;
- }
- return 0;
-}
-
-static int
-gfe_early_init(int idx)
-{
-struct gfe_softc *sc;
-uint32_t d;
-
- if ( idx < 0 || idx >= NETDRIVER_SLOTS )
- return -1;
-
- sc = device_get_softc(&the_gfe_devs[idx]);
- d = bus_space_read_4(sc->sc_gt_memt, sc->sc_gt_memh, ETH_EPAR);
-
- sc->sc_phyaddr = ETH_EPAR_PhyAD_GET(d, sc->sc_macno);
- sc->sc_dev.dv_xname = NETDRIVER;
- return 0;
-}
-
-static int
-gfe_early_read_phy(int idx, unsigned reg)
-{
-uint32_t rval;
-struct gfe_softc *sc;
-
- if ( idx < 0 || idx >= NETDRIVER_SLOTS )
- return -1;
-
- sc = device_get_softc(&the_gfe_devs[idx]);
-
- if ( gfe_mii_read( 0, sc, reg, &rval) )
- return -1;
- return rval & 0xffff;
-}
-
-
-static int
-gfe_early_write_phy(int idx, unsigned reg, unsigned val)
-{
-struct gfe_softc *sc;
-
- if ( idx < 0 || idx >= NETDRIVER_SLOTS )
- return -1;
-
- sc = device_get_softc(&the_gfe_devs[idx]);
-
- return gfe_mii_write( 0, sc, reg, val);
-}
-
-rtems_bsdnet_early_link_check_ops
-rtems_gfe_early_link_check_ops = {
- init: gfe_early_init,
- read_phy: gfe_early_read_phy,
- write_phy: gfe_early_write_phy,
- name: NETDRIVER,
- num_slots: NETDRIVER_SLOTS
-};
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfevar.h b/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfevar.h
deleted file mode 100644
index cbb9609cf8..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/if_gfevar.h
+++ /dev/null
@@ -1,225 +0,0 @@
-#ifndef IF_GFEVAR_H
-#define IF_GFEVAR_H
-/* $NetBSD: if_gfevar.h,v 1.4.10.1 2005/04/29 11:28:56 kent Exp $ */
-
-/*
- * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Allegro Networks, Inc., and Wasabi Systems, Inc.
- * 4. The name of Allegro Networks, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * 5. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
- * WASABI SYSTEMS, INC. ``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 EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
- * 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.
- */
-
-/* NOTE: GE_RXDESC_MAX * 16 <= GE_RXDESC_MEMSIZE */
-/* NOTE: the driver needs 4*GE_RXDESC_MAX mbuf clusters (4 queues) */
-#ifndef __rtems__
-#define GE_RXDESC_MEMSIZE (1 * PAGE_SIZE)
-#define GE_RXDESC_MAX 64
-#define GE_RXBUF_SIZE 2048
-#define GE_RXBUF_MEMSIZE (GE_RXDESC_MAX*GE_RXBUF_SIZE)
-#else
-#define GE_RXDESC_MEMSIZE (GE_RXDESC_MAX * sizeof(struct gt_eth_desc))
-#define GE_RXDESC_MAX (sc->num_rxdesc)
-#define GE_RXBUF_MEMSIZE 0
-#endif
-
-#define GE_RXBUF_NSEGS ((GE_RXBUF_MEMSIZE/PAGE_SIZE)+1)
-#define GE_DMSEG_MAX (GE_RXBUF_NSEGS)
-
-struct gfe_dmamem {
- bus_dmamap_t gdm_map; /* dmamem'ed memory */
-#ifdef __rtems__
- void *gdm_unaligned_buf;
-#endif
- caddr_t gdm_kva; /* kva of tx memory */
- int gdm_nsegs; /* # of segment in gdm_segs */
- int gdm_maxsegs; /* maximum # of segments allowed */
- size_t gdm_size; /* size of memory region */
- bus_dma_segment_t gdm_segs[GE_DMSEG_MAX]; /* dma segment of tx memory */
-};
-
-/* With a 4096 page size, we get 256 descriptors per page.
- */
-#ifndef __rtems__
-#define GE_TXDESC_MEMSIZE (1 * PAGE_SIZE)
-#define GE_TXDESC_MAX (GE_TXDESC_MEMSIZE / 16)
-#define GE_TXBUF_SIZE (4 * PAGE_SIZE)
-#else
-#define GE_TXDESC_MEMSIZE (sc->num_txdesc * sizeof(struct gt_eth_desc))
-#define GE_TXDESC_MAX (sc->num_txdesc)
-#endif
-
-struct gfe_txqueue {
- struct ifqueue txq_pendq; /* these are ready to go to the GT */
- struct ifqueue txq_sentq;
- struct gfe_dmamem txq_desc_mem; /* transmit descriptor memory */
-#ifndef __rtems__
- struct gfe_dmamem txq_buf_mem; /* transmit buffer memory */
-#endif
- unsigned int txq_lo; /* next to be given to GT */
- unsigned int txq_fi; /* next to be returned to CPU */
-#ifndef __rtems__
- unsigned int txq_ei_gapcount; /* counter until next EI */
-#endif
- unsigned int txq_nactive; /* number of active descriptors */
-#ifndef __rtems__
- unsigned int txq_outptr; /* where to put next transmit packet */
- unsigned int txq_inptr; /* start of 1st queued tx packet */
-#endif
- uint32_t txq_intrbits; /* bits to write to EIMR */
- uint32_t txq_esdcmrbits; /* bits to write to ESDCMR */
- uint32_t txq_epsrbits; /* bits to test with EPSR */
- volatile struct gt_eth_desc *txq_descs; /* ptr to tx descriptors */
- bus_addr_t txq_ectdp; /* offset to cur. tx desc ptr reg */
- bus_addr_t txq_desc_busaddr; /* bus addr of tx descriptors */
-#ifndef __rtems__
- bus_addr_t txq_buf_busaddr; /* bus addr of tx buffers */
-#endif
-};
-
-/* With a 4096 page size, we get 256 descriptors per page. We want 1024
- * which will give us about 8ms of 64 byte packets (2ms for each priority
- * queue).
- */
-
-#ifndef __rtems__
-struct gfe_rxbuf {
- uint8_t rb_data[GE_RXBUF_SIZE];
-};
-#endif
-
-struct gfe_rxqueue {
- struct gfe_dmamem rxq_desc_mem; /* receive descriptor memory */
-#ifndef __rtems__
- struct gfe_dmamem rxq_buf_mem; /* receive buffer memory */
- struct mbuf *rxq_curpkt; /* mbuf for current packet */
-#endif
- volatile struct gt_eth_desc *rxq_descs;
-#ifndef __rtems__
- struct gfe_rxbuf *rxq_bufs;
-#else
- struct mbuf **rxq_bufs;
-#endif
- unsigned int rxq_fi; /* next to be returned to CPU */
- unsigned int rxq_active; /* # of descriptors given to GT */
- uint32_t rxq_intrbits; /* bits to write to EIMR */
- bus_addr_t rxq_desc_busaddr; /* bus addr of rx descriptors */
- uint32_t rxq_cmdsts; /* save cmdsts from first descriptor */
- bus_size_t rxq_efrdp;
- bus_size_t rxq_ecrdp;
-};
-
-enum gfe_txprio {
- GE_TXPRIO_HI=1,
- GE_TXPRIO_LO=0,
- GE_TXPRIO_NONE=2
-};
-enum gfe_rxprio {
- GE_RXPRIO_HI=3,
- GE_RXPRIO_MEDHI=2,
- GE_RXPRIO_MEDLO=1,
- GE_RXPRIO_LO=0
-};
-
-#ifdef __rtems__
-#define sc_ec arpcom
-#define ec_if ac_if
-#define sc_dev arpcom
-#define dv_xname ac_if.if_name
-#endif
-
-struct gfe_softc {
-#ifndef __rtems__
- struct device sc_dev; /* must be first */
- struct ethercom sc_ec; /* common ethernet glue */
- struct callout sc_co; /* resource recovery */
- mii_data_t sc_mii; /* mii interface */
-
- /*
- *
- */
- bus_space_tag_t sc_gt_memt;
- bus_space_handle_t sc_gt_memh;
- bus_space_handle_t sc_memh; /* subregion for ethernet */
- bus_dma_tag_t sc_dmat;
-#else
- struct arpcom sc_ec;
- unsigned sc_gt_memh;
- unsigned sc_memh;
- unsigned char irq_no;
- rtems_id tid;
- int sc_phyaddr;
- int num_rxdesc, num_txdesc;
-#endif
- int sc_macno; /* which mac? 0, 1, or 2 */
-
- unsigned int sc_tickflags;
-#define GE_TICK_TX_IFSTART 0x0001
-#define GE_TICK_RX_RESTART 0x0002
- unsigned int sc_flags;
-#define GE_ALLMULTI 0x0001
-#define GE_PHYSTSCHG 0x0002
-#define GE_RXACTIVE 0x0004
-#define GE_NOFREE 0x0008 /* Don't free on disable */
- uint32_t sc_pcr; /* current EPCR value */
- uint32_t sc_pcxr; /* current EPCXR value */
- uint32_t sc_intrmask; /* current EIMR value */
- uint32_t sc_idlemask; /* suspended EIMR bits */
- size_t sc_max_frame_length; /* maximum frame length */
-
- /*
- * Hash table related members
- */
- struct gfe_dmamem sc_hash_mem; /* dma'ble hash table */
- uint64_t *sc_hashtable;
- unsigned int sc_hashmask; /* 0x1ff or 0x1fff */
-
- /*
- * Transmit related members
- */
- struct gfe_txqueue sc_txq[2]; /* High & Low transmit queues */
-
- /*
- * Receive related members
- */
- struct gfe_rxqueue sc_rxq[4]; /* Hi/MedHi/MedLo/Lo receive queues */
-};
-
-#ifdef __rtems__
-int
-gfe_mii_read(int phy, void *arg, unsigned reg, uint32_t *pval);
-
-int
-gfe_mii_write(int phy, void *arg, unsigned reg, uint32_t value);
-#endif
-
-#endif
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/rtemscompat_defs.h b/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/rtemscompat_defs.h
deleted file mode 100644
index 971b1d3cca..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_gfe/rtemscompat_defs.h
+++ /dev/null
@@ -1,161 +0,0 @@
-#ifndef RTEMS_COMPAT_DEFS_H
-#define RTEMS_COMPAT_DEFS_H
-
-#include <stdint.h>
-#include <stddef.h>
-
-/* Number of device instances the driver should support
- * - may be limited to 1 depending on IRQ API
- * (braindamaged PC586 and powerpc)
- */
-#define NETDRIVER_SLOTS 1
-/* String name to print with error messages */
-#define NETDRIVER "gfe"
-/* Name snippet used to make global symbols unique to this driver */
-#define NETDRIVER_PREFIX gfe
-
-/* Define according to endianness of the *ethernet*chip*
- * (not the CPU - most probably are LE)
- * This must be either NET_CHIP_LE or NET_CHIP_BE
- */
-
-#define NET_CHIP_LE
-#undef NET_CHIP_BE
-
-/* Define either NET_CHIP_MEM_IO or NET_CHIP_PORT_IO,
- * depending whether the CPU sees it in memory address space
- * or (e.g. x86) uses special I/O instructions.
- */
-#define NET_CHIP_MEM_IO
-#undef NET_CHIP_PORT_IO
-
-/* The name of the hijacked 'bus handle' field in the softc
- * structure. We use this field to store the chip's base address.
- */
-#define NET_SOFTC_BHANDLE_FIELD sc_memh
-
-/* define the names of the 'if_XXXreg.h' and 'if_XXXvar.h' headers
- * (only if present, i.e., if the BSDNET driver has no respective
- * header, leave this undefined).
- *
- */
-#undef IF_REG_HEADER
-#define IF_VAR_HEADER "../if_gfe/if_gfevar.h"
-
-/* define if a pci device */
-/*
-#define NETDRIVER_PCI <bsp/pci.h>
-*/
-#undef NETDRIVER_PCI
-
-/* Macros to disable and enable interrupts, respectively.
- * The 'disable' macro is expanded in the ISR, the 'enable'
- * macro is expanded in the driver task.
- * The global network semaphore usually provides mutex
- * protection of the device registers.
- * Special care must be taken when coding the 'disable' macro,
- * however to MAKE SURE THERE ARE NO OTHER SIDE EFFECTS such
- * as:
- * - macro must not clear any status flags
- * - macro must save/restore any context information
- * (e.g., a address register pointer or a bank switch register)
- *
- * ARGUMENT: the macro arg is a pointer to the driver's 'softc' structure
- */
-
-#define NET_DISABLE_IRQS(sc) GE_WRITE(sc, EIMR, 0)
-#define NET_ENABLE_IRQS(sc) GE_WRITE(sc, EIMR, sc->sc_intrmask)
-
-/* Driver may provide a macro/function to copy the hardware address
- * from the device into 'softc.arpcom'.
- * If this is undefined, the driver must to the copy itself.
- * Preferrably, it should check soft.arpcom.ac_enaddr for all
- * zeros and leave it alone if it is nonzero, i.e., write it
- * to the hardware.
-#define NET_READ_MAC_ADDR(sc)
- */
-
-typedef struct {
- uint32_t ds_addr;
- uint32_t ds_len;
-} bus_dma_segment_t;
-
-#define dm_segs gdm_segs
-#define dm_nsegs gdm_nsegs
-typedef struct gfe_dmamem *bus_dmamap_t;
-
-typedef uint32_t bus_addr_t;
-typedef uint32_t bus_size_t;
-
-typedef struct device blah;
-
-#define BUS_DMA_NOCACHE 0xdeadbeef
-
-#ifdef __PPC__
-#define bus_dmamap_sync(args...) do { __asm__ volatile("sync":::"memory"); } while(0)
-#else
-#error "Dont' know how to sync memory on your CPU"
-#endif
-
-int ether_sprintf_r(const unsigned char *enaddr, char *buf, int len);
-
-/* we have it although we're not ansi */
-int snprintf(char *, size_t, const char *,...);
-
-#include <string.h>
-
-/* declare in every routine using ether_sprintf */
-#define SPRINTFVARDECL char rtems_sprintf_local_buf[3*6] /* ethernet string */
-
-#define ether_sprintf_macro(a) \
- (snprintf(rtems_sprintf_local_buf, \
- sizeof(rtems_sprintf_local_buf), \
- "%02X:%02X:%02X:%02X:%02X:%02X", \
- a[0],a[1],a[2],a[3],a[4],a[5]) ? \
- rtems_sprintf_local_buf : 0 \
- )
-
-
-#define aprint_normal(args...) printf(args)
-#define aprint_error(args...) fprintf(stderr,args)
-
-#define delay(arg) DELAY(arg)
-
-#define KASSERT(a...) do {} while (0)
-
-#define gfe_assign_desc _bsd_gfe_assign_desc
-#define gfe_attach _bsd_gfe_attach
-#define gfe_dbg_config _bsd_gfe_dbg_config
-#define gfe_dmamem_alloc _bsd_gfe_dmamem_alloc
-#define gfe_dmamem_free _bsd_gfe_dmamem_free
-#define gfe_hash_alloc _bsd_gfe_hash_alloc
-#define gfe_hash_compute _bsd_gfe_hash_compute
-#define gfe_hash_entry_op _bsd_gfe_hash_entry_op
-#define gfe_hash_fill _bsd_gfe_hash_fill
-#define gfe_ifioctl _bsd_gfe_ifioctl
-#define gfe_ifstart _bsd_gfe_ifstart
-#define gfe_ifwatchdog _bsd_gfe_ifwatchdog
-#define gfe_init _bsd_gfe_init
-#define gfe_intr _bsd_gfe_intr
-#define gfe_mdio_access _bsd_gfe_mdio_access
-#define gfe_mii_read _bsd_gfe_mii_read
-#define gfe_mii_write _bsd_gfe_mii_write
-#define gfe_probe _bsd_gfe_probe
-#define gfe_rx_cleanup _bsd_gfe_rx_cleanup
-#define gfe_rx_get _bsd_gfe_rx_get
-#define gfe_rx_prime _bsd_gfe_rx_prime
-#define gfe_rx_process _bsd_gfe_rx_process
-#define gfe_rx_rxqalloc _bsd_gfe_rx_rxqalloc
-#define gfe_rx_rxqinit _bsd_gfe_rx_rxqinit
-#define gfe_rx_stop _bsd_gfe_rx_stop
-#define gfe_tick _bsd_gfe_tick
-#define gfe_tx_cleanup _bsd_gfe_tx_cleanup
-#define gfe_tx_done _bsd_gfe_tx_done
-#define gfe_tx_enqueue _bsd_gfe_tx_enqueue
-#define gfe_tx_start _bsd_gfe_tx_start
-#define gfe_tx_stop _bsd_gfe_tx_stop
-#define gfe_tx_txqalloc _bsd_gfe_tx_txqalloc
-#define gfe_whack _bsd_gfe_whack
-#define the_gfe_devs _bsd_the_gfe_devs
-
-#endif
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mv643xx_eth.c b/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mv643xx_eth.c
deleted file mode 100644
index 85ab038bf5..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mv643xx_eth.c
+++ /dev/null
@@ -1,3318 +0,0 @@
-/* RTEMS driver for the mv643xx gigabit ethernet chip */
-
-/* Acknowledgement:
- *
- * Valuable information for developing this driver was obtained
- * from the linux open-source driver mv643xx_eth.c which was written
- * by the following people and organizations:
- *
- * Matthew Dharm <mdharm@momenco.com>
- * rabeeh@galileo.co.il
- * PMC-Sierra, Inc., Manish Lachwani
- * Ralf Baechle <ralf@linux-mips.org>
- * MontaVista Software, Inc., Dale Farnsworth <dale@farnsworth.org>
- * Steven J. Hill <sjhill1@rockwellcollins.com>/<sjhill@realitydiluted.com>
- *
- * Note however, that in spite of the identical name of this file
- * (and some of the symbols used herein) this file provides a
- * new implementation and is the original work by the author.
- */
-
-/*
- * Authorship
- * ----------
- * This software (mv643xx ethernet driver for RTEMS) was
- * created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
- * Stanford Linear Accelerator Center, Stanford University.
- *
- * Acknowledgement of sponsorship
- * ------------------------------
- * The 'mv643xx ethernet driver for RTEMS' was produced by
- * the Stanford Linear Accelerator Center, Stanford University,
- * under Contract DE-AC03-76SFO0515 with the Department of Energy.
- *
- * Government disclaimer of liability
- * ----------------------------------
- * Neither the United States nor the United States Department of Energy,
- * nor any of their employees, makes any warranty, express or implied, or
- * assumes any legal liability or responsibility for the accuracy,
- * completeness, or usefulness of any data, apparatus, product, or process
- * disclosed, or represents that its use would not infringe privately owned
- * rights.
- *
- * Stanford disclaimer of liability
- * --------------------------------
- * Stanford University makes no representations or warranties, express or
- * implied, nor assumes any liability for the use of this software.
- *
- * Stanford disclaimer of copyright
- * --------------------------------
- * Stanford University, owner of the copyright, hereby disclaims its
- * copyright and all other rights in this software. Hence, anyone may
- * freely use it for any purpose without restriction.
- *
- * Maintenance of notices
- * ----------------------
- * In the interest of clarity regarding the origin and status of this
- * SLAC software, this and all the preceding Stanford University notices
- * are to remain affixed to any copy or derivative of this software made
- * or distributed by the recipient and are to be affixed to any copy of
- * software made or distributed by the recipient that contains a copy or
- * derivative of this software.
- *
- * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
- */
-
-/*
- * NOTE: Some register (e.g., the SMI register) are SHARED among the
- * three devices. Concurrent access protection is provided by
- * the global networking semaphore.
- * If other drivers are running on a subset of IFs then proper
- * locking of all shared registers must be implemented!
- *
- * Some things I learned about this hardware can be found
- * further down...
- */
-
-#ifndef KERNEL
-#define KERNEL
-#endif
-#ifndef _KERNEL
-#define _KERNEL
-#endif
-
-#include <rtems.h>
-#include <rtems/bspIo.h>
-#include <rtems/error.h>
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <bsp/gtreg.h>
-#include <libcpu/byteorder.h>
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <dev/mii/mii.h>
-#include <net/if_var.h>
-#include <net/if_media.h>
-
-/* Not so nice; would be more elegant not to depend on C library but the
- * RTEMS-specific ioctl for dumping statistics needs stdio anyways.
- */
-
-/*#define NDEBUG effectively removes all assertions
- * If defining NDEBUG, MAKE SURE assert() EXPRESSION HAVE NO SIDE_EFFECTS!!
- * This driver DOES have side-effects, so DONT DEFINE NDEBUG
- * Performance-critical assertions are removed by undefining MVETH_TESTING.
- */
-
-#undef NDEBUG
-#include <assert.h>
-#include <stdio.h>
-#include <errno.h>
-#include <inttypes.h>
-
-#include <rtems/rtems_bsdnet.h>
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <net/ethernet.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <rtems/rtems_mii_ioctl.h>
-#include <bsp/early_enet_link_status.h>
-#include <bsp/if_mve_pub.h>
-
-/* CONFIGURABLE PARAMETERS */
-
-/* Enable Hardware Snooping; if this is disabled (undefined),
- * cache coherency is maintained by software.
- */
-#undef ENABLE_HW_SNOOPING
-
-/* Compile-time debugging features */
-
-/* Enable paranoia assertions and checks; reduce # of descriptors to minimum for stressing */
-#undef MVETH_TESTING
-
-/* Enable debugging messages and some support routines (dump rings etc.) */
-#undef MVETH_DEBUG
-
-/* Hack for driver development; rtems bsdnet doesn't implement detaching an interface :-(
- * but this hack allows us to unload/reload the driver module which makes development
- * a lot less painful.
- */
-#undef MVETH_DETACH_HACK
-
-/* Ring sizes */
-
-#ifdef MVETH_TESTING
-
-/* hard and small defaults */
-#undef MV643XX_RX_RING_SIZE
-#define MV643XX_RX_RING_SIZE 2
-#undef MV643XX_TX_RING_SIZE
-#define MV643XX_TX_RING_SIZE 4
-
-#else /* MVETH_TESTING */
-
-/* Define default ring sizes, allow override from bsp.h, Makefile,... and from ifcfg->rbuf_count/xbuf_count */
-
-#ifndef MV643XX_RX_RING_SIZE
-#define MV643XX_RX_RING_SIZE 40 /* attached buffers are always 2k clusters, i.e., this
- * driver - with a configured ring size of 40 - constantly
- * locks 80k of cluster memory - your app config better
- * provides enough space!
- */
-#endif
-
-#ifndef MV643XX_TX_RING_SIZE
-/* NOTE: tx ring size MUST be > max. # of fragments / mbufs in a chain;
- * in 'TESTING' mode, special code is compiled in to repackage
- * chains that are longer than the ring size. Normally, this is
- * disabled for sake of speed.
- * I observed chains of >17 entries regularly!
- *
- * Also, TX_NUM_TAG_SLOTS (1) must be left empty as a marker, hence
- * the ring size must be > max. #frags + 1.
- */
-#define MV643XX_TX_RING_SIZE 200 /* these are smaller fragments and not occupied when
- * the driver is idle.
- */
-#endif
-
-#endif /* MVETH_TESTING */
-
-/* How many instances to we support (bsp.h could override) */
-#ifndef MV643XXETH_NUM_DRIVER_SLOTS
-#define MV643XXETH_NUM_DRIVER_SLOTS 2
-#endif
-
-#define TX_NUM_TAG_SLOTS 1 /* leave room for tag; must not be 0 */
-
-/* This is REAL; chip reads from 64-bit down-aligned buffer
- * if the buffer size is < 8 !!! for buffer sizes 8 and upwards
- * alignment is not an issue. This was verified using the
- * 'mve_smallbuf_test.c'
- */
-#define ENABLE_TX_WORKAROUND_8_BYTE_PROBLEM
-
-/* Chip register configuration values */
-#define MVETH_PORT_CONFIG_VAL (0 \
- | MV643XX_ETH_DFLT_RX_Q(0) \
- | MV643XX_ETH_DFLT_RX_ARP_Q(0) \
- | MV643XX_ETH_DFLT_RX_TCP_Q(0) \
- | MV643XX_ETH_DFLT_RX_UDP_Q(0) \
- | MV643XX_ETH_DFLT_RX_BPDU_Q(0) \
- )
-
-
-#define MVETH_PORT_XTEND_CONFIG_VAL 0
-
-#ifdef OLDCONFIGVAL
-#define MVETH_SERIAL_CTRL_CONFIG_VAL (0 \
- | MV643XX_ETH_FORCE_LINK_PASS \
- | MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOWCTL \
- | MV643XX_ETH_ADVERTISE_SYMMETRIC_FLOWCTL \
- | MV643XX_ETH_BIT9_UNKNOWN \
- | MV643XX_ETH_FORCE_LINK_FAIL_DISABLE \
- | MV643XX_ETH_SC_MAX_RX_1552 \
- | MV643XX_ETH_SET_FULL_DUPLEX \
- | MV643XX_ETH_ENBL_FLOWCTL_TX_RX_IN_FD \
- )
-#endif
-/* If we enable autoneg (duplex, speed, ...) then it seems
- * that the chip automatically updates link settings
- * (correct link settings are reflected in PORT_STATUS_R).
- * However, when we disable aneg in the PHY then things
- * can get messed up and the port doesn't work anymore.
- * => we follow the linux driver in disabling all aneg
- * in the serial config reg. and manually updating the
- * speed & duplex bits when the phy link status changes.
- * FIXME: don't know what to do about pause/flow-ctrl.
- * It is best to just use ANEG anyways!!!
- */
-#define MVETH_SERIAL_CTRL_CONFIG_VAL (0 \
- | MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLEX \
- | MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOWCTL \
- | MV643XX_ETH_ADVERTISE_SYMMETRIC_FLOWCTL \
- | MV643XX_ETH_BIT9_UNKNOWN \
- | MV643XX_ETH_FORCE_LINK_FAIL_DISABLE \
- | MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII \
- | MV643XX_ETH_SC_MAX_RX_1552 \
- )
-
-#define MVETH_SERIAL_CTRL_CONFIG_MSK (0 \
- | MV643XX_ETH_SERIAL_PORT_ENBL \
- | MV643XX_ETH_FORCE_LINK_PASS \
- | MV643XX_ETH_SC_MAX_RX_MASK \
- )
-
-
-#ifdef __PPC__
-#define MVETH_SDMA_CONFIG_VAL (0 \
- | MV643XX_ETH_RX_BURST_SZ_4_64BIT \
- | MV643XX_ETH_TX_BURST_SZ_4_64BIT \
- )
-#else
-#define MVETH_SDMA_CONFIG_VAL (0 \
- | MV643XX_ETH_RX_BURST_SZ_16_64BIT \
- | MV643XX_ETH_TX_BURST_SZ_16_64BIT \
- )
-#endif
-
-/* minimal frame size we accept */
-#define MVETH_MIN_FRAMSZ_CONFIG_VAL 40
-
-/* END OF CONFIGURABLE SECTION */
-
-/*
- * Here's stuff I learned about this chip:
- *
- *
- * RX interrupt flags:
- *
- * broadcast packet RX: 0x00000005
- * last buf: 0x00000c05
- * overrun: 0x00000c00
- * unicast packet RX: 0x00000005
- * bad CRC received: 0x00000005
- *
- * clearing 0x00000004 -> clears 0x00000001
- * clearing 0x00000400 -> clears 0x00000800
- *
- * --> 0x0801 are probably some sort of summary bits.
- *
- * TX interrupt flags:
- *
- * broadcast packet in 1 buf: xcause: 0x00000001 (cause 0x00080000)
- * into disconn. link: " "
- *
- * in some cases, I observed xcause: 0x00000101 (reason for 0x100 unknown
- * but the linux driver accepts it also).
- *
- *
- * Here a few more ugly things about this piece of hardware I learned
- * (painfully, painfully; spending many many hours & nights :-()
- *
- * a) Especially in the case of 'chained' descriptors, the DMA keeps
- * clobbering 'cmd_sts' long after it cleared the OWNership flag!!!
- * Only after the whole chain is processed (OWN cleared on the
- * last descriptor) it is safe to change cmd_sts.
- * However, in the case of hardware snooping I found that the
- * last descriptor in chain has its cmd_sts still clobbered *after*
- * checking ownership!, I.e.,
- * if ( ! OWN & cmd_sts ) {
- * cmd_sts = 0;
- * }
- * --> sometimes, cmd_sts is STILL != 0 here
- *
- * b) Sometimes, the OWNership flag is *not cleared*.
- *
- * c) Weird things happen if the chip finds a descriptor with 'OWN'
- * still set (i.e., not properly loaded), i.e., corrupted packets
- * are sent [with OK checksum since the chip calculates it].
- *
- * Combine a+b+c and we end up with a real mess.
- *
- * The fact that the chip doesn't reliably reset OWN and that OTOH,
- * it can't be reliably reset by the driver and still, the chip needs
- * it for proper communication doesn't make things easy...
- *
- * Here the basic workarounds:
- *
- * - In addition to check OWN, the scavenger compares the "currently
- * served desc" register to the descriptor it tries to recover and
- * ignores OWN if they do not match. Hope this is OK.
- * Otherwise, we could scan the list of used descriptors and proceed
- * recycling descriptors if we find a !OWNed one behind the target...
- *
- * - Always keep an empty slot around to mark the end of the list of
- * jobs. The driver clears the descriptor ahead when enqueueing a new
- * packet.
- */
-
-#define DRVNAME "mve"
-#define MAX_NUM_SLOTS 3
-
-#if MV643XXETH_NUM_DRIVER_SLOTS > MAX_NUM_SLOTS
-#error "mv643xxeth: only MAX_NUM_SLOTS supported"
-#endif
-
-#ifdef NDEBUG
-#error "Driver uses assert() statements with side-effects; MUST NOT define NDEBUG"
-#endif
-
-#ifdef MVETH_DEBUG
-#define STATIC
-#else
-#define STATIC static
-#endif
-
-#define TX_AVAILABLE_RING_SIZE(mp) ((mp)->xbuf_count - (TX_NUM_TAG_SLOTS))
-
-/* macros for ring alignment; proper alignment is a hardware req; . */
-
-#ifdef ENABLE_HW_SNOOPING
-
-#define RING_ALIGNMENT 16
-/* rx buffers must be 64-bit aligned (chip requirement) */
-#define RX_BUF_ALIGNMENT 8
-
-#else /* ENABLE_HW_SNOOPING */
-
-/* Software cache management */
-
-#ifndef __PPC__
-#error "Dont' know how to deal with cache on this CPU architecture"
-#endif
-
-/* Ring entries are 32 bytes; coherency-critical chunks are 16 -> software coherency
- * management works for cache line sizes of 16 and 32 bytes only. If the line size
- * is bigger, the descriptors could be padded...
- */
-#if PPC_CACHE_ALIGMENT != 16 && PPC_CACHE_ALIGNMENT != 32
-#error "Cache line size must be 16 or 32"
-#else
-#define RING_ALIGNMENT PPC_CACHE_ALIGNMENT
-#define RX_BUF_ALIGNMENT PPC_CACHE_ALIGNMENT
-#endif
-
-#endif /* ENABLE_HW_SNOOPING */
-
-
-/* HELPER MACROS */
-
-/* Align base to alignment 'a' */
-#define MV643XX_ALIGN(b, a) ((((uint32_t)(b)) + (a)-1) & (~((a)-1)))
-
-#define NOOP() do {} while(0)
-
-/* Function like macros */
-#define MV_READ(off) \
- ld_le32((volatile uint32_t *)(BSP_MV64x60_BASE + (off)))
-#define MV_WRITE(off, data) \
- st_le32((volatile uint32_t *)(BSP_MV64x60_BASE + (off)), ((unsigned)data))
-
-
-/* ENET window mapped 1:1 to CPU addresses by our BSP/MotLoad
- * -- if this is changed, we should think about caching the 'next' and 'buf' pointers.
- */
-#define CPUADDR2ENET(a) ((Dma_addr_t)(a))
-#define ENET2CPUADDR(a) (a)
-
-#if 1 /* Whether to automatically try to reclaim descriptors when enqueueing new packets */
-#define MVETH_CLEAN_ON_SEND(mp) (BSP_mve_swipe_tx(mp))
-#else
-#define MVETH_CLEAN_ON_SEND(mp) (-1)
-#endif
-
-#define NEXT_TXD(d) (d)->next
-#define NEXT_RXD(d) (d)->next
-
-/* REGISTER AND DESCRIPTOR OFFSET AND BIT DEFINITIONS */
-
-/* Descriptor Definitions */
-/* Rx descriptor */
-#define RDESC_ERROR (1<< 0) /* Error summary */
-
-/* Error code (bit 1&2) is only valid if summary bit is set */
-#define RDESC_CRC_ERROR ( 1)
-#define RDESC_OVERRUN_ERROR ( 3)
-#define RDESC_MAX_FRAMELENGTH_ERROR ( 5)
-#define RDESC_RESOURCE_ERROR ( 7)
-
-#define RDESC_LAST (1<<26) /* Last Descriptor */
-#define RDESC_FRST (1<<27) /* First Descriptor */
-#define RDESC_INT_ENA (1<<29) /* Enable Interrupts */
-#define RDESC_DMA_OWNED (1<<31)
-
-/* Tx descriptor */
-#define TDESC_ERROR (1<< 0) /* Error summary */
-#define TDESC_ZERO_PAD (1<<19)
-#define TDESC_LAST (1<<20) /* Last Descriptor */
-#define TDESC_FRST (1<<21) /* First Descriptor */
-#define TDESC_GEN_CRC (1<<22)
-#define TDESC_INT_ENA (1<<23) /* Enable Interrupts */
-#define TDESC_DMA_OWNED (1<<31)
-
-
-
-/* Register Definitions */
-#define MV643XX_ETH_PHY_ADDR_R (0x2000)
-#define MV643XX_ETH_SMI_R (0x2004)
-#define MV643XX_ETH_SMI_BUSY (1<<28)
-#define MV643XX_ETH_SMI_VALID (1<<27)
-#define MV643XX_ETH_SMI_OP_WR (0<<26)
-#define MV643XX_ETH_SMI_OP_RD (1<<26)
-
-#define MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(port) (0x2448 + ((port)<<10))
-#define MV643XX_ETH_TX_START(queue) (0x0001<<(queue))
-#define MV643XX_ETH_TX_STOP(queue) (0x0100<<(queue))
-#define MV643XX_ETH_TX_START_M(queues) ((queues)&0xff)
-#define MV643XX_ETH_TX_STOP_M(queues) (((queues)&0xff)<<8)
-#define MV643XX_ETH_TX_STOP_ALL (0xff00)
-#define MV643XX_ETH_TX_ANY_RUNNING (0x00ff)
-
-#define MV643XX_ETH_RECEIVE_QUEUE_COMMAND_R(port) (0x2680 + ((port)<<10))
-#define MV643XX_ETH_RX_START(queue) (0x0001<<(queue))
-#define MV643XX_ETH_RX_STOP(queue) (0x0100<<(queue))
-#define MV643XX_ETH_RX_STOP_ALL (0xff00)
-#define MV643XX_ETH_RX_ANY_RUNNING (0x00ff)
-
-#define MV643XX_ETH_CURRENT_SERVED_TX_DESC(port) (0x2684 + ((port)<<10))
-
-/* The chip puts the ethernet header at offset 2 into the buffer so
- * that the payload is aligned
- */
-#define ETH_RX_OFFSET 2
-#define ETH_CRC_LEN 4 /* strip FCS at end of packet */
-
-
-#define MV643XX_ETH_INTERRUPT_CAUSE_R(port) (0x2460 + ((port)<<10))
-/* not fully understood; RX seems to raise 0x0005 or 0x0c05 if last buffer is filled and 0x0c00
- * if there are no buffers
- */
-#define MV643XX_ETH_ALL_IRQS (0x0007ffff)
-#define MV643XX_ETH_KNOWN_IRQS (0x00000c05)
-#define MV643XX_ETH_IRQ_EXT_ENA (1<<1)
-#define MV643XX_ETH_IRQ_RX_DONE (1<<2)
-#define MV643XX_ETH_IRQ_RX_NO_DESC (1<<10)
-
-#define MV643XX_ETH_INTERRUPT_EXTEND_CAUSE_R(port) (0x2464 + ((port)<<10))
-/* not fully understood; TX seems to raise 0x0001 and link change is 0x00010000
- * if there are no buffers
- */
-#define MV643XX_ETH_ALL_EXT_IRQS (0x0011ffff)
-#define MV643XX_ETH_KNOWN_EXT_IRQS (0x00010101)
-#define MV643XX_ETH_EXT_IRQ_TX_DONE (1<<0)
-#define MV643XX_ETH_EXT_IRQ_LINK_CHG (1<<16)
-#define MV643XX_ETH_INTERRUPT_ENBL_R(port) (0x2468 + ((port)<<10))
-#define MV643XX_ETH_INTERRUPT_EXTEND_ENBL_R(port) (0x246c + ((port)<<10))
-
-/* port configuration */
-#define MV643XX_ETH_PORT_CONFIG_R(port) (0x2400 + ((port)<<10))
-#define MV643XX_ETH_UNICAST_PROMISC_MODE (1<<0)
-#define MV643XX_ETH_DFLT_RX_Q(q) ((q)<<1)
-#define MV643XX_ETH_DFLT_RX_ARP_Q(q) ((q)<<4)
-#define MV643XX_ETH_REJ_BCAST_IF_NOT_IP_OR_ARP (1<<7)
-#define MV643XX_ETH_REJ_BCAST_IF_IP (1<<8)
-#define MV643XX_ETH_REJ_BCAST_IF_ARP (1<<9)
-#define MV643XX_ETH_TX_AM_NO_UPDATE_ERR_SUMMARY (1<<12)
-#define MV643XX_ETH_CAPTURE_TCP_FRAMES_ENBL (1<<14)
-#define MV643XX_ETH_CAPTURE_UDP_FRAMES_ENBL (1<<15)
-#define MV643XX_ETH_DFLT_RX_TCP_Q(q) ((q)<<16)
-#define MV643XX_ETH_DFLT_RX_UDP_Q(q) ((q)<<19)
-#define MV643XX_ETH_DFLT_RX_BPDU_Q(q) ((q)<<22)
-
-
-
-#define MV643XX_ETH_PORT_CONFIG_XTEND_R(port) (0x2404 + ((port)<<10))
-#define MV643XX_ETH_CLASSIFY_ENBL (1<<0)
-#define MV643XX_ETH_SPAN_BPDU_PACKETS_AS_NORMAL (0<<1)
-#define MV643XX_ETH_SPAN_BPDU_PACKETS_2_Q7 (1<<1)
-#define MV643XX_ETH_PARTITION_DISBL (0<<2)
-#define MV643XX_ETH_PARTITION_ENBL (1<<2)
-
-#define MV643XX_ETH_SDMA_CONFIG_R(port) (0x241c + ((port)<<10))
-#define MV643XX_ETH_SDMA_RIFB (1<<0)
-#define MV643XX_ETH_RX_BURST_SZ_1_64BIT (0<<1)
-#define MV643XX_ETH_RX_BURST_SZ_2_64BIT (1<<1)
-#define MV643XX_ETH_RX_BURST_SZ_4_64BIT (2<<1)
-#define MV643XX_ETH_RX_BURST_SZ_8_64BIT (3<<1)
-#define MV643XX_ETH_RX_BURST_SZ_16_64BIT (4<<1)
-#define MV643XX_ETH_SMDA_BLM_RX_NO_SWAP (1<<4)
-#define MV643XX_ETH_SMDA_BLM_TX_NO_SWAP (1<<5)
-#define MV643XX_ETH_SMDA_DESC_BYTE_SWAP (1<<6)
-#define MV643XX_ETH_TX_BURST_SZ_1_64BIT (0<<22)
-#define MV643XX_ETH_TX_BURST_SZ_2_64BIT (1<<22)
-#define MV643XX_ETH_TX_BURST_SZ_4_64BIT (2<<22)
-#define MV643XX_ETH_TX_BURST_SZ_8_64BIT (3<<22)
-#define MV643XX_ETH_TX_BURST_SZ_16_64BIT (4<<22)
-
-#define MV643XX_ETH_RX_MIN_FRAME_SIZE_R(port) (0x247c + ((port)<<10))
-
-
-#define MV643XX_ETH_SERIAL_CONTROL_R(port) (0x243c + ((port)<<10))
-#define MV643XX_ETH_SERIAL_PORT_ENBL (1<<0) /* Enable serial port */
-#define MV643XX_ETH_FORCE_LINK_PASS (1<<1)
-#define MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLEX (1<<2)
-#define MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOWCTL (1<<3)
-#define MV643XX_ETH_ADVERTISE_SYMMETRIC_FLOWCTL (1<<4)
-#define MV643XX_ETH_FORCE_FC_MODE_TX_PAUSE_DIS (1<<5)
-#define MV643XX_ETH_FORCE_BP_MODE_JAM_TX (1<<7)
-#define MV643XX_ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR (1<<8)
-#define MV643XX_ETH_BIT9_UNKNOWN (1<<9) /* unknown purpose; linux sets this */
-#define MV643XX_ETH_FORCE_LINK_FAIL_DISABLE (1<<10)
-#define MV643XX_ETH_RETRANSMIT_FOREVER (1<<11) /* limit to 16 attempts if clear */
-#define MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII (1<<13)
-#define MV643XX_ETH_DTE_ADV_1 (1<<14)
-#define MV643XX_ETH_AUTO_NEG_BYPASS_ENBL (1<<15)
-#define MV643XX_ETH_RESTART_AUTO_NEG (1<<16)
-#define MV643XX_ETH_SC_MAX_RX_1518 (0<<17) /* Limit RX packet size */
-#define MV643XX_ETH_SC_MAX_RX_1522 (1<<17) /* Limit RX packet size */
-#define MV643XX_ETH_SC_MAX_RX_1552 (2<<17) /* Limit RX packet size */
-#define MV643XX_ETH_SC_MAX_RX_9022 (3<<17) /* Limit RX packet size */
-#define MV643XX_ETH_SC_MAX_RX_9192 (4<<17) /* Limit RX packet size */
-#define MV643XX_ETH_SC_MAX_RX_9700 (5<<17) /* Limit RX packet size */
-#define MV643XX_ETH_SC_MAX_RX_MASK (7<<17) /* bitmask */
-#define MV643XX_ETH_SET_EXT_LOOPBACK (1<<20)
-#define MV643XX_ETH_SET_FULL_DUPLEX (1<<21)
-#define MV643XX_ETH_ENBL_FLOWCTL_TX_RX_IN_FD (1<<22) /* enable flow ctrl on rx and tx in full-duplex */
-#define MV643XX_ETH_SET_GMII_SPEED_1000 (1<<23) /* 10/100 if clear */
-#define MV643XX_ETH_SET_MII_SPEED_100 (1<<24) /* 10 if clear */
-
-#define MV643XX_ETH_PORT_STATUS_R(port) (0x2444 + ((port)<<10))
-
-#define MV643XX_ETH_PORT_STATUS_MODE_10_BIT (1<<0)
-#define MV643XX_ETH_PORT_STATUS_LINK_UP (1<<1)
-#define MV643XX_ETH_PORT_STATUS_FDX (1<<2)
-#define MV643XX_ETH_PORT_STATUS_FC (1<<3)
-#define MV643XX_ETH_PORT_STATUS_1000 (1<<4)
-#define MV643XX_ETH_PORT_STATUS_100 (1<<5)
-/* PSR bit 6 unknown */
-#define MV643XX_ETH_PORT_STATUS_TX_IN_PROGRESS (1<<7)
-#define MV643XX_ETH_PORT_STATUS_ANEG_BYPASSED (1<<8)
-#define MV643XX_ETH_PORT_STATUS_PARTITION (1<<9)
-#define MV643XX_ETH_PORT_STATUS_TX_FIFO_EMPTY (1<<10)
-
-#define MV643XX_ETH_MIB_COUNTERS(port) (0x3000 + ((port)<<7))
-#define MV643XX_ETH_NUM_MIB_COUNTERS 32
-
-#define MV643XX_ETH_MIB_GOOD_OCTS_RCVD_LO (0)
-#define MV643XX_ETH_MIB_GOOD_OCTS_RCVD_HI (1<<2)
-#define MV643XX_ETH_MIB_BAD_OCTS_RCVD (2<<2)
-#define MV643XX_ETH_MIB_INTERNAL_MAC_TX_ERR (3<<2)
-#define MV643XX_ETH_MIB_GOOD_FRAMES_RCVD (4<<2)
-#define MV643XX_ETH_MIB_BAD_FRAMES_RCVD (5<<2)
-#define MV643XX_ETH_MIB_BCAST_FRAMES_RCVD (6<<2)
-#define MV643XX_ETH_MIB_MCAST_FRAMES_RCVD (7<<2)
-#define MV643XX_ETH_MIB_FRAMES_64_OCTS (8<<2)
-#define MV643XX_ETH_MIB_FRAMES_65_127_OCTS (9<<2)
-#define MV643XX_ETH_MIB_FRAMES_128_255_OCTS (10<<2)
-#define MV643XX_ETH_MIB_FRAMES_256_511_OCTS (11<<2)
-#define MV643XX_ETH_MIB_FRAMES_512_1023_OCTS (12<<2)
-#define MV643XX_ETH_MIB_FRAMES_1024_MAX_OCTS (13<<2)
-#define MV643XX_ETH_MIB_GOOD_OCTS_SENT_LO (14<<2)
-#define MV643XX_ETH_MIB_GOOD_OCTS_SENT_HI (15<<2)
-#define MV643XX_ETH_MIB_GOOD_FRAMES_SENT (16<<2)
-#define MV643XX_ETH_MIB_EXCESSIVE_COLL (17<<2)
-#define MV643XX_ETH_MIB_MCAST_FRAMES_SENT (18<<2)
-#define MV643XX_ETH_MIB_BCAST_FRAMES_SENT (19<<2)
-#define MV643XX_ETH_MIB_UNREC_MAC_CTRL_RCVD (20<<2)
-#define MV643XX_ETH_MIB_FC_SENT (21<<2)
-#define MV643XX_ETH_MIB_GOOD_FC_RCVD (22<<2)
-#define MV643XX_ETH_MIB_BAD_FC_RCVD (23<<2)
-#define MV643XX_ETH_MIB_UNDERSIZE_RCVD (24<<2)
-#define MV643XX_ETH_MIB_FRAGMENTS_RCVD (25<<2)
-#define MV643XX_ETH_MIB_OVERSIZE_RCVD (26<<2)
-#define MV643XX_ETH_MIB_JABBER_RCVD (27<<2)
-#define MV643XX_ETH_MIB_MAC_RX_ERR (28<<2)
-#define MV643XX_ETH_MIB_BAD_CRC_EVENT (29<<2)
-#define MV643XX_ETH_MIB_COLL (30<<2)
-#define MV643XX_ETH_MIB_LATE_COLL (31<<2)
-
-#define MV643XX_ETH_DA_FILTER_SPECL_MCAST_TBL(port) (0x3400+((port)<<10))
-#define MV643XX_ETH_DA_FILTER_OTHER_MCAST_TBL(port) (0x3500+((port)<<10))
-#define MV643XX_ETH_DA_FILTER_UNICAST_TBL(port) (0x3600+((port)<<10))
-#define MV643XX_ETH_NUM_MCAST_ENTRIES 64
-#define MV643XX_ETH_NUM_UNICAST_ENTRIES 4
-
-#define MV643XX_ETH_BAR_0 (0x2200)
-#define MV643XX_ETH_SIZE_R_0 (0x2204)
-#define MV643XX_ETH_BAR_1 (0x2208)
-#define MV643XX_ETH_SIZE_R_1 (0x220c)
-#define MV643XX_ETH_BAR_2 (0x2210)
-#define MV643XX_ETH_SIZE_R_2 (0x2214)
-#define MV643XX_ETH_BAR_3 (0x2218)
-#define MV643XX_ETH_SIZE_R_3 (0x221c)
-#define MV643XX_ETH_BAR_4 (0x2220)
-#define MV643XX_ETH_SIZE_R_4 (0x2224)
-#define MV643XX_ETH_BAR_5 (0x2228)
-#define MV643XX_ETH_SIZE_R_5 (0x222c)
-#define MV643XX_ETH_NUM_BARS 6
-
-/* Bits in the BAR reg to program cache snooping */
-#define MV64360_ENET2MEM_SNOOP_NONE 0x0000
-#define MV64360_ENET2MEM_SNOOP_WT 0x1000
-#define MV64360_ENET2MEM_SNOOP_WB 0x2000
-#define MV64360_ENET2MEM_SNOOP_MSK 0x3000
-
-
-#define MV643XX_ETH_BAR_ENBL_R (0x2290)
-#define MV643XX_ETH_BAR_DISABLE(bar) (1<<(bar))
-#define MV643XX_ETH_BAR_DISBL_ALL 0x3f
-
-#define MV643XX_ETH_RX_Q0_CURRENT_DESC_PTR(port) (0x260c+((port)<<10))
-#define MV643XX_ETH_RX_Q1_CURRENT_DESC_PTR(port) (0x261c+((port)<<10))
-#define MV643XX_ETH_RX_Q2_CURRENT_DESC_PTR(port) (0x262c+((port)<<10))
-#define MV643XX_ETH_RX_Q3_CURRENT_DESC_PTR(port) (0x263c+((port)<<10))
-#define MV643XX_ETH_RX_Q4_CURRENT_DESC_PTR(port) (0x264c+((port)<<10))
-#define MV643XX_ETH_RX_Q5_CURRENT_DESC_PTR(port) (0x265c+((port)<<10))
-#define MV643XX_ETH_RX_Q6_CURRENT_DESC_PTR(port) (0x266c+((port)<<10))
-#define MV643XX_ETH_RX_Q7_CURRENT_DESC_PTR(port) (0x267c+((port)<<10))
-
-#define MV643XX_ETH_TX_Q0_CURRENT_DESC_PTR(port) (0x26c0+((port)<<10))
-#define MV643XX_ETH_TX_Q1_CURRENT_DESC_PTR(port) (0x26c4+((port)<<10))
-#define MV643XX_ETH_TX_Q2_CURRENT_DESC_PTR(port) (0x26c8+((port)<<10))
-#define MV643XX_ETH_TX_Q3_CURRENT_DESC_PTR(port) (0x26cc+((port)<<10))
-#define MV643XX_ETH_TX_Q4_CURRENT_DESC_PTR(port) (0x26d0+((port)<<10))
-#define MV643XX_ETH_TX_Q5_CURRENT_DESC_PTR(port) (0x26d4+((port)<<10))
-#define MV643XX_ETH_TX_Q6_CURRENT_DESC_PTR(port) (0x26d8+((port)<<10))
-#define MV643XX_ETH_TX_Q7_CURRENT_DESC_PTR(port) (0x26dc+((port)<<10))
-
-#define MV643XX_ETH_MAC_ADDR_LO(port) (0x2414+((port)<<10))
-#define MV643XX_ETH_MAC_ADDR_HI(port) (0x2418+((port)<<10))
-
-/* TYPE DEFINITIONS */
-
-/* just to make the purpose explicit; vars of this
- * type may need CPU-dependent address translation,
- * endian conversion etc.
- */
-typedef uint32_t Dma_addr_t;
-
-typedef volatile struct mveth_rx_desc {
-#ifndef __BIG_ENDIAN__
-#error "descriptor declaration not implemented for little endian machines"
-#endif
- uint16_t byte_cnt;
- uint16_t buf_size;
- uint32_t cmd_sts; /* control and status */
- Dma_addr_t next_desc_ptr; /* next descriptor (as seen from DMA) */
- Dma_addr_t buf_ptr;
- /* fields below here are not used by the chip */
- void *u_buf; /* user buffer */
- volatile struct mveth_rx_desc *next; /* next descriptor (CPU address; next_desc_ptr is a DMA address) */
- uint32_t pad[2];
-} __attribute__(( aligned(RING_ALIGNMENT) )) MvEthRxDescRec, *MvEthRxDesc;
-
-typedef volatile struct mveth_tx_desc {
-#ifndef __BIG_ENDIAN__
-#error "descriptor declaration not implemented for little endian machines"
-#endif
- uint16_t byte_cnt;
- uint16_t l4i_chk;
- uint32_t cmd_sts; /* control and status */
- Dma_addr_t next_desc_ptr; /* next descriptor (as seen from DMA) */
- Dma_addr_t buf_ptr;
- /* fields below here are not used by the chip */
- uint32_t workaround[2]; /* use this space to work around the 8byte problem (is this real?) */
- void *u_buf; /* user buffer */
- volatile struct mveth_tx_desc *next; /* next descriptor (CPU address; next_desc_ptr is a DMA address) */
-} __attribute__(( aligned(RING_ALIGNMENT) )) MvEthTxDescRec, *MvEthTxDesc;
-
-/* Assume there are never more then 64k aliasing entries */
-typedef uint16_t Mc_Refcnt[MV643XX_ETH_NUM_MCAST_ENTRIES*4];
-
-/* driver private data and bsdnet interface structure */
-struct mveth_private {
- MvEthRxDesc rx_ring; /* pointers to aligned ring area */
- MvEthTxDesc tx_ring; /* pointers to aligned ring area */
- MvEthRxDesc ring_area; /* allocated ring area */
- int rbuf_count, xbuf_count; /* saved ring sizes from ifconfig */
- int port_num;
- int phy;
- MvEthRxDesc d_rx_t; /* tail of the RX ring; next received packet */
- MvEthTxDesc d_tx_t, d_tx_h;
- uint32_t rx_desc_dma, tx_desc_dma; /* ring address as seen by DMA; (1:1 on this BSP) */
- int avail;
- void (*isr)(void*);
- void *isr_arg;
- /* Callbacks to handle buffers */
- void (*cleanup_txbuf)(void*, void*, int); /* callback to cleanup TX buffer */
- void *cleanup_txbuf_arg;
- void *(*alloc_rxbuf)(int *psize, uintptr_t *paddr); /* allocate RX buffer */
- void (*consume_rxbuf)(void*, void*, int); /* callback to consume RX buffer */
- void *consume_rxbuf_arg;
- rtems_id tid;
- uint32_t irq_mask; /* IRQs we use */
- uint32_t xirq_mask;
- int promisc;
- struct {
- unsigned irqs;
- unsigned maxchain;
- unsigned repack;
- unsigned packet;
- unsigned odrops; /* no counter in core code */
- struct {
- uint64_t good_octs_rcvd; /* 64-bit */
- uint32_t bad_octs_rcvd;
- uint32_t internal_mac_tx_err;
- uint32_t good_frames_rcvd;
- uint32_t bad_frames_rcvd;
- uint32_t bcast_frames_rcvd;
- uint32_t mcast_frames_rcvd;
- uint32_t frames_64_octs;
- uint32_t frames_65_127_octs;
- uint32_t frames_128_255_octs;
- uint32_t frames_256_511_octs;
- uint32_t frames_512_1023_octs;
- uint32_t frames_1024_max_octs;
- uint64_t good_octs_sent; /* 64-bit */
- uint32_t good_frames_sent;
- uint32_t excessive_coll;
- uint32_t mcast_frames_sent;
- uint32_t bcast_frames_sent;
- uint32_t unrec_mac_ctrl_rcvd;
- uint32_t fc_sent;
- uint32_t good_fc_rcvd;
- uint32_t bad_fc_rcvd;
- uint32_t undersize_rcvd;
- uint32_t fragments_rcvd;
- uint32_t oversize_rcvd;
- uint32_t jabber_rcvd;
- uint32_t mac_rx_err;
- uint32_t bad_crc_event;
- uint32_t coll;
- uint32_t late_coll;
- } mib;
- } stats;
- struct {
- Mc_Refcnt specl, other;
- } mc_refcnt;
-};
-
-/* stuff needed for bsdnet support */
-struct mveth_bsdsupp {
- int oif_flags; /* old / cached if_flags */
-};
-
-struct mveth_softc {
- struct arpcom arpcom;
- struct mveth_bsdsupp bsd;
- struct mveth_private pvt;
-};
-
-/* GLOBAL VARIABLES */
-#ifdef MVETH_DEBUG_TX_DUMP
-int mveth_tx_dump = 0;
-#endif
-
-/* THE array of driver/bsdnet structs */
-
-/* If detaching/module unloading is enabled, the main driver data
- * structure must remain in memory; hence it must reside in its own
- * 'dummy' module...
- */
-#ifdef MVETH_DETACH_HACK
-extern
-#else
-STATIC
-#endif
-struct mveth_softc theMvEths[MV643XXETH_NUM_DRIVER_SLOTS]
-#ifndef MVETH_DETACH_HACK
-= {{{{0}},}}
-#endif
-;
-
-/* daemon task id */
-STATIC rtems_id mveth_tid = 0;
-/* register access protection mutex */
-STATIC rtems_id mveth_mtx = 0;
-#define REGLOCK() do { \
- if ( RTEMS_SUCCESSFUL != rtems_semaphore_obtain(mveth_mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT) ) \
- rtems_panic(DRVNAME": unable to lock register protection mutex"); \
- } while (0)
-#define REGUNLOCK() rtems_semaphore_release(mveth_mtx)
-
-/* Format strings for statistics messages */
-static const char *mibfmt[] = {
- " GOOD_OCTS_RCVD: %"PRIu64"\n",
- 0,
- " BAD_OCTS_RCVD: %"PRIu32"\n",
- " INTERNAL_MAC_TX_ERR: %"PRIu32"\n",
- " GOOD_FRAMES_RCVD: %"PRIu32"\n",
- " BAD_FRAMES_RCVD: %"PRIu32"\n",
- " BCAST_FRAMES_RCVD: %"PRIu32"\n",
- " MCAST_FRAMES_RCVD: %"PRIu32"\n",
- " FRAMES_64_OCTS: %"PRIu32"\n",
- " FRAMES_65_127_OCTS: %"PRIu32"\n",
- " FRAMES_128_255_OCTS: %"PRIu32"\n",
- " FRAMES_256_511_OCTS: %"PRIu32"\n",
- " FRAMES_512_1023_OCTS:%"PRIu32"\n",
- " FRAMES_1024_MAX_OCTS:%"PRIu32"\n",
- " GOOD_OCTS_SENT: %"PRIu64"\n",
- 0,
- " GOOD_FRAMES_SENT: %"PRIu32"\n",
- " EXCESSIVE_COLL: %"PRIu32"\n",
- " MCAST_FRAMES_SENT: %"PRIu32"\n",
- " BCAST_FRAMES_SENT: %"PRIu32"\n",
- " UNREC_MAC_CTRL_RCVD: %"PRIu32"\n",
- " FC_SENT: %"PRIu32"\n",
- " GOOD_FC_RCVD: %"PRIu32"\n",
- " BAD_FC_RCVD: %"PRIu32"\n",
- " UNDERSIZE_RCVD: %"PRIu32"\n",
- " FRAGMENTS_RCVD: %"PRIu32"\n",
- " OVERSIZE_RCVD: %"PRIu32"\n",
- " JABBER_RCVD: %"PRIu32"\n",
- " MAC_RX_ERR: %"PRIu32"\n",
- " BAD_CRC_EVENT: %"PRIu32"\n",
- " COLL: %"PRIu32"\n",
- " LATE_COLL: %"PRIu32"\n",
-};
-
-/* Interrupt Handler Connection */
-
-/* forward decls + implementation for IRQ API funcs */
-
-static void mveth_isr(rtems_irq_hdl_param unit);
-static void mveth_isr_1(rtems_irq_hdl_param unit);
-static void noop(const rtems_irq_connect_data *unused) {}
-static int noop1(const rtems_irq_connect_data *unused) { return 0; }
-
-static rtems_irq_connect_data irq_data[MAX_NUM_SLOTS] = {
- {
- BSP_IRQ_ETH0,
- 0,
- (rtems_irq_hdl_param)0,
- noop,
- noop,
- noop1
- },
- {
- BSP_IRQ_ETH1,
- 0,
- (rtems_irq_hdl_param)1,
- noop,
- noop,
- noop1
- },
- {
- BSP_IRQ_ETH2,
- 0,
- (rtems_irq_hdl_param)2,
- noop,
- noop,
- noop1
- },
-};
-
-/* MII Ioctl Interface */
-
-STATIC unsigned
-mveth_mii_read(struct mveth_private *mp, unsigned addr);
-
-STATIC unsigned
-mveth_mii_write(struct mveth_private *mp, unsigned addr, unsigned v);
-
-
-/* mdio / mii interface wrappers for rtems_mii_ioctl API */
-
-static int mveth_mdio_r(int phy, void *uarg, unsigned reg, uint32_t *pval)
-{
- if ( phy > 1 )
- return -1;
-
- *pval = mveth_mii_read(uarg, reg);
- return 0;
-}
-
-static int mveth_mdio_w(int phy, void *uarg, unsigned reg, uint32_t val)
-{
- if ( phy > 1 )
- return -1;
- mveth_mii_write(uarg, reg, val);
- return 0;
-}
-
-static struct rtems_mdio_info mveth_mdio = {
- mdio_r: mveth_mdio_r,
- mdio_w: mveth_mdio_w,
- has_gmii: 1,
-};
-
-/* LOW LEVEL SUPPORT ROUTINES */
-
-/* Software Cache Coherency */
-#ifndef ENABLE_HW_SNOOPING
-#ifndef __PPC__
-#error "Software cache coherency maintenance is not implemented for your CPU architecture"
-#endif
-
-static inline unsigned INVAL_DESC(volatile void *d)
-{
-typedef const char cache_line[PPC_CACHE_ALIGNMENT];
- asm volatile("dcbi 0, %1":"=m"(*(cache_line*)d):"r"(d));
- return (unsigned)d; /* so this can be used in comma expression */
-}
-
-static inline void FLUSH_DESC(volatile void *d)
-{
-typedef const char cache_line[PPC_CACHE_ALIGNMENT];
- asm volatile("dcbf 0, %0"::"r"(d),"m"(*(cache_line*)d));
-}
-
-static inline void FLUSH_BARRIER(void)
-{
- asm volatile("eieio");
-}
-
-/* RX buffers are always cache-line aligned
- * ASSUMPTIONS:
- * - 'addr' is cache aligned
- * - len is a multiple >0 of cache lines
- */
-static inline void INVAL_BUF(register uintptr_t addr, register int len)
-{
-typedef char maxbuf[2048]; /* more than an ethernet packet */
- do {
- len -= RX_BUF_ALIGNMENT;
- asm volatile("dcbi %0, %1"::"b"(addr),"r"(len));
- } while (len > 0);
- asm volatile("":"=m"(*(maxbuf*)addr));
-}
-
-/* Flushing TX buffers is a little bit trickier; we don't really know their
- * alignment but *assume* adjacent addresses are covering 'ordinary' memory
- * so that flushing them does no harm!
- */
-static inline void FLUSH_BUF(register uintptr_t addr, register int len)
-{
- asm volatile("":::"memory");
- len = MV643XX_ALIGN(len, RX_BUF_ALIGNMENT);
- do {
- asm volatile("dcbf %0, %1"::"b"(addr),"r"(len));
- len -= RX_BUF_ALIGNMENT;
- } while ( len >= 0 );
-}
-
-#else /* hardware snooping enabled */
-
-/* inline this to silence compiler warnings */
-static inline int INVAL_DESC(volatile void *d)
-{ return 0; }
-
-#define FLUSH_DESC(d) NOOP()
-#define INVAL_BUF(b,l) NOOP()
-#define FLUSH_BUF(b,l) NOOP()
-#define FLUSH_BARRIER() NOOP()
-
-#endif /* cache coherency support */
-
-/* Synchronize memory access */
-#ifdef __PPC__
-static inline void membarrier(void)
-{
- asm volatile("sync":::"memory");
-}
-#else
-#error "memory barrier instruction not defined (yet) for this CPU"
-#endif
-
-/* Enable and disable interrupts at the device */
-static inline void
-mveth_enable_irqs(struct mveth_private *mp, uint32_t mask)
-{
-rtems_interrupt_level l;
-uint32_t val;
- rtems_interrupt_disable(l);
-
- val = MV_READ(MV643XX_ETH_INTERRUPT_ENBL_R(mp->port_num));
- val = (val | mask | MV643XX_ETH_IRQ_EXT_ENA) & mp->irq_mask;
-
- MV_WRITE(MV643XX_ETH_INTERRUPT_ENBL_R(mp->port_num), val);
-
- val = MV_READ(MV643XX_ETH_INTERRUPT_EXTEND_ENBL_R(mp->port_num));
- val = (val | mask) & mp->xirq_mask;
- MV_WRITE(MV643XX_ETH_INTERRUPT_EXTEND_ENBL_R(mp->port_num), val);
-
- rtems_interrupt_enable(l);
-}
-
-static inline uint32_t
-mveth_disable_irqs(struct mveth_private *mp, uint32_t mask)
-{
-rtems_interrupt_level l;
-uint32_t val,xval,tmp;
- rtems_interrupt_disable(l);
-
- val = MV_READ(MV643XX_ETH_INTERRUPT_ENBL_R(mp->port_num));
- tmp = ( (val & ~mask) | MV643XX_ETH_IRQ_EXT_ENA ) & mp->irq_mask;
- MV_WRITE(MV643XX_ETH_INTERRUPT_ENBL_R(mp->port_num), tmp);
-
- xval = MV_READ(MV643XX_ETH_INTERRUPT_EXTEND_ENBL_R(mp->port_num));
- tmp = (xval & ~mask) & mp->xirq_mask;
- MV_WRITE(MV643XX_ETH_INTERRUPT_EXTEND_ENBL_R(mp->port_num), tmp);
-
- rtems_interrupt_enable(l);
-
- return (val | xval);
-}
-
-/* This should be safe even w/o turning off interrupts if multiple
- * threads ack different bits in the cause register (and ignore
- * other ones) since writing 'ones' into the cause register doesn't
- * 'stick'.
- */
-
-static inline uint32_t
-mveth_ack_irqs(struct mveth_private *mp, uint32_t mask)
-{
-register uint32_t x,xe,p;
-
- p = mp->port_num;
- /* Get cause */
- x = MV_READ(MV643XX_ETH_INTERRUPT_CAUSE_R(p));
-
- /* Ack interrupts filtering the ones we're interested in */
-
- /* Note: EXT_IRQ bit clears by itself if EXT interrupts are cleared */
- MV_WRITE(MV643XX_ETH_INTERRUPT_CAUSE_R(p), ~ (x & mp->irq_mask & mask));
-
- /* linux driver tests 1<<1 as a summary bit for extended interrupts;
- * the mv64360 seems to use 1<<19 for that purpose; for the moment,
- * I just check both.
- * Update: link status irq (1<<16 in xe) doesn't set (1<<19) in x!
- */
- if ( 1 /* x & 2 */ )
- {
- xe = MV_READ(MV643XX_ETH_INTERRUPT_EXTEND_CAUSE_R(p));
-
- MV_WRITE(MV643XX_ETH_INTERRUPT_EXTEND_CAUSE_R(p), ~ (xe & mp->xirq_mask & mask));
- } else {
- xe = 0;
- }
-#ifdef MVETH_TESTING
- if ( ((x & MV643XX_ETH_ALL_IRQS) & ~MV643XX_ETH_KNOWN_IRQS)
- || ((xe & MV643XX_ETH_ALL_EXT_IRQS) & ~MV643XX_ETH_KNOWN_EXT_IRQS) ) {
- fprintf(stderr, "Unknown IRQs detected; leaving all disabled for debugging:\n");
- fprintf(stderr, "Cause reg was 0x%08x, ext cause 0x%08x\n", x, xe);
- mp->irq_mask = 0;
- mp->xirq_mask = 0;
- }
-#endif
- /* luckily, the extended and 'normal' interrupts we use don't overlap so
- * we can just OR them into a single word
- */
- return (xe & mp->xirq_mask) | (x & mp->irq_mask);
-}
-
-static void mveth_isr(rtems_irq_hdl_param arg)
-{
-unsigned unit = (unsigned)arg;
- mveth_disable_irqs(&theMvEths[unit].pvt, -1);
- theMvEths[unit].pvt.stats.irqs++;
- rtems_bsdnet_event_send( theMvEths[unit].pvt.tid, 1<<unit );
-}
-
-static void mveth_isr_1(rtems_irq_hdl_param arg)
-{
-unsigned unit = (unsigned)arg;
-struct mveth_private *mp = &theMvEths[unit].pvt;
-
- mp->stats.irqs++;
- mp->isr(mp->isr_arg);
-}
-
-static void
-mveth_clear_mib_counters(struct mveth_private *mp)
-{
-register int i;
-register uint32_t b;
- /* reading the counters resets them */
- b = MV643XX_ETH_MIB_COUNTERS(mp->port_num);
- for (i=0; i< MV643XX_ETH_NUM_MIB_COUNTERS; i++, b+=4)
- (void)MV_READ(b);
-}
-
-/* Reading a MIB register also clears it. Hence we read the lo
- * register first, then the hi one. Correct reading is guaranteed since
- * the 'lo' register cannot overflow after it is read since it had
- * been reset to 0.
- */
-static unsigned long long
-read_long_mib_counter(int port_num, int idx)
-{
-unsigned long lo;
-unsigned long long hi;
- lo = MV_READ(MV643XX_ETH_MIB_COUNTERS(port_num)+(idx<<2));
- idx++;
- hi = MV_READ(MV643XX_ETH_MIB_COUNTERS(port_num)+(idx<<2));
- return (hi<<32) | lo;
-}
-
-static inline unsigned long
-read_mib_counter(int port_num, int idx)
-{
- return MV_READ(MV643XX_ETH_MIB_COUNTERS(port_num)+(idx<<2));
-}
-
-
-/* write ethernet address from buffer to hardware (need to change unicast filter after this) */
-static void
-mveth_write_eaddr(struct mveth_private *mp, unsigned char *eaddr)
-{
-int i;
-uint32_t x;
-
- /* build hi word */
- for (i=4,x=0; i; i--, eaddr++) {
- x = (x<<8) | *eaddr;
- }
- MV_WRITE(MV643XX_ETH_MAC_ADDR_HI(mp->port_num), x);
-
- /* build lo word */
- for (i=2,x=0; i; i--, eaddr++) {
- x = (x<<8) | *eaddr;
- }
- MV_WRITE(MV643XX_ETH_MAC_ADDR_LO(mp->port_num), x);
-}
-
-/* PHY/MII Interface
- *
- * Read/write a PHY register;
- *
- * NOTE: The SMI register is shared among the three devices.
- * Protection is provided by the global networking semaphore.
- * If non-bsd drivers are running on a subset of IFs proper
- * locking of all shared registers must be implemented!
- */
-STATIC unsigned
-mveth_mii_read(struct mveth_private *mp, unsigned addr)
-{
-unsigned v;
-unsigned wc = 0;
-
- addr &= 0x1f;
-
- /* wait until not busy */
- do {
- v = MV_READ(MV643XX_ETH_SMI_R);
- wc++;
- } while ( MV643XX_ETH_SMI_BUSY & v );
-
- MV_WRITE(MV643XX_ETH_SMI_R, (addr <<21 ) | (mp->phy<<16) | MV643XX_ETH_SMI_OP_RD );
-
- do {
- v = MV_READ(MV643XX_ETH_SMI_R);
- wc++;
- } while ( MV643XX_ETH_SMI_BUSY & v );
-
- if (wc>0xffff)
- wc = 0xffff;
- return (wc<<16) | (v & 0xffff);
-}
-
-STATIC unsigned
-mveth_mii_write(struct mveth_private *mp, unsigned addr, unsigned v)
-{
-unsigned wc = 0;
-
- addr &= 0x1f;
- v &= 0xffff;
-
- /* busywait is ugly but not preventing ISRs or high priority tasks from
- * preempting us
- */
-
- /* wait until not busy */
- while ( MV643XX_ETH_SMI_BUSY & MV_READ(MV643XX_ETH_SMI_R) )
- wc++ /* wait */;
-
- MV_WRITE(MV643XX_ETH_SMI_R, (addr <<21 ) | (mp->phy<<16) | MV643XX_ETH_SMI_OP_WR | v );
-
- return wc;
-}
-
-/* MID-LAYER SUPPORT ROUTINES */
-
-/* Start TX if descriptors are exhausted */
-static __inline__ void
-mveth_start_tx(struct mveth_private *mp)
-{
-uint32_t running;
- if ( mp->avail <= 0 ) {
- running = MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(mp->port_num));
- if ( ! (running & MV643XX_ETH_TX_START(0)) ) {
- MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(mp->port_num), MV643XX_ETH_TX_START(0));
- }
- }
-}
-
-/* Stop TX and wait for the command queues to stop and the fifo to drain */
-static uint32_t
-mveth_stop_tx(int port)
-{
-uint32_t active_q;
-
- active_q = (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(port)) & MV643XX_ETH_TX_ANY_RUNNING);
-
- if ( active_q ) {
- /* Halt TX and wait for activity to stop */
- MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(port), MV643XX_ETH_TX_STOP_ALL);
- while ( MV643XX_ETH_TX_ANY_RUNNING & MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(port)) )
- /* poll-wait */;
- /* Wait for Tx FIFO to drain */
- while ( ! (MV643XX_ETH_PORT_STATUS_R(port) & MV643XX_ETH_PORT_STATUS_TX_FIFO_EMPTY) )
- /* poll-wait */;
- }
-
- return active_q;
-}
-
-/* update serial port settings from current link status */
-static void
-mveth_update_serial_port(struct mveth_private *mp, int media)
-{
-int port = mp->port_num;
-uint32_t old, new;
-
- new = old = MV_READ(MV643XX_ETH_SERIAL_CONTROL_R(port));
-
- /* mask speed and duplex settings */
- new &= ~( MV643XX_ETH_SET_GMII_SPEED_1000
- | MV643XX_ETH_SET_MII_SPEED_100
- | MV643XX_ETH_SET_FULL_DUPLEX );
-
- if ( IFM_FDX & media )
- new |= MV643XX_ETH_SET_FULL_DUPLEX;
-
- switch ( IFM_SUBTYPE(media) ) {
- default: /* treat as 10 */
- break;
- case IFM_100_TX:
- new |= MV643XX_ETH_SET_MII_SPEED_100;
- break;
- case IFM_1000_T:
- new |= MV643XX_ETH_SET_GMII_SPEED_1000;
- break;
- }
-
- if ( new != old ) {
- if ( ! (MV643XX_ETH_SERIAL_PORT_ENBL & new) ) {
- /* just write */
- MV_WRITE(MV643XX_ETH_SERIAL_CONTROL_R(port), new);
- } else {
- uint32_t were_running;
-
- were_running = mveth_stop_tx(port);
-
- old &= ~MV643XX_ETH_SERIAL_PORT_ENBL;
- MV_WRITE(MV643XX_ETH_SERIAL_CONTROL_R(port), old);
- MV_WRITE(MV643XX_ETH_SERIAL_CONTROL_R(port), new);
- /* linux driver writes twice... */
- MV_WRITE(MV643XX_ETH_SERIAL_CONTROL_R(port), new);
-
- if ( were_running ) {
- MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(mp->port_num), MV643XX_ETH_TX_START(0));
- }
- }
- }
-}
-
-/* Clear multicast filters */
-void
-BSP_mve_mcast_filter_clear(struct mveth_private *mp)
-{
-int i;
-register uint32_t s,o;
-uint32_t v = mp->promisc ? 0x01010101 : 0x00000000;
- s = MV643XX_ETH_DA_FILTER_SPECL_MCAST_TBL(mp->port_num);
- o = MV643XX_ETH_DA_FILTER_OTHER_MCAST_TBL(mp->port_num);
- for (i=0; i<MV643XX_ETH_NUM_MCAST_ENTRIES; i++) {
- MV_WRITE(s,v);
- MV_WRITE(o,v);
- s+=4;
- o+=4;
- }
- for (i=0; i<sizeof(mp->mc_refcnt.specl)/sizeof(mp->mc_refcnt.specl[0]); i++) {
- mp->mc_refcnt.specl[i] = 0;
- mp->mc_refcnt.other[i] = 0;
- }
-}
-
-void
-BSP_mve_mcast_filter_accept_all(struct mveth_private *mp)
-{
-int i;
-register uint32_t s,o;
- s = MV643XX_ETH_DA_FILTER_SPECL_MCAST_TBL(mp->port_num);
- o = MV643XX_ETH_DA_FILTER_OTHER_MCAST_TBL(mp->port_num);
- for (i=0; i<MV643XX_ETH_NUM_MCAST_ENTRIES; i++) {
- MV_WRITE(s,0x01010101);
- MV_WRITE(o,0x01010101);
- s+=4;
- o+=4;
- /* Not clear what we should do with the reference count.
- * For now just increment it.
- */
- for (i=0; i<sizeof(mp->mc_refcnt.specl)/sizeof(mp->mc_refcnt.specl[0]); i++) {
- mp->mc_refcnt.specl[i]++;
- mp->mc_refcnt.other[i]++;
- }
- }
-}
-
-static void add_entry(uint32_t off, uint8_t hash, Mc_Refcnt *refcnt)
-{
-uint32_t val;
-uint32_t slot = hash & 0xfc;
-
- if ( 0 == (*refcnt)[hash]++ ) {
- val = MV_READ(off+slot) | ( 1 << ((hash&3)<<3) );
- MV_WRITE(off+slot, val);
- }
-}
-
-static void del_entry(uint32_t off, uint8_t hash, Mc_Refcnt *refcnt)
-{
-uint32_t val;
-uint32_t slot = hash & 0xfc;
-
- if ( (*refcnt)[hash] > 0 && 0 == --(*refcnt)[hash] ) {
- val = MV_READ(off+slot) & ~( 1 << ((hash&3)<<3) );
- MV_WRITE(off+slot, val);
- }
-}
-
-void
-BSP_mve_mcast_filter_accept_add(struct mveth_private *mp, unsigned char *enaddr)
-{
-uint32_t hash;
-static const char spec[]={0x01,0x00,0x5e,0x00,0x00};
-static const char bcst[]={0xff,0xff,0xff,0xff,0xff,0xff};
-uint32_t tabl;
-Mc_Refcnt *refcnt;
-
- if ( ! (0x01 & enaddr[0]) ) {
- /* not a multicast address; ignore */
- return;
- }
-
- if ( 0 == memcmp(enaddr, bcst, sizeof(bcst)) ) {
- /* broadcast address; ignore */
- return;
- }
-
- if ( 0 == memcmp(enaddr, spec, sizeof(spec)) ) {
- hash = enaddr[5];
- tabl = MV643XX_ETH_DA_FILTER_SPECL_MCAST_TBL(mp->port_num);
- refcnt = &mp->mc_refcnt.specl;
- } else {
- uint32_t test, mask;
- int i;
- /* algorithm used by linux driver */
- for ( hash=0, i=0; i<6; i++ ) {
- hash = (hash ^ enaddr[i]) << 8;
- for ( test=0x8000, mask=0x8380; test>0x0080; test>>=1, mask>>=1 ) {
- if ( hash & test )
- hash ^= mask;
- }
- }
- tabl = MV643XX_ETH_DA_FILTER_OTHER_MCAST_TBL(mp->port_num);
- refcnt = &mp->mc_refcnt.other;
- }
- add_entry(tabl, hash, refcnt);
-}
-
-void
-BSP_mve_mcast_filter_accept_del(struct mveth_private *mp, unsigned char *enaddr)
-{
-uint32_t hash;
-static const char spec[]={0x01,0x00,0x5e,0x00,0x00};
-static const char bcst[]={0xff,0xff,0xff,0xff,0xff,0xff};
-uint32_t tabl;
-Mc_Refcnt *refcnt;
-
- if ( ! (0x01 & enaddr[0]) ) {
- /* not a multicast address; ignore */
- return;
- }
-
- if ( 0 == memcmp(enaddr, bcst, sizeof(bcst)) ) {
- /* broadcast address; ignore */
- return;
- }
-
- if ( 0 == memcmp(enaddr, spec, sizeof(spec)) ) {
- hash = enaddr[5];
- tabl = MV643XX_ETH_DA_FILTER_SPECL_MCAST_TBL(mp->port_num);
- refcnt = &mp->mc_refcnt.specl;
- } else {
- uint32_t test, mask;
- int i;
- /* algorithm used by linux driver */
- for ( hash=0, i=0; i<6; i++ ) {
- hash = (hash ^ enaddr[i]) << 8;
- for ( test=0x8000, mask=0x8380; test>0x0080; test>>=1, mask>>=1 ) {
- if ( hash & test )
- hash ^= mask;
- }
- }
- tabl = MV643XX_ETH_DA_FILTER_OTHER_MCAST_TBL(mp->port_num);
- refcnt = &mp->mc_refcnt.other;
- }
- del_entry(tabl, hash, refcnt);
-}
-
-/* Clear all address filters (multi- and unicast) */
-static void
-mveth_clear_addr_filters(struct mveth_private *mp)
-{
-register int i;
-register uint32_t u;
- u = MV643XX_ETH_DA_FILTER_UNICAST_TBL(mp->port_num);
- for (i=0; i<MV643XX_ETH_NUM_UNICAST_ENTRIES; i++) {
- MV_WRITE(u,0);
- u+=4;
- }
- BSP_mve_mcast_filter_clear(mp);
-}
-
-/* Setup unicast filter for a given MAC address (least significant nibble) */
-static void
-mveth_ucfilter(struct mveth_private *mp, unsigned char mac_lsbyte, int accept)
-{
-unsigned nib, slot, bit;
-uint32_t val;
- /* compute slot in table */
- nib = mac_lsbyte & 0xf; /* strip nibble */
- slot = nib & ~3; /* (nibble/4)*4 */
- bit = (nib & 3)<<3; /* 8*(nibble % 4) */
- val = MV_READ(MV643XX_ETH_DA_FILTER_UNICAST_TBL(mp->port_num) + slot);
- if ( accept ) {
- val |= 0x01 << bit;
- } else {
- val &= 0x0e << bit;
- }
- MV_WRITE(MV643XX_ETH_DA_FILTER_UNICAST_TBL(mp->port_num) + slot, val);
-}
-
-#if defined( ENABLE_TX_WORKAROUND_8_BYTE_PROBLEM ) && 0
-/* Currently unused; small unaligned buffers seem to be rare
- * so we just use memcpy()...
- */
-
-/* memcpy for 0..7 bytes; arranged so that gcc
- * optimizes for powerpc...
- */
-
-static inline void memcpy8(void *to, void *fr, unsigned x)
-{
-register uint8_t *d = to, *s = fro;
-
- d+=l; s+=l;
- if ( l & 1 ) {
- *--d=*--s;
- }
- if ( l & 2 ) {
- /* pre-decrementing causes gcc to use auto-decrementing
- * PPC instructions (lhzu rx, -2(ry))
- */
- d-=2; s-=2;
- /* use memcpy; don't cast to short -- accessing
- * misaligned data as short is not portable
- * (but it works on PPC).
- */
- __builtin_memcpy(d,s,2);
- }
- if ( l & 4 ) {
- d-=4; s-=4;
- /* see above */
- __builtin_memcpy(d,s,4);
- }
-}
-#endif
-
-/* Assign values (buffer + user data) to a tx descriptor slot */
-static int
-mveth_assign_desc(MvEthTxDesc d, struct mbuf *m, unsigned long extra)
-{
-int rval = (d->byte_cnt = m->m_len);
-
-#ifdef MVETH_TESTING
- assert( !d->mb );
- assert( m->m_len );
-#endif
-
- /* set CRC on all descriptors; seems to be necessary */
- d->cmd_sts = extra | (TDESC_GEN_CRC | TDESC_ZERO_PAD);
-
-#ifdef ENABLE_TX_WORKAROUND_8_BYTE_PROBLEM
- /* The buffer must be 64bit aligned if the payload is <8 (??) */
- if ( rval < 8 && ((mtod(m, uintptr_t)) & 7) ) {
- d->buf_ptr = CPUADDR2ENET( d->workaround );
- memcpy((void*)d->workaround, mtod(m, void*), rval);
- } else
-#endif
- {
- d->buf_ptr = CPUADDR2ENET( mtod(m, unsigned long) );
- }
- d->l4i_chk = 0;
- return rval;
-}
-
-static int
-mveth_assign_desc_raw(MvEthTxDesc d, void *buf, int len, unsigned long extra)
-{
-int rval = (d->byte_cnt = len);
-
-#ifdef MVETH_TESTING
- assert( !d->u_buf );
- assert( len );
-#endif
-
- /* set CRC on all descriptors; seems to be necessary */
- d->cmd_sts = extra | (TDESC_GEN_CRC | TDESC_ZERO_PAD);
-
-#ifdef ENABLE_TX_WORKAROUND_8_BYTE_PROBLEM
- /* The buffer must be 64bit aligned if the payload is <8 (??) */
- if ( rval < 8 && ( ((uintptr_t)buf) & 7) ) {
- d->buf_ptr = CPUADDR2ENET( d->workaround );
- memcpy((void*)d->workaround, buf, rval);
- } else
-#endif
- {
- d->buf_ptr = CPUADDR2ENET( (unsigned long)buf );
- }
- d->l4i_chk = 0;
- return rval;
-}
-
-/*
- * Ring Initialization
- *
- * ENDIAN ASSUMPTION: DMA engine matches CPU endianness (???)
- *
- * Linux driver discriminates __LITTLE and __BIG endian for re-arranging
- * the u16 fields in the descriptor structs. However, no endian conversion
- * is done on the individual fields (SDMA byte swapping is disabled on LE).
- */
-
-STATIC int
-mveth_init_rx_desc_ring(struct mveth_private *mp)
-{
-int i,sz;
-MvEthRxDesc d;
-uintptr_t baddr;
-
- memset((void*)mp->rx_ring, 0, sizeof(*mp->rx_ring)*mp->rbuf_count);
-
- mp->rx_desc_dma = CPUADDR2ENET(mp->rx_ring);
-
- for ( i=0, d = mp->rx_ring; i<mp->rbuf_count; i++, d++ ) {
- d->u_buf = mp->alloc_rxbuf(&sz, &baddr);
- assert( d->u_buf );
-
-#ifndef ENABLE_HW_SNOOPING
- /* could reduce the area to max. ethernet packet size */
- INVAL_BUF(baddr, sz);
-#endif
-
- d->buf_size = sz;
- d->byte_cnt = 0;
- d->cmd_sts = RDESC_DMA_OWNED | RDESC_INT_ENA;
- d->next = mp->rx_ring + (i+1) % mp->rbuf_count;
-
- d->buf_ptr = CPUADDR2ENET( baddr );
- d->next_desc_ptr = CPUADDR2ENET(d->next);
- FLUSH_DESC(d);
- }
- FLUSH_BARRIER();
-
- mp->d_rx_t = mp->rx_ring;
-
- /* point the chip to the start of the ring */
- MV_WRITE(MV643XX_ETH_RX_Q0_CURRENT_DESC_PTR(mp->port_num),mp->rx_desc_dma);
-
-
- return i;
-}
-
-STATIC int
-mveth_init_tx_desc_ring(struct mveth_private *mp)
-{
-int i;
-MvEthTxDesc d;
-
- memset((void*)mp->tx_ring, 0, sizeof(*mp->tx_ring)*mp->xbuf_count);
-
- /* DMA and CPU live in the same address space (rtems) */
- mp->tx_desc_dma = CPUADDR2ENET(mp->tx_ring);
- mp->avail = TX_AVAILABLE_RING_SIZE(mp);
-
- for ( i=0, d=mp->tx_ring; i<mp->xbuf_count; i++,d++ ) {
- d->l4i_chk = 0;
- d->byte_cnt = 0;
- d->cmd_sts = 0;
- d->buf_ptr = 0;
-
- d->next = mp->tx_ring + (i+1) % mp->xbuf_count;
- d->next_desc_ptr = CPUADDR2ENET(d->next);
- FLUSH_DESC(d);
- }
- FLUSH_BARRIER();
-
- mp->d_tx_h = mp->d_tx_t = mp->tx_ring;
-
- /* point the chip to the start of the ring */
- MV_WRITE(MV643XX_ETH_TX_Q0_CURRENT_DESC_PTR(mp->port_num),mp->tx_desc_dma);
-
- return i;
-}
-
-/* PUBLIC LOW-LEVEL DRIVER ACCESS */
-
-static struct mveth_private *
-mve_setup_internal(
- int unit,
- rtems_id tid,
- void (*isr)(void*isr_arg),
- void *isr_arg,
- void (*cleanup_txbuf)(void *user_buf, void *closure, int error_on_tx_occurred),
- void *cleanup_txbuf_arg,
- void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
- void (*consume_rxbuf)(void *user_buf, void *closure, int len),
- void *consume_rxbuf_arg,
- int rx_ring_size,
- int tx_ring_size,
- int irq_mask
-)
-
-{
-struct mveth_private *mp;
-struct ifnet *ifp;
-int InstallISRSuccessful;
-
- if ( unit <= 0 || unit > MV643XXETH_NUM_DRIVER_SLOTS ) {
- printk(DRVNAME": Bad unit number %i; must be 1..%i\n", unit, MV643XXETH_NUM_DRIVER_SLOTS);
- return 0;
- }
- ifp = &theMvEths[unit-1].arpcom.ac_if;
- if ( ifp->if_init ) {
- if ( ifp->if_init ) {
- printk(DRVNAME": instance %i already attached.\n", unit);
- return 0;
- }
- }
-
- if ( rx_ring_size < 0 && tx_ring_size < 0 )
- return 0;
-
- if ( MV_64360 != BSP_getDiscoveryVersion(0) ) {
- printk(DRVNAME": not mv64360 chip\n");
- return 0;
- }
-
- /* lazy init of mutex (non thread-safe! - we assume 1st initialization is single-threaded) */
- if ( ! mveth_mtx ) {
- rtems_status_code sc;
- sc = rtems_semaphore_create(
- rtems_build_name('m','v','e','X'),
- 1,
- RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY | RTEMS_DEFAULT_ATTRIBUTES,
- 0,
- &mveth_mtx);
- if ( RTEMS_SUCCESSFUL != sc ) {
- rtems_error(sc,DRVNAME": creating mutex\n");
- rtems_panic("unable to proceed\n");
- }
- }
-
- mp = &theMvEths[unit-1].pvt;
-
- memset(mp, 0, sizeof(*mp));
-
- mp->port_num = unit-1;
- mp->phy = (MV_READ(MV643XX_ETH_PHY_ADDR_R) >> (5*mp->port_num)) & 0x1f;
-
- mp->tid = tid;
- mp->isr = isr;
- mp->isr_arg = isr_arg;
-
- mp->cleanup_txbuf = cleanup_txbuf;
- mp->cleanup_txbuf_arg = cleanup_txbuf_arg;
- mp->alloc_rxbuf = alloc_rxbuf;
- mp->consume_rxbuf = consume_rxbuf;
- mp->consume_rxbuf_arg = consume_rxbuf_arg;
-
- mp->rbuf_count = rx_ring_size ? rx_ring_size : MV643XX_RX_RING_SIZE;
- mp->xbuf_count = tx_ring_size ? tx_ring_size : MV643XX_TX_RING_SIZE;
-
- if ( mp->xbuf_count > 0 )
- mp->xbuf_count += TX_NUM_TAG_SLOTS;
-
- if ( mp->rbuf_count < 0 )
- mp->rbuf_count = 0;
- if ( mp->xbuf_count < 0 )
- mp->xbuf_count = 0;
-
- /* allocate ring area; add 1 entry -- room for alignment */
- assert( !mp->ring_area );
- mp->ring_area = malloc(
- sizeof(*mp->ring_area) *
- (mp->rbuf_count + mp->xbuf_count + 1),
- M_DEVBUF,
- M_WAIT );
- assert( mp->ring_area );
-
- BSP_mve_stop_hw(mp);
-
- if ( irq_mask ) {
- irq_data[mp->port_num].hdl = tid ? mveth_isr : mveth_isr_1;
- InstallISRSuccessful = BSP_install_rtems_irq_handler( &irq_data[mp->port_num] );
- assert( InstallISRSuccessful );
- }
-
- /* mark as used */
- ifp->if_init = (void*)(-1);
-
- if ( rx_ring_size < 0 )
- irq_mask &= ~ MV643XX_ETH_IRQ_RX_DONE;
- if ( tx_ring_size < 0 )
- irq_mask &= ~ MV643XX_ETH_EXT_IRQ_TX_DONE;
-
- mp->irq_mask = (irq_mask & MV643XX_ETH_IRQ_RX_DONE);
- if ( (irq_mask &= (MV643XX_ETH_EXT_IRQ_TX_DONE | MV643XX_ETH_EXT_IRQ_LINK_CHG)) ) {
- mp->irq_mask |= MV643XX_ETH_IRQ_EXT_ENA;
- mp->xirq_mask = irq_mask;
- } else {
- mp->xirq_mask = 0;
- }
-
- return mp;
-}
-
-struct mveth_private *
-BSP_mve_setup(
- int unit,
- rtems_id tid,
- void (*cleanup_txbuf)(void *user_buf, void *closure, int error_on_tx_occurred),
- void *cleanup_txbuf_arg,
- void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
- void (*consume_rxbuf)(void *user_buf, void *closure, int len),
- void *consume_rxbuf_arg,
- int rx_ring_size,
- int tx_ring_size,
- int irq_mask
-)
-{
- if ( irq_mask && 0 == tid ) {
- printk(DRVNAME": must supply a TID if irq_msk not zero\n");
- return 0;
- }
-
- return mve_setup_internal(
- unit,
- tid,
- 0, 0,
- cleanup_txbuf, cleanup_txbuf_arg,
- alloc_rxbuf,
- consume_rxbuf, consume_rxbuf_arg,
- rx_ring_size, tx_ring_size,
- irq_mask);
-}
-
-struct mveth_private *
-BSP_mve_setup_1(
- int unit,
- void (*isr)(void *isr_arg),
- void *isr_arg,
- void (*cleanup_txbuf)(void *user_buf, void *closure, int error_on_tx_occurred),
- void *cleanup_txbuf_arg,
- void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
- void (*consume_rxbuf)(void *user_buf, void *closure, int len),
- void *consume_rxbuf_arg,
- int rx_ring_size,
- int tx_ring_size,
- int irq_mask
-)
-{
- if ( irq_mask && 0 == isr ) {
- printk(DRVNAME": must supply an ISR if irq_msk not zero\n");
- return 0;
- }
-
- return mve_setup_internal(
- unit,
- 0,
- isr, isr_arg,
- cleanup_txbuf, cleanup_txbuf_arg,
- alloc_rxbuf,
- consume_rxbuf, consume_rxbuf_arg,
- rx_ring_size, tx_ring_size,
- irq_mask);
-}
-
-rtems_id
-BSP_mve_get_tid(struct mveth_private *mp)
-{
- return mp->tid;
-}
-
-int
-BSP_mve_detach(struct mveth_private *mp)
-{
-int unit = mp->port_num;
- BSP_mve_stop_hw(mp);
- if ( mp->irq_mask || mp->xirq_mask ) {
- if ( !BSP_remove_rtems_irq_handler( &irq_data[mp->port_num] ) )
- return -1;
- }
- free( (void*)mp->ring_area, M_DEVBUF );
- memset(mp, 0, sizeof(*mp));
- __asm__ __volatile__("":::"memory");
- /* mark as unused */
- theMvEths[unit].arpcom.ac_if.if_init = 0;
- return 0;
-}
-
-/* MAIN RX-TX ROUTINES
- *
- * BSP_mve_swipe_tx(): descriptor scavenger; releases mbufs
- * BSP_mve_send_buf(): xfer mbufs from IF to chip
- * BSP_mve_swipe_rx(): enqueue received mbufs to interface
- * allocate new ones and yield them to the
- * chip.
- */
-
-/* clean up the TX ring freeing up buffers */
-int
-BSP_mve_swipe_tx(struct mveth_private *mp)
-{
-int rval = 0;
-register MvEthTxDesc d;
-
- for ( d = mp->d_tx_t; d->buf_ptr; d = NEXT_TXD(d) ) {
-
- INVAL_DESC(d);
-
- if ( (TDESC_DMA_OWNED & d->cmd_sts)
- && (uint32_t)d == MV_READ(MV643XX_ETH_CURRENT_SERVED_TX_DESC(mp->port_num)) )
- break;
-
- /* d->u_buf is only set on the last descriptor in a chain;
- * we only count errors in the last descriptor;
- */
- if ( d->u_buf ) {
- mp->cleanup_txbuf(d->u_buf, mp->cleanup_txbuf_arg, (d->cmd_sts & TDESC_ERROR) ? 1 : 0);
- d->u_buf = 0;
- }
-
- d->buf_ptr = 0;
-
- rval++;
- }
- mp->d_tx_t = d;
- mp->avail += rval;
-
- return rval;
-}
-
-/* allocate a new cluster and copy an existing chain there;
- * old chain is released...
- */
-static struct mbuf *
-repackage_chain(struct mbuf *m_head)
-{
-struct mbuf *m;
- MGETHDR(m, M_DONTWAIT, MT_DATA);
-
- if ( !m ) {
- goto bail;
- }
-
- MCLGET(m, M_DONTWAIT);
-
- if ( !(M_EXT & m->m_flags) ) {
- m_freem(m);
- m = 0;
- goto bail;
- }
-
- m_copydata(m_head, 0, MCLBYTES, mtod(m, caddr_t));
- m->m_pkthdr.len = m->m_len = m_head->m_pkthdr.len;
-
-bail:
- m_freem(m_head);
- return m;
-}
-
-/* Enqueue a mbuf chain or a raw data buffer for transmission;
- * RETURN: #bytes sent or -1 if there are not enough descriptors
- *
- * If 'len' is <=0 then 'm_head' is assumed to point to a mbuf chain.
- * OTOH, a raw data packet may be send (non-BSD driver) by pointing
- * m_head to the start of the data and passing 'len' > 0.
- *
- * Comments: software cache-flushing incurs a penalty if the
- * packet cannot be queued since it is flushed anyways.
- * The algorithm is slightly more efficient in the normal
- * case, though.
- */
-int
-BSP_mve_send_buf(struct mveth_private *mp, void *m_head, void *data_p, int len)
-{
-int rval;
-register MvEthTxDesc l,d,h;
-register struct mbuf *m1;
-int nmbs;
-int ismbuf = (len <= 0);
-
-/* Only way to get here is when we discover that the mbuf chain
- * is too long for the tx ring
- */
-startover:
-
- rval = 0;
-
-#ifdef MVETH_TESTING
- assert(m_head);
-#endif
-
- /* if no descriptor is available; try to wipe the queue */
- if ( (mp->avail < 1) && MVETH_CLEAN_ON_SEND(mp)<=0 ) {
- /* Maybe TX is stalled and needs to be restarted */
- mveth_start_tx(mp);
- return -1;
- }
-
- h = mp->d_tx_h;
-
-#ifdef MVETH_TESTING
- assert( !h->buf_ptr );
- assert( !h->mb );
-#endif
-
- if ( ! (m1 = m_head) )
- return 0;
-
- if ( ismbuf ) {
- /* find first mbuf with actual data */
- while ( 0 == m1->m_len ) {
- if ( ! (m1 = m1->m_next) ) {
- /* end reached and still no data to send ?? */
- m_freem(m_head);
- return 0;
- }
- }
- }
-
- /* Don't use the first descriptor yet because BSP_mve_swipe_tx()
- * needs mp->d_tx_h->buf_ptr == NULL as a marker. Hence, we
- * start with the second mbuf and fill the first descriptor
- * last.
- */
-
- l = h;
- d = NEXT_TXD(h);
-
- mp->avail--;
-
- nmbs = 1;
- if ( ismbuf ) {
- register struct mbuf *m;
- for ( m=m1->m_next; m; m=m->m_next ) {
- if ( 0 == m->m_len )
- continue; /* skip empty mbufs */
-
- nmbs++;
-
- if ( mp->avail < 1 && MVETH_CLEAN_ON_SEND(mp)<=0 ) {
- /* Maybe TX was stalled - try to restart */
- mveth_start_tx(mp);
-
- /* not enough descriptors; cleanup...
- * the first slot was never used, so we start
- * at mp->d_tx_h->next;
- */
- for ( l = NEXT_TXD(h); l!=d; l=NEXT_TXD(l) ) {
-#ifdef MVETH_TESTING
- assert( l->mb == 0 );
-#endif
- l->buf_ptr = 0;
- l->cmd_sts = 0;
- mp->avail++;
- }
- mp->avail++;
- if ( nmbs > TX_AVAILABLE_RING_SIZE(mp) ) {
- /* this chain will never fit into the ring */
- if ( nmbs > mp->stats.maxchain )
- mp->stats.maxchain = nmbs;
- mp->stats.repack++;
- if ( ! (m_head = repackage_chain(m_head)) ) {
- /* no cluster available */
- mp->stats.odrops++;
- return 0;
- }
- goto startover;
- }
- return -1;
- }
-
- mp->avail--;
-
-#ifdef MVETH_TESTING
- assert( d != h );
- assert( !d->buf_ptr );
-#endif
-
- /* fill this slot */
- rval += mveth_assign_desc(d, m, TDESC_DMA_OWNED);
-
- FLUSH_BUF(mtod(m, uint32_t), m->m_len);
-
- l = d;
- d = NEXT_TXD(d);
-
- FLUSH_DESC(l);
- }
-
- /* fill first slot - don't release to DMA yet */
- rval += mveth_assign_desc(h, m1, TDESC_FRST);
-
-
- FLUSH_BUF(mtod(m1, uint32_t), m1->m_len);
-
- } else {
- /* fill first slot with raw buffer - don't release to DMA yet */
- rval += mveth_assign_desc_raw(h, data_p, len, TDESC_FRST);
-
- FLUSH_BUF( (uint32_t)data_p, len);
- }
-
- /* tag last slot; this covers the case where 1st==last */
- l->cmd_sts |= TDESC_LAST | TDESC_INT_ENA;
- /* mbuf goes into last desc */
- l->u_buf = m_head;
-
-
- FLUSH_DESC(l);
-
- /* Tag end; make sure chip doesn't try to read ahead of here! */
- l->next->cmd_sts = 0;
- FLUSH_DESC(l->next);
-
-#ifdef MVETH_DEBUG_TX_DUMP
- if ( (mveth_tx_dump & (1<<mp->port_num)) ) {
- int ll,kk;
- if ( ismbuf ) {
- struct mbuf *m;
- for ( kk=0, m=m_head; m; m=m->m_next) {
- for ( ll=0; ll<m->m_len; ll++ ) {
- printf("%02X ",*(mtod(m,char*) + ll));
- if ( ((++kk)&0xf) == 0 )
- printf("\n");
- }
- }
- } else {
- for ( ll=0; ll<len; ) {
- printf("%02X ",*((char*)data_p + ll));
- if ( ((++ll)&0xf) == 0 )
- printf("\n");
- }
- }
- printf("\n");
- }
-#endif
-
- membarrier();
-
- /* turn over the whole chain by flipping ownership of the first desc */
- h->cmd_sts |= TDESC_DMA_OWNED;
-
- FLUSH_DESC(h);
-
- membarrier();
-
- /* notify the device */
- MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(mp->port_num), MV643XX_ETH_TX_START(0));
-
- /* Update softc */
- mp->stats.packet++;
- if ( nmbs > mp->stats.maxchain )
- mp->stats.maxchain = nmbs;
-
- /* remember new head */
- mp->d_tx_h = d;
-
- return rval; /* #bytes sent */
-}
-
-int
-BSP_mve_send_buf_raw(
- struct mveth_private *mp,
- void *head_p,
- int h_len,
- void *data_p,
- int d_len)
-{
-int rval;
-register MvEthTxDesc l,d,h;
-int needed;
-void *frst_buf;
-int frst_len;
-
- rval = 0;
-
-#ifdef MVETH_TESTING
- assert(header || data);
-#endif
-
- needed = head_p && data_p ? 2 : 1;
-
- /* if no descriptor is available; try to wipe the queue */
- if ( ( mp->avail < needed )
- && ( MVETH_CLEAN_ON_SEND(mp) <= 0 || mp->avail < needed ) ) {
- /* Maybe TX was stalled and needs a restart */
- mveth_start_tx(mp);
- return -1;
- }
-
- h = mp->d_tx_h;
-
-#ifdef MVETH_TESTING
- assert( !h->buf_ptr );
- assert( !h->mb );
-#endif
-
- /* find the 'first' user buffer */
- if ( (frst_buf = head_p) ) {
- frst_len = h_len;
- } else {
- frst_buf = data_p;
- frst_len = d_len;
- }
-
- /* Don't use the first descriptor yet because BSP_mve_swipe_tx()
- * needs mp->d_tx_h->buf_ptr == NULL as a marker. Hence, we
- * start with the second (optional) slot and fill the first
- * descriptor last.
- */
-
- l = h;
- d = NEXT_TXD(h);
-
- mp->avail--;
-
- if ( needed > 1 ) {
- mp->avail--;
-#ifdef MVETH_TESTING
- assert( d != h );
- assert( !d->buf_ptr );
-#endif
- rval += mveth_assign_desc_raw(d, data_p, d_len, TDESC_DMA_OWNED);
- FLUSH_BUF( (uint32_t)data_p, d_len );
- d->u_buf = data_p;
-
- l = d;
- d = NEXT_TXD(d);
-
- FLUSH_DESC(l);
- }
-
- /* fill first slot with raw buffer - don't release to DMA yet */
- rval += mveth_assign_desc_raw(h, frst_buf, frst_len, TDESC_FRST);
-
- FLUSH_BUF( (uint32_t)frst_buf, frst_len);
-
- /* tag last slot; this covers the case where 1st==last */
- l->cmd_sts |= TDESC_LAST | TDESC_INT_ENA;
-
- /* first buffer of 'chain' goes into last desc */
- l->u_buf = frst_buf;
-
- FLUSH_DESC(l);
-
- /* Tag end; make sure chip doesn't try to read ahead of here! */
- l->next->cmd_sts = 0;
- FLUSH_DESC(l->next);
-
- membarrier();
-
- /* turn over the whole chain by flipping ownership of the first desc */
- h->cmd_sts |= TDESC_DMA_OWNED;
-
- FLUSH_DESC(h);
-
- membarrier();
-
- /* notify the device */
- MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(mp->port_num), MV643XX_ETH_TX_START(0));
-
- /* Update softc */
- mp->stats.packet++;
- if ( needed > mp->stats.maxchain )
- mp->stats.maxchain = needed;
-
- /* remember new head */
- mp->d_tx_h = d;
-
- return rval; /* #bytes sent */
-}
-
-/* send received buffers upwards and replace them
- * with freshly allocated ones;
- * ASSUMPTION: buffer length NEVER changes and is set
- * when the ring is initialized.
- * TS 20060727: not sure if this assumption is still necessary - I believe it isn't.
- */
-
-int
-BSP_mve_swipe_rx(struct mveth_private *mp)
-{
-int rval = 0, err;
-register MvEthRxDesc d;
-void *newbuf;
-int sz;
-uintptr_t baddr;
-
- for ( d = mp->d_rx_t; ! (INVAL_DESC(d), (RDESC_DMA_OWNED & d->cmd_sts)); d=NEXT_RXD(d) ) {
-
-#ifdef MVETH_TESTING
- assert(d->u_buf);
-#endif
-
- err = (RDESC_ERROR & d->cmd_sts);
-
- if ( err || !(newbuf = mp->alloc_rxbuf(&sz, &baddr)) ) {
- /* drop packet and recycle buffer */
- newbuf = d->u_buf;
- mp->consume_rxbuf(0, mp->consume_rxbuf_arg, err ? -1 : 0);
- } else {
-#ifdef MVETH_TESTING
- assert( d->byte_cnt > 0 );
-#endif
- mp->consume_rxbuf(d->u_buf, mp->consume_rxbuf_arg, d->byte_cnt);
-
-#ifndef ENABLE_HW_SNOOPING
- /* could reduce the area to max. ethernet packet size */
- INVAL_BUF(baddr, sz);
-#endif
- d->u_buf = newbuf;
- d->buf_ptr = CPUADDR2ENET(baddr);
- d->buf_size = sz;
- FLUSH_DESC(d);
- }
-
- membarrier();
-
- d->cmd_sts = RDESC_DMA_OWNED | RDESC_INT_ENA;
-
- FLUSH_DESC(d);
-
- rval++;
- }
- MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_R(mp->port_num), MV643XX_ETH_RX_START(0));
- mp->d_rx_t = d;
- return rval;
-}
-
-/* Stop hardware and clean out the rings */
-void
-BSP_mve_stop_hw(struct mveth_private *mp)
-{
-MvEthTxDesc d;
-MvEthRxDesc r;
-int i;
-
- mveth_disable_irqs(mp, -1);
-
- mveth_stop_tx(mp->port_num);
-
- /* cleanup TX rings */
- if (mp->d_tx_t) { /* maybe ring isn't initialized yet */
- for ( i=0, d=mp->tx_ring; i<mp->xbuf_count; i++, d++ ) {
- /* should be safe to clear ownership */
- d->cmd_sts &= ~TDESC_DMA_OWNED;
- FLUSH_DESC(d);
- }
- FLUSH_BARRIER();
-
- BSP_mve_swipe_tx(mp);
-
-#ifdef MVETH_TESTING
- assert( mp->d_tx_h == mp->d_tx_t );
- for ( i=0, d=mp->tx_ring; i<mp->xbuf_count; i++, d++ ) {
- assert( !d->buf_ptr );
- }
-#endif
- }
-
- MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_R(mp->port_num), MV643XX_ETH_RX_STOP_ALL);
- while ( MV643XX_ETH_RX_ANY_RUNNING & MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_R(mp->port_num)) )
- /* poll-wait */;
-
- /* stop serial port */
- MV_WRITE(MV643XX_ETH_SERIAL_CONTROL_R(mp->port_num),
- MV_READ(MV643XX_ETH_SERIAL_CONTROL_R(mp->port_num))
- & ~( MV643XX_ETH_SERIAL_PORT_ENBL | MV643XX_ETH_FORCE_LINK_FAIL_DISABLE | MV643XX_ETH_FORCE_LINK_PASS)
- );
-
- /* clear pending interrupts */
- MV_WRITE(MV643XX_ETH_INTERRUPT_CAUSE_R(mp->port_num), 0);
- MV_WRITE(MV643XX_ETH_INTERRUPT_EXTEND_CAUSE_R(mp->port_num), 0);
-
- /* cleanup RX rings */
- if ( mp->rx_ring ) {
- for ( i=0, r=mp->rx_ring; i<mp->rbuf_count; i++, r++ ) {
- /* should be OK to clear ownership flag */
- r->cmd_sts = 0;
- FLUSH_DESC(r);
- mp->consume_rxbuf(r->u_buf, mp->consume_rxbuf_arg, 0);
- r->u_buf = 0;
- }
- FLUSH_BARRIER();
- }
-
-
-}
-
-uint32_t mveth_serial_ctrl_config_val = MVETH_SERIAL_CTRL_CONFIG_VAL;
-
-/* Fire up the low-level driver
- *
- * - make sure hardware is halted
- * - enable cache snooping
- * - clear address filters
- * - clear mib counters
- * - reset phy
- * - initialize (or reinitialize) descriptor rings
- * - check that the firmware has set up a reasonable mac address.
- * - generate unicast filter entry for our mac address
- * - write register config values to the chip
- * - start hardware (serial port and SDMA)
- */
-
-void
-BSP_mve_init_hw(struct mveth_private *mp, int promisc, unsigned char *enaddr)
-{
-int i;
-uint32_t v;
-static int inited = 0;
-
-#ifdef MVETH_DEBUG
- printk(DRVNAME"%i: Entering BSP_mve_init_hw()\n", mp->port_num+1);
-#endif
-
- /* since enable/disable IRQ routine only operate on select bitsets
- * we must make sure everything is masked initially.
- */
- MV_WRITE(MV643XX_ETH_INTERRUPT_ENBL_R(mp->port_num), 0);
- MV_WRITE(MV643XX_ETH_INTERRUPT_EXTEND_ENBL_R(mp->port_num), 0);
-
- BSP_mve_stop_hw(mp);
-
- memset(&mp->stats, 0, sizeof(mp->stats));
-
- mp->promisc = promisc;
-
- /* MotLoad has cache snooping disabled on the ENET2MEM windows.
- * Some comments in (linux) indicate that there are errata
- * which cause problems which would be a real bummer.
- * We try it anyways...
- */
- if ( !inited ) {
- unsigned long disbl, bar;
- inited = 1; /* FIXME: non-thread safe lazy init */
- disbl = MV_READ(MV643XX_ETH_BAR_ENBL_R);
- /* disable all 6 windows */
- MV_WRITE(MV643XX_ETH_BAR_ENBL_R, MV643XX_ETH_BAR_DISBL_ALL);
- /* set WB snooping on enabled bars */
- for ( i=0; i<MV643XX_ETH_NUM_BARS*8; i+=8 ) {
- if ( (bar = MV_READ(MV643XX_ETH_BAR_0 + i)) && MV_READ(MV643XX_ETH_SIZE_R_0 + i) ) {
-#ifdef ENABLE_HW_SNOOPING
- MV_WRITE(MV643XX_ETH_BAR_0 + i, bar | MV64360_ENET2MEM_SNOOP_WB);
-#else
- MV_WRITE(MV643XX_ETH_BAR_0 + i, bar & ~MV64360_ENET2MEM_SNOOP_MSK);
-#endif
- /* read back to flush fifo [linux comment] */
- (void)MV_READ(MV643XX_ETH_BAR_0 + i);
- }
- }
- /* restore/re-enable */
- MV_WRITE(MV643XX_ETH_BAR_ENBL_R, disbl);
- }
-
- mveth_clear_mib_counters(mp);
- mveth_clear_addr_filters(mp);
-
-/* Just leave it alone...
- reset_phy();
-*/
-
- if ( mp->rbuf_count > 0 ) {
- mp->rx_ring = (MvEthRxDesc)MV643XX_ALIGN(mp->ring_area, RING_ALIGNMENT);
- mveth_init_rx_desc_ring(mp);
- }
-
- if ( mp->xbuf_count > 0 ) {
- mp->tx_ring = (MvEthTxDesc)mp->rx_ring + mp->rbuf_count;
- mveth_init_tx_desc_ring(mp);
- }
-
- if ( enaddr ) {
- /* set ethernet address from arpcom struct */
-#ifdef MVETH_DEBUG
- printk(DRVNAME"%i: Writing MAC addr ", mp->port_num+1);
- for (i=5; i>=0; i--) {
- printk("%02X%c", enaddr[i], i?':':'\n');
- }
-#endif
- mveth_write_eaddr(mp, enaddr);
- }
-
- /* set mac address and unicast filter */
-
- {
- uint32_t machi, maclo;
- maclo = MV_READ(MV643XX_ETH_MAC_ADDR_LO(mp->port_num));
- machi = MV_READ(MV643XX_ETH_MAC_ADDR_HI(mp->port_num));
- /* ASSUME: firmware has set the mac address for us
- * - if assertion fails, we have to do more work...
- */
- assert( maclo && machi && maclo != 0xffffffff && machi != 0xffffffff );
- mveth_ucfilter(mp, maclo&0xff, 1/* accept */);
- }
-
- /* port, serial and sdma configuration */
- v = MVETH_PORT_CONFIG_VAL;
- if ( promisc ) {
- /* multicast filters were already set up to
- * accept everything (mveth_clear_addr_filters())
- */
- v |= MV643XX_ETH_UNICAST_PROMISC_MODE;
- } else {
- v &= ~MV643XX_ETH_UNICAST_PROMISC_MODE;
- }
- MV_WRITE(MV643XX_ETH_PORT_CONFIG_R(mp->port_num),
- v);
- MV_WRITE(MV643XX_ETH_PORT_CONFIG_XTEND_R(mp->port_num),
- MVETH_PORT_XTEND_CONFIG_VAL);
-
- v = MV_READ(MV643XX_ETH_SERIAL_CONTROL_R(mp->port_num));
- v &= ~(MVETH_SERIAL_CTRL_CONFIG_MSK);
- v |= mveth_serial_ctrl_config_val;
- MV_WRITE(MV643XX_ETH_SERIAL_CONTROL_R(mp->port_num), v);
-
- i = IFM_MAKEWORD(0, 0, 0, 0);
- if ( 0 == BSP_mve_media_ioctl(mp, SIOCGIFMEDIA, &i) ) {
- if ( (IFM_LINK_OK & i) ) {
- mveth_update_serial_port(mp, i);
- }
- }
-
- /* enable serial port */
- v = MV_READ(MV643XX_ETH_SERIAL_CONTROL_R(mp->port_num));
- MV_WRITE(MV643XX_ETH_SERIAL_CONTROL_R(mp->port_num),
- v | MV643XX_ETH_SERIAL_PORT_ENBL);
-
-#ifndef __BIG_ENDIAN__
-#error "byte swapping needs to be disabled for little endian machines"
-#endif
- MV_WRITE(MV643XX_ETH_SDMA_CONFIG_R(mp->port_num), MVETH_SDMA_CONFIG_VAL);
-
- /* allow short frames */
- MV_WRITE(MV643XX_ETH_RX_MIN_FRAME_SIZE_R(mp->port_num), MVETH_MIN_FRAMSZ_CONFIG_VAL);
-
- MV_WRITE(MV643XX_ETH_INTERRUPT_CAUSE_R(mp->port_num), 0);
- MV_WRITE(MV643XX_ETH_INTERRUPT_EXTEND_CAUSE_R(mp->port_num), 0);
- /* TODO: set irq coalescing */
-
- /* enable Rx */
- if ( mp->rbuf_count > 0 ) {
- MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_R(mp->port_num), MV643XX_ETH_RX_START(0));
- }
-
- mveth_enable_irqs(mp, -1);
-
-#ifdef MVETH_DEBUG
- printk(DRVNAME"%i: Leaving BSP_mve_init_hw()\n", mp->port_num+1);
-#endif
-}
-
-/* read ethernet address from hw to buffer */
-void
-BSP_mve_read_eaddr(struct mveth_private *mp, unsigned char *oeaddr)
-{
-int i;
-uint32_t x;
-unsigned char buf[6], *eaddr;
-
- eaddr = oeaddr ? oeaddr : buf;
-
- eaddr += 5;
- x = MV_READ(MV643XX_ETH_MAC_ADDR_LO(mp->port_num));
-
- /* lo word */
- for (i=2; i; i--, eaddr--) {
- *eaddr = (unsigned char)(x & 0xff);
- x>>=8;
- }
-
- x = MV_READ(MV643XX_ETH_MAC_ADDR_HI(mp->port_num));
- /* hi word */
- for (i=4; i; i--, eaddr--) {
- *eaddr = (unsigned char)(x & 0xff);
- x>>=8;
- }
-
- if ( !oeaddr ) {
- printf("%02X",buf[0]);
- for (i=1; i<sizeof(buf); i++)
- printf(":%02X",buf[i]);
- printf("\n");
- }
-}
-
-int
-BSP_mve_media_ioctl(struct mveth_private *mp, int cmd, int *parg)
-{
-int rval;
- /* alias cmd == 0,1 */
- switch ( cmd ) {
- case 0: cmd = SIOCGIFMEDIA;
- break;
- case 1: cmd = SIOCSIFMEDIA;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- break;
- default: return -1;
- }
- REGLOCK();
- rval = rtems_mii_ioctl(&mveth_mdio, mp, cmd, parg);
- REGUNLOCK();
- return rval;
-}
-
-void
-BSP_mve_enable_irqs(struct mveth_private *mp)
-{
- mveth_enable_irqs(mp, -1);
-}
-
-void
-BSP_mve_disable_irqs(struct mveth_private *mp)
-{
- mveth_disable_irqs(mp, -1);
-}
-
-uint32_t
-BSP_mve_ack_irqs(struct mveth_private *mp)
-{
- return mveth_ack_irqs(mp, -1);
-}
-
-
-void
-BSP_mve_enable_irq_mask(struct mveth_private *mp, uint32_t mask)
-{
- mveth_enable_irqs(mp, mask);
-}
-
-uint32_t
-BSP_mve_disable_irq_mask(struct mveth_private *mp, uint32_t mask)
-{
- return mveth_disable_irqs(mp, mask);
-}
-
-uint32_t
-BSP_mve_ack_irq_mask(struct mveth_private *mp, uint32_t mask)
-{
- return mveth_ack_irqs(mp, mask);
-}
-
-int
-BSP_mve_ack_link_chg(struct mveth_private *mp, int *pmedia)
-{
-int media = IFM_MAKEWORD(0,0,0,0);
-
- if ( 0 == BSP_mve_media_ioctl(mp, SIOCGIFMEDIA, &media)) {
- if ( IFM_LINK_OK & media ) {
- mveth_update_serial_port(mp, media);
- /* If TX stalled because there was no buffer then whack it */
- mveth_start_tx(mp);
- }
- if ( pmedia )
- *pmedia = media;
- return 0;
- }
- return -1;
-}
-
-/* BSDNET SUPPORT/GLUE ROUTINES */
-
-static void
-mveth_set_filters(struct ifnet *ifp);
-
-STATIC void
-mveth_stop(struct mveth_softc *sc)
-{
- BSP_mve_stop_hw(&sc->pvt);
- sc->arpcom.ac_if.if_timer = 0;
-}
-
-/* allocate a mbuf for RX with a properly aligned data buffer
- * RETURNS 0 if allocation fails
- */
-static void *
-alloc_mbuf_rx(int *psz, uintptr_t *paddr)
-{
-struct mbuf *m;
-unsigned long l,o;
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if ( !m )
- return 0;
- MCLGET(m, M_DONTWAIT);
- if ( ! (m->m_flags & M_EXT) ) {
- m_freem(m);
- return 0;
- }
-
- o = mtod(m, unsigned long);
- l = MV643XX_ALIGN(o, RX_BUF_ALIGNMENT) - o;
-
- /* align start of buffer */
- m->m_data += l;
-
- /* reduced length */
- l = MCLBYTES - l;
-
- m->m_len = m->m_pkthdr.len = l;
- *psz = m->m_len;
- *paddr = mtod(m, uintptr_t);
-
- return (void*) m;
-}
-
-static void consume_rx_mbuf(void *buf, void *arg, int len)
-{
-struct ifnet *ifp = arg;
-struct mbuf *m = buf;
-
- if ( len <= 0 ) {
- ifp->if_iqdrops++;
- if ( len < 0 ) {
- ifp->if_ierrors++;
- }
- if ( m )
- m_freem(m);
- } else {
- struct ether_header *eh;
-
- eh = (struct ether_header *)(mtod(m, unsigned long) + ETH_RX_OFFSET);
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header) - ETH_RX_OFFSET - ETH_CRC_LEN;
- m->m_data += sizeof(struct ether_header) + ETH_RX_OFFSET;
- m->m_pkthdr.rcvif = ifp;
-
- ifp->if_ipackets++;
- ifp->if_ibytes += m->m_pkthdr.len;
-
- if (0) {
- /* Low-level debugging */
- int i;
- for (i=0; i<13; i++) {
- printf("%02X:",((char*)eh)[i]);
- }
- printf("%02X\n",((char*)eh)[i]);
- for (i=0; i<m->m_len; i++) {
- if ( !(i&15) )
- printf("\n");
- printf("0x%02x ",mtod(m,char*)[i]);
- }
- printf("\n");
- }
-
- if (0) {
- /* Low-level debugging/testing without bsd stack */
- m_freem(m);
- } else {
- /* send buffer upwards */
- ether_input(ifp, eh, m);
- }
- }
-}
-
-static void release_tx_mbuf(void *buf, void *arg, int err)
-{
-struct ifnet *ifp = arg;
-struct mbuf *mb = buf;
-
- if ( err ) {
- ifp->if_oerrors++;
- } else {
- ifp->if_opackets++;
- }
- ifp->if_obytes += mb->m_pkthdr.len;
- m_freem(mb);
-}
-
-static void
-dump_update_stats(struct mveth_private *mp, FILE *f)
-{
-int p = mp->port_num;
-int idx;
-uint32_t v;
-
- if ( !f )
- f = stdout;
-
- fprintf(f, DRVNAME"%i Statistics:\n", mp->port_num + 1);
- fprintf(f, " # IRQS: %i\n", mp->stats.irqs);
- fprintf(f, " Max. mbuf chain length: %i\n", mp->stats.maxchain);
- fprintf(f, " # repacketed: %i\n", mp->stats.repack);
- fprintf(f, " # packets: %i\n", mp->stats.packet);
- fprintf(f, "MIB Counters:\n");
- for ( idx = MV643XX_ETH_MIB_GOOD_OCTS_RCVD_LO>>2;
- idx < MV643XX_ETH_NUM_MIB_COUNTERS;
- idx++ ) {
- switch ( idx ) {
- case MV643XX_ETH_MIB_GOOD_OCTS_RCVD_LO>>2:
- mp->stats.mib.good_octs_rcvd += read_long_mib_counter(p, idx);
- fprintf(f, mibfmt[idx], mp->stats.mib.good_octs_rcvd);
- idx++;
- break;
-
- case MV643XX_ETH_MIB_GOOD_OCTS_SENT_LO>>2:
- mp->stats.mib.good_octs_sent += read_long_mib_counter(p, idx);
- fprintf(f, mibfmt[idx], mp->stats.mib.good_octs_sent);
- idx++;
- break;
-
- default:
- v = ((uint32_t*)&mp->stats.mib)[idx] += read_mib_counter(p, idx);
- fprintf(f, mibfmt[idx], v);
- break;
- }
- }
- fprintf(f, "\n");
-}
-
-void
-BSP_mve_dump_stats(struct mveth_private *mp, FILE *f)
-{
- dump_update_stats(mp, f);
-}
-
-/* BSDNET DRIVER CALLBACKS */
-
-static void
-mveth_init(void *arg)
-{
-struct mveth_softc *sc = arg;
-struct ifnet *ifp = &sc->arpcom.ac_if;
-int media;
-
- BSP_mve_init_hw(&sc->pvt, ifp->if_flags & IFF_PROMISC, sc->arpcom.ac_enaddr);
-
- media = IFM_MAKEWORD(0, 0, 0, 0);
- if ( 0 == BSP_mve_media_ioctl(&sc->pvt, SIOCGIFMEDIA, &media) ) {
- if ( (IFM_LINK_OK & media) ) {
- ifp->if_flags &= ~IFF_OACTIVE;
- } else {
- ifp->if_flags |= IFF_OACTIVE;
- }
- }
-
- /* if promiscuous then there is no need to change */
- if ( ! (ifp->if_flags & IFF_PROMISC) )
- mveth_set_filters(ifp);
-
- ifp->if_flags |= IFF_RUNNING;
- sc->arpcom.ac_if.if_timer = 0;
-}
-
-/* bsdnet driver entry to start transmission */
-static void
-mveth_start(struct ifnet *ifp)
-{
-struct mveth_softc *sc = ifp->if_softc;
-struct mbuf *m = 0;
-
- while ( ifp->if_snd.ifq_head ) {
- IF_DEQUEUE( &ifp->if_snd, m );
- if ( BSP_mve_send_buf(&sc->pvt, m, 0, 0) < 0 ) {
- IF_PREPEND( &ifp->if_snd, m);
- ifp->if_flags |= IFF_OACTIVE;
- break;
- }
- /* need to do this really only once
- * but it's cheaper this way.
- */
- ifp->if_timer = 2*IFNET_SLOWHZ;
- }
-}
-
-/* bsdnet driver entry; */
-static void
-mveth_watchdog(struct ifnet *ifp)
-{
-struct mveth_softc *sc = ifp->if_softc;
-
- ifp->if_oerrors++;
- printk(DRVNAME"%i: watchdog timeout; resetting\n", ifp->if_unit);
-
- mveth_init(sc);
- mveth_start(ifp);
-}
-
-static void
-mveth_set_filters(struct ifnet *ifp)
-{
-struct mveth_softc *sc = ifp->if_softc;
-uint32_t v;
-
- v = MV_READ(MV643XX_ETH_PORT_CONFIG_R(sc->pvt.port_num));
- if ( ifp->if_flags & IFF_PROMISC )
- v |= MV643XX_ETH_UNICAST_PROMISC_MODE;
- else
- v &= ~MV643XX_ETH_UNICAST_PROMISC_MODE;
- MV_WRITE(MV643XX_ETH_PORT_CONFIG_R(sc->pvt.port_num), v);
-
- if ( ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI) ) {
- BSP_mve_mcast_filter_accept_all(&sc->pvt);
- } else {
- struct ether_multi *enm;
- struct ether_multistep step;
-
- BSP_mve_mcast_filter_clear( &sc->pvt );
-
- ETHER_FIRST_MULTI(step, (struct arpcom *)ifp, enm);
-
- while ( enm ) {
- if ( memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN) )
- assert( !"Should never get here; IFF_ALLMULTI should be set!" );
-
- BSP_mve_mcast_filter_accept_add(&sc->pvt, enm->enm_addrlo);
-
- ETHER_NEXT_MULTI(step, enm);
- }
- }
-}
-
-/* bsdnet driver ioctl entry */
-static int
-mveth_ioctl(struct ifnet *ifp, ioctl_command_t cmd, caddr_t data)
-{
-struct mveth_softc *sc = ifp->if_softc;
-struct ifreq *ifr = (struct ifreq *)data;
-int error = 0;
-int f;
-
- switch ( cmd ) {
- case SIOCSIFFLAGS:
- f = ifp->if_flags;
- if ( f & IFF_UP ) {
- if ( ! ( f & IFF_RUNNING ) ) {
- mveth_init(sc);
- } else {
- if ( (f & IFF_PROMISC) != (sc->bsd.oif_flags & IFF_PROMISC) ) {
- /* Note: in all other scenarios the 'promisc' flag
- * in the low-level driver [which affects the way
- * the multicast filter is setup: accept none vs.
- * accept all in promisc mode] is eventually
- * set when the IF is brought up...
- */
- sc->pvt.promisc = (f & IFF_PROMISC);
-
- mveth_set_filters(ifp);
- }
- /* FIXME: other flag changes are ignored/unimplemented */
- }
- } else {
- if ( f & IFF_RUNNING ) {
- mveth_stop(sc);
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
- }
- }
- sc->bsd.oif_flags = ifp->if_flags;
- break;
-
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- error = BSP_mve_media_ioctl(&sc->pvt, cmd, &ifr->ifr_media);
- break;
-
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- error = (cmd == SIOCADDMULTI)
- ? ether_addmulti(ifr, &sc->arpcom)
- : ether_delmulti(ifr, &sc->arpcom);
-
- if (error == ENETRESET) {
- if (ifp->if_flags & IFF_RUNNING) {
- mveth_set_filters(ifp);
- }
- error = 0;
- }
- break;
-
-
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- dump_update_stats(&sc->pvt, stdout);
- break;
-
- default:
- error = ether_ioctl(ifp, cmd, data);
- break;
- }
-
- return error;
-}
-
-/* DRIVER TASK */
-
-/* Daemon task does all the 'interrupt' work */
-static void mveth_daemon(void *arg)
-{
-struct mveth_softc *sc;
-struct ifnet *ifp;
-rtems_event_set evs;
- for (;;) {
- rtems_bsdnet_event_receive( 7, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &evs );
- evs &= 7;
- for ( sc = theMvEths; evs; evs>>=1, sc++ ) {
- if ( (evs & 1) ) {
- register uint32_t x;
-
- ifp = &sc->arpcom.ac_if;
-
- if ( !(ifp->if_flags & IFF_UP) ) {
- mveth_stop(sc);
- ifp->if_flags &= ~(IFF_UP|IFF_RUNNING);
- continue;
- }
-
- if ( !(ifp->if_flags & IFF_RUNNING) ) {
- /* event could have been pending at the time hw was stopped;
- * just ignore...
- */
- continue;
- }
-
- x = mveth_ack_irqs(&sc->pvt, -1);
-
- if ( MV643XX_ETH_EXT_IRQ_LINK_CHG & x ) {
- /* phy status changed */
- int media;
-
- if ( 0 == BSP_mve_ack_link_chg(&sc->pvt, &media) ) {
- if ( IFM_LINK_OK & media ) {
- ifp->if_flags &= ~IFF_OACTIVE;
- mveth_start(ifp);
- } else {
- /* stop sending */
- ifp->if_flags |= IFF_OACTIVE;
- }
- }
- }
- /* free tx chain */
- if ( (MV643XX_ETH_EXT_IRQ_TX_DONE & x) && BSP_mve_swipe_tx(&sc->pvt) ) {
- ifp->if_flags &= ~IFF_OACTIVE;
- if ( TX_AVAILABLE_RING_SIZE(&sc->pvt) == sc->pvt.avail )
- ifp->if_timer = 0;
- mveth_start(ifp);
- }
- if ( (MV643XX_ETH_IRQ_RX_DONE & x) )
- BSP_mve_swipe_rx(&sc->pvt);
-
- mveth_enable_irqs(&sc->pvt, -1);
- }
- }
- }
-}
-
-#ifdef MVETH_DETACH_HACK
-static int mveth_detach(struct mveth_softc *sc);
-#endif
-
-
-/* PUBLIC RTEMS BSDNET ATTACH FUNCTION */
-int
-rtems_mve_attach(struct rtems_bsdnet_ifconfig *ifcfg, int attaching)
-{
-char *unitName;
-int unit,i,cfgUnits;
-struct mveth_softc *sc;
-struct ifnet *ifp;
-
- unit = rtems_bsdnet_parse_driver_name(ifcfg, &unitName);
- if ( unit <= 0 || unit > MV643XXETH_NUM_DRIVER_SLOTS ) {
- printk(DRVNAME": Bad unit number %i; must be 1..%i\n", unit, MV643XXETH_NUM_DRIVER_SLOTS);
- return 1;
- }
-
- sc = &theMvEths[unit-1];
- ifp = &sc->arpcom.ac_if;
- sc->pvt.port_num = unit-1;
- sc->pvt.phy = (MV_READ(MV643XX_ETH_PHY_ADDR_R) >> (5*sc->pvt.port_num)) & 0x1f;
-
- if ( attaching ) {
- if ( ifp->if_init ) {
- printk(DRVNAME": instance %i already attached.\n", unit);
- return -1;
- }
-
- for ( i=cfgUnits = 0; i<MV643XXETH_NUM_DRIVER_SLOTS; i++ ) {
- if ( theMvEths[i].arpcom.ac_if.if_init )
- cfgUnits++;
- }
- cfgUnits++; /* this new one */
-
- /* lazy init of TID should still be thread-safe because we are protected
- * by the global networking semaphore..
- */
- if ( !mveth_tid ) {
- /* newproc uses the 1st 4 chars of name string to build an rtems name */
- mveth_tid = rtems_bsdnet_newproc("MVEd", 4096, mveth_daemon, 0);
- }
-
- if ( !BSP_mve_setup( unit,
- mveth_tid,
- release_tx_mbuf, ifp,
- alloc_mbuf_rx,
- consume_rx_mbuf, ifp,
- ifcfg->rbuf_count,
- ifcfg->xbuf_count,
- BSP_MVE_IRQ_TX | BSP_MVE_IRQ_RX | BSP_MVE_IRQ_LINK) ) {
- return -1;
- }
-
- if ( nmbclusters < sc->pvt.rbuf_count * cfgUnits + 60 /* arbitrary */ ) {
- printk(DRVNAME"%i: (mv643xx ethernet) Your application has not enough mbuf clusters\n", unit);
- printk( " configured for this driver.\n");
- return -1;
- }
-
- if ( ifcfg->hardware_address ) {
- memcpy(sc->arpcom.ac_enaddr, ifcfg->hardware_address, ETHER_ADDR_LEN);
- } else {
- /* read back from hardware assuming that MotLoad already had set it up */
- BSP_mve_read_eaddr(&sc->pvt, sc->arpcom.ac_enaddr);
- }
-
- ifp->if_softc = sc;
- ifp->if_unit = unit;
- ifp->if_name = unitName;
-
- ifp->if_mtu = ifcfg->mtu ? ifcfg->mtu : ETHERMTU;
-
- ifp->if_init = mveth_init;
- ifp->if_ioctl = mveth_ioctl;
- ifp->if_start = mveth_start;
- ifp->if_output = ether_output;
- /*
- * While nonzero, the 'if->if_timer' is decremented
- * (by the networking code) at a rate of IFNET_SLOWHZ (1hz) and 'if_watchdog'
- * is called when it expires.
- * If either of those fields is 0 the feature is disabled.
- */
- ifp->if_watchdog = mveth_watchdog;
- ifp->if_timer = 0;
-
- sc->bsd.oif_flags = /* ... */
- ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX;
-
- /*
- * if unset, this set to 10Mbps by ether_ifattach; seems to be unused by bsdnet stack;
- * could be updated along with phy speed, though...
- ifp->if_baudrate = 10000000;
- */
-
- /* NOTE: ether_output drops packets if ifq_len >= ifq_maxlen
- * but this is the packet count, not the fragment count!
- ifp->if_snd.ifq_maxlen = sc->pvt.xbuf_count;
- */
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
-
-#ifdef MVETH_DETACH_HACK
- if ( !ifp->if_addrlist ) /* do only the first time [reattach hack] */
-#endif
- {
- if_attach(ifp);
- ether_ifattach(ifp);
- }
-
- } else {
-#ifdef MVETH_DETACH_HACK
- if ( !ifp->if_init ) {
- printk(DRVNAME": instance %i not attached.\n", unit);
- return -1;
- }
- return mveth_detach(sc);
-#else
- printk(DRVNAME": interface detaching not implemented\n");
- return -1;
-#endif
- }
-
- return 0;
-}
-
-/* EARLY PHY ACCESS */
-static int
-mveth_early_init(int idx)
-{
- if ( idx < 0 || idx >= MV643XXETH_NUM_DRIVER_SLOTS )
- return -1;
-
- /* determine the phy */
- theMvEths[idx].pvt.phy = (MV_READ(MV643XX_ETH_PHY_ADDR_R) >> (5*idx)) & 0x1f;
- return 0;
-}
-
-static int
-mveth_early_read_phy(int idx, unsigned reg)
-{
-int rval;
-
- if ( idx < 0 || idx >= MV643XXETH_NUM_DRIVER_SLOTS )
- return -1;
-
- rval = mveth_mii_read(&theMvEths[idx].pvt, reg);
- return rval < 0 ? rval : rval & 0xffff;
-}
-
-static int
-mveth_early_write_phy(int idx, unsigned reg, unsigned val)
-{
- if ( idx < 0 || idx >= MV643XXETH_NUM_DRIVER_SLOTS )
- return -1;
-
- mveth_mii_write(&theMvEths[idx].pvt, reg, val);
- return 0;
-}
-
-rtems_bsdnet_early_link_check_ops
-rtems_mve_early_link_check_ops = {
- init: mveth_early_init,
- read_phy: mveth_early_read_phy,
- write_phy: mveth_early_write_phy,
- name: DRVNAME,
- num_slots: MAX_NUM_SLOTS
-};
-
-/* DEBUGGING */
-
-#ifdef MVETH_DEBUG
-/* Display/dump descriptor rings */
-
-int
-mveth_dring(struct mveth_softc *sc)
-{
-int i;
-if (1) {
-MvEthRxDesc pr;
-printf("RX:\n");
-
- for (i=0, pr=sc->pvt.rx_ring; i<sc->pvt.rbuf_count; i++, pr++) {
-#ifndef ENABLE_HW_SNOOPING
- /* can't just invalidate the descriptor - if it contains
- * data that hasn't been flushed yet, we create an inconsistency...
- */
- rtems_bsdnet_semaphore_obtain();
- INVAL_DESC(pr);
-#endif
- printf("cnt: 0x%04x, size: 0x%04x, stat: 0x%08x, next: 0x%08x, buf: 0x%08x\n",
- pr->byte_cnt, pr->buf_size, pr->cmd_sts, (uint32_t)pr->next_desc_ptr, pr->buf_ptr);
-
-#ifndef ENABLE_HW_SNOOPING
- rtems_bsdnet_semaphore_release();
-#endif
- }
-}
-if (1) {
-MvEthTxDesc pt;
-printf("TX:\n");
- for (i=0, pt=sc->pvt.tx_ring; i<sc->pvt.xbuf_count; i++, pt++) {
-#ifndef ENABLE_HW_SNOOPING
- rtems_bsdnet_semaphore_obtain();
- INVAL_DESC(pt);
-#endif
- printf("cnt: 0x%04x, stat: 0x%08x, next: 0x%08x, buf: 0x%08x, mb: 0x%08x\n",
- pt->byte_cnt, pt->cmd_sts, (uint32_t)pt->next_desc_ptr, pt->buf_ptr,
- (uint32_t)pt->mb);
-
-#ifndef ENABLE_HW_SNOOPING
- rtems_bsdnet_semaphore_release();
-#endif
- }
-}
- return 0;
-}
-
-#endif
-
-/* DETACH HACK DETAILS */
-
-#ifdef MVETH_DETACH_HACK
-int
-_cexpModuleFinalize(void *mh)
-{
-int i;
- for ( i=0; i<MV643XXETH_NUM_DRIVER_SLOTS; i++ ) {
- if ( theMvEths[i].arpcom.ac_if.if_init ) {
- printf("Interface %i still attached; refuse to unload\n", i+1);
- return -1;
- }
- }
- /* delete task; since there are no attached interfaces, it should block
- * for events and hence not hold the semaphore or other resources...
- */
- rtems_task_delete(mveth_tid);
- return 0;
-}
-
-/* ugly hack to allow unloading/reloading the driver core.
- * needed because rtems' bsdnet release doesn't implement
- * if_detach(). Therefore, we bring the interface down but
- * keep the device record alive...
- */
-static void
-ether_ifdetach_pvt(struct ifnet *ifp)
-{
- ifp->if_flags = 0;
- ifp->if_ioctl = 0;
- ifp->if_start = 0;
- ifp->if_watchdog = 0;
- ifp->if_init = 0;
-}
-
-static int
-mveth_detach(struct mveth_softc *sc)
-{
-struct ifnet *ifp = &sc->arpcom.ac_if;
- if ( ifp->if_init ) {
- if ( ifp->if_flags & (IFF_UP | IFF_RUNNING) ) {
- printf(DRVNAME"%i: refuse to detach; interface still up\n",sc->pvt.port_num+1);
- return -1;
- }
- mveth_stop(sc);
-/* not implemented in BSDnet/RTEMS (yet) but declared in header */
-#define ether_ifdetach ether_ifdetach_pvt
- ether_ifdetach(ifp);
- }
- free( (void*)sc->pvt.ring_area, M_DEVBUF );
- sc->pvt.ring_area = 0;
- sc->pvt.tx_ring = 0;
- sc->pvt.rx_ring = 0;
- sc->pvt.d_tx_t = sc->pvt.d_tx_h = 0;
- sc->pvt.d_rx_t = 0;
- sc->pvt.avail = 0;
- /* may fail if ISR was not installed yet */
- BSP_remove_rtems_irq_handler( &irq_data[sc->pvt.port_num] );
- return 0;
-}
-
-#ifdef MVETH_DEBUG
-struct rtems_bsdnet_ifconfig mveth_dbg_config = {
- name: DRVNAME"1",
- attach: rtems_mve_attach,
- ip_address: "192.168.2.10", /* not used by rtems_bsdnet_attach */
- ip_netmask: "255.255.255.0", /* not used by rtems_bsdnet_attach */
- hardware_address: 0, /* (void *) */
- ignore_broadcast: 0, /* TODO driver should honour this */
- mtu: 0,
- rbuf_count: 0, /* TODO driver should honour this */
- xbuf_count: 0, /* TODO driver should honour this */
-};
-#endif
-#endif
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mve_smallbuf_tst.c b/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mve_smallbuf_tst.c
deleted file mode 100644
index 721ade30d1..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mve_smallbuf_tst.c
+++ /dev/null
@@ -1,145 +0,0 @@
-#include <rtems.h>
-#include <bsp.h>
-#include <bsp/if_mve_pub.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-/* Demo for the mv64360 ethernet quirk:
- *
- * $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
- * $$ buffer segments < 8 bytes must be aligned $$
- * $$ to 8 bytes but larger segments are not $$
- * $$ sensitive to alignment. $$
- * $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
- *
- * How to use:
- *
- * Init MVE driver on (unused) unit 2:
- *
- * mve = mvtst_init(2)
- *
- * data = { 1,2,3,4,5,6,7,8,9,0xa,0xb, ... }
- *
- * Alloc 2-element mbuf chain (1st holds an
- * ethernet header which is > 8bytes so we can't
- * test this with only 1 mbuf. The 2nd mbuf holds
- * a small fragment of data).
- *
- * mb = mvtst_getbuf(mve)
- *
- * Copy data into aligned area inside 2nd mbuf,
- * (so that you can see if the chip starts using
- * the aligned area rather than the unaligned
- * buffer pointer). Point mbuf's data pointer
- * at 'off'set from the aligned area:
- *
- * mvtst_putbuf(mb, data, len, offset)
- *
- * Send chain off:
- *
- * BSP_mve_send_buf(mve, mb, 0, 0)
- *
- * Watch raw data:
- *
- * tcpdump -XX -vv -s0 ether host <my-ether-addr>
- *
- * E.g, if offset = 1, len = 2 then we would like
- * to see
- *
- * GOOD:
- * < 14 header bytes > 0x02, 0x03
-
- * but if the chip starts DMA at aligned address
- * we see instead
- * BAD:
- * < 14 header bytes > 0x01, 0x02
- */
-
-static inline void *rmalloc(size_t l) { return malloc(l); }
-static inline void rfree(void *p) { return free(p); }
-
-#define _KERNEL
-#include <sys/param.h>
-#include <sys/mbuf.h>
-
-static void
-cleanup_buf(void *u_b, void *closure, int error)
-{
-rtems_bsdnet_semaphore_obtain();
- m_freem((struct mbuf*)u_b);
-rtems_bsdnet_semaphore_release();
-}
-
-struct mbuf *mvtst_getbuf(struct mveth_private *mp)
-{
-struct mbuf *m,*n;
-
- if ( !mp ) {
- printf("need driver ptr arg\n");
- return 0;
- }
-rtems_bsdnet_semaphore_obtain();
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- MGET(n, M_DONTWAIT, MT_DATA);
- m->m_next = n;
-rtems_bsdnet_semaphore_release();
- /* Ethernet header */
- memset( mtod(m, unsigned char*), 0xff, 6);
- BSP_mve_read_eaddr(mp, mtod(m, unsigned char*) + 6);
- /* Arbitrary; setting to IP but we don't bother
- * to setup a real IP header. We just watch the
- * raw packet contents...
- */
- mtod(m, unsigned char*)[12] = 0x08;
- mtod(m, unsigned char*)[13] = 0x00;
- m->m_pkthdr.len = m->m_len = 14;
- n->m_len = 0;
- return m;
-}
-
-int
-mvtst_putbuf(struct mbuf *m, void *data, int len, int off)
-{
-int i;
- if ( m ) {
- m->m_pkthdr.len += len;
- if ( ( m= m->m_next ) ) {
- m->m_len = len;
- memcpy(mtod(m, void*), data, 32);
- m->m_data += off;
- printf("m.dat: 0x%08x, m.data: 0x%08x\n", m->m_dat, m->m_data);
- for ( i=0; i< 16; i++ ) {
- printf(" %02x,",mtod(m, unsigned char*)[i]);
- }
- printf("\n");
- }
- }
-
- return 0;
-}
-
-static void *alloc_rxbuf(int *p_size, unsigned long *paddr)
-{
- return *(void**)paddr = rmalloc((*p_size = 1800));
-}
-
-static void consume_buf(void *buf, void *closure, int len)
-{
- rfree(buf);
-}
-
-void *
-mvtst_init(int unit)
-{
-struct mveth_private *mp;
- mp = BSP_mve_setup(
- unit, 0,
- cleanup_buf, 0,
- alloc_rxbuf,
- consume_buf, 0,
- 10, 10,
- 0);
- if ( mp )
- BSP_mve_init_hw(mp, 0, 0);
- return mp;
-}
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/testing.c b/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/testing.c
deleted file mode 100644
index a1233bdb0b..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/testing.c
+++ /dev/null
@@ -1,324 +0,0 @@
-#ifndef KERNEL
-#define KERNEL
-#endif
-
-#include <rtems.h>
-#include <rtems/rtems_bsdnet_internal.h>
-#include <bsp.h>
-#include <sys/param.h>
-#include <sys/mbuf.h>
-
-#include "mv64340_eth_ll.h"
-
-#include <string.h>
-#include <assert.h>
-
-#include <netinet/in.h>
-#include <stdio.h>
-
-#define RX_SPACING 1
-#define TX_SPACING 1
-
-#define RX_RING_SIZE (MV64340_RX_QUEUE_SIZE*RX_SPACING)
-#define TX_RING_SIZE (MV64340_TX_QUEUE_SIZE*TX_SPACING)
-
-
-struct eth_rx_desc rx_ring[RX_RING_SIZE] __attribute__((aligned(32)));
-struct eth_rx_desc rx_ring[RX_RING_SIZE] = {{0},};
-
-struct eth_tx_desc tx_ring[TX_RING_SIZE] __attribute__((aligned(32)));
-struct eth_tx_desc tx_ring[TX_RING_SIZE] = {{0},};
-
-/* packet buffers */
-char rx_buf[MV64340_RX_QUEUE_SIZE][2048] __attribute__((aligned(8)));
-char rx_buf[MV64340_RX_QUEUE_SIZE][2048];
-
-char tx_buf[MV64340_RX_QUEUE_SIZE][2048] __attribute__((aligned(8)));
-char tx_buf[MV64340_RX_QUEUE_SIZE][2048];
-
-char BcHeader[22] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* dst */
- 0x00, 0x01, 0xaf, 0x13, 0xb5, 0x3e, /* src */
- 00, 00, /* len */
- 0xAA, /* dsap */
- 0xAA, /* ssap */
- 0x03, /* ctrl */
- 0x08, 0x00, 0x56, /* snap_org [stanford] */
- 0x80, 0x5b, /* snap_type (stanford kernel) */
-};
-
-struct mv64340_private mveth = {
- port_num: 0,
- port_mac_addr: {0x00,0x01,0xAF,0x13,0xB5,0x3C},
- /* port_config .. tx_resource_err are set by port_init */
- 0
-};
-
-struct pkt_info p0,p1;
-
-static inline void rx_stopq(int port)
-{
- MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(port), 0x0000ff00);
-}
-
-static inline void tx_stopq(int port)
-{
- MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port), 0x0000ff00);
-}
-
-#define MV64360_ENET2MEM_SNOOP_NONE 0x0000
-#define MV64360_ENET2MEM_SNOOP_WT 0x1000
-#define MV64360_ENET2MEM_SNOOP_WB 0x2000
-
-#if 0
-int
-mveth_init(struct mv64340_private *mp)
-{
-int i;
- mp->p_rx_desc_area = rx_ring;
- mp->p_tx_desc_area = tx_ring;
-
- rx_stopq(mp->port_num);
- tx_stopq(mp->port_num);
-
- /* MotLoad has cache snooping disabled on the ENET2MEM windows.
- * Some comments in (linux) indicate that there are errata
- * which cause problems which is a real bummer.
- * We try it anyways...
- */
- {
- unsigned long disbl, bar;
- disbl = MV_READ(MV64340_ETH_BASE_ADDR_ENABLE_REG);
- /* disable all 6 windows */
- MV_WRITE(MV64340_ETH_BASE_ADDR_ENABLE_REG, 0x3f);
- /* set WB snooping */
- for ( i=0; i<6*8; i+=8 ) {
- if ( (bar = MV_READ(MV64340_ETH_BAR_0 + i)) && MV_READ(MV64340_ETH_SIZE_REG_0 + i) ) {
- MV_WRITE(MV64340_ETH_BAR_0 + i, bar | MV64360_ENET2MEM_SNOOP_WB);
- /* read back to flush fifo [linux comment] */
- (void)MV_READ(MV64340_ETH_BAR_0 + i);
- }
- }
- /* restore/re-enable */
- MV_WRITE(MV64340_ETH_BASE_ADDR_ENABLE_REG, disbl);
- }
-
- eth_port_init(mp);
-
- sleep(1);
-
- mveth_init_tx_desc_ring(mp);
- mveth_init_rx_desc_ring(mp);
-#if 0
- for ( i = 0; i<MV64340_RX_QUEUE_SIZE; i++ ) {
- p0.byte_cnt = sizeof(rx_buf[0]);
- p0.buf_ptr = (dma_addr_t)rx_buf[i];
- p0.return_info = (void*)i;
- /* other fields are not used by ll driver */
- assert ( ETH_OK == eth_rx_return_buff(mp,&p0) );
- }
- memset(&p0, 0, sizeof(p0));
-#endif
-
- return eth_port_start(mp);
-}
-#endif
-
-void
-mveth_stop(struct mv64340_private *mp)
-{
-extern void mveth_stop_hw();
- rtems_bsdnet_semaphore_obtain();
- mveth_stop_hw(mp);
- rtems_bsdnet_semaphore_release();
-}
-
-extern int mveth_send_mbuf();
-extern int mveth_swipe_tx();
-
-int
-mveth_tx(struct mv64340_private *mp, char *data, int len, int nbufs)
-{
-int rval = -1,l;
-char *p;
-struct mbuf *m;
-char *emsg = 0;
-
- rtems_bsdnet_semaphore_obtain();
- MGETHDR(m, M_WAIT, MT_DATA);
- if ( !m ) {
- emsg="Unable to allocate header\n";
- goto bail;
- }
- MCLGET(m, M_WAIT);
- if ( !(m->m_flags & M_EXT) ) {
- m_freem(m);
- emsg="Unable to allocate cluster\n";
- goto bail;
- }
- p = mtod(m, char *);
- l = 0;
- switch (nbufs) {
- case 3:
- default:
- emsg="nbufs arg must be 1..3\n";
- goto bail;
-
- case 1:
- l += sizeof(BcHeader);
- memcpy(p, &BcHeader, sizeof(BcHeader));
- p += sizeof(BcHeader);
-
- case 2:
- memcpy(p,data,len);
- l += len;
- m->m_len = m->m_pkthdr.len = l;
- if ( 2 == nbufs ) {
- M_PREPEND(m, sizeof (BcHeader), M_WAIT);
- if (!m) {
- emsg = "Unable to prepend\n";
- goto bail;
- }
- p = mtod(m, char*);
- memcpy(p,&BcHeader,sizeof(BcHeader));
- l += sizeof(BcHeader);
- }
- break;
- }
- *(short*)(mtod(m, char*) + 12) = htons(l-14);
- rval = mveth_send_mbuf(mp,m);
-
-bail:
- rtems_bsdnet_semaphore_release();
- if (emsg)
- printf(emsg);
-
-#if 0
- /*
- * Add local net header. If no space in first mbuf,
- * allocate another.
- */
- M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
- if (m == 0)
- senderr(ENOBUFS);
- eh = mtod(m, struct ether_header *);
- (void)memcpy(&eh->ether_type, &type,
- sizeof(eh->ether_type));
- (void)memcpy(eh->ether_dhost, edst, sizeof (edst));
- (void)memcpy(eh->ether_shost, ac->ac_enaddr,
- sizeof(eh->ether_shost));
-#endif
- return rval;
-}
-
-int
-mveth_protected(int (*p)(struct mv64340_private*), struct mv64340_private *mp)
-{
-int rval;
- rtems_bsdnet_semaphore_obtain();
- rval = p(mp);
- rtems_bsdnet_semaphore_release();
- return rval;
-}
-
-int
-mveth_rx(struct mv64340_private *mp)
-{
-extern int mveth_swipe_rx();
- return mveth_protected(mveth_swipe_rx,mp);
-}
-
-int
-mveth_reclaim(struct mv64340_private *mp)
-{
-extern int mveth_swipe_tx();
- return mveth_protected(mveth_swipe_tx,mp);
-}
-
-
-int preth(FILE *f, char *p)
-{
-int i;
- for (i=0; i<4; i++)
- fprintf(f,"%02X:",p[i]);
- fprintf(f,"%02X",p[i]);
- return 6;
-}
-
-char *errcode2str(st)
-{
-char *rval;
- switch(st) {
- case ETH_OK:
- rval = "OK";
- break;
- case ETH_ERROR:
- rval = "Fundamental error.";
- break;
- case ETH_RETRY:
- rval = "Could not process request. Try later.";
- break;
- case ETH_END_OF_JOB:
- rval = "Ring has nothing to process.";
- break;
- case ETH_QUEUE_FULL:
- rval = "Ring resource error.";
- break;
- case ETH_QUEUE_LAST_RESOURCE:
- rval = "Ring resources about to exhaust.";
- break;
- default:
- rval = "UNKNOWN"; break;
- }
- return rval;
-}
-
-
-#if 0
-int
-mveth_rx(struct mv64340_private *mp)
-{
-int st;
-struct pkt_info p;
- if ( ETH_OK != (st=eth_port_receive(mp, &p)) ) {
- fprintf(stderr,"receive: %s\n", errcode2str(st));
- return -1;
- }
- printf("%i bytes received from ", p.byte_cnt);
- preth(stdout,(char*)p.buf_ptr+6);
- printf(" (desc. stat: 0x%08x)\n", p.cmd_sts);
-
- p.byte_cnt = sizeof(rx_buf[0]);
- p.buf_ptr -= RX_BUF_OFFSET;
- if ( ETH_OK != (st=eth_rx_return_buff(mp,&p) ) ) {
- fprintf(stderr,"returning buffer: %s\n", errcode2str(st));
- return -1;
- }
- return 0;
-}
-#endif
-
-int
-dring()
-{
-int i;
-if (1) {
-struct eth_rx_desc *pr;
-printf("RX:\n");
- for (i=0, pr=rx_ring; i<RX_RING_SIZE; i+=RX_SPACING, pr+=RX_SPACING) {
- dcbi(pr);
- printf("cnt: 0x%04x, size: 0x%04x, stat: 0x%08x, next: 0x%08x, buf: 0x%08x\n",
- pr->byte_cnt, pr->buf_size, pr->cmd_sts, pr->next_desc_ptr, pr->buf_ptr);
- }
-}
-if (1) {
-struct eth_tx_desc *pt;
-printf("TX:\n");
- for (i=0, pt=tx_ring; i<TX_RING_SIZE; i+=TX_SPACING, pt+=TX_SPACING) {
- dcbi(pt);
- printf("cnt: 0x%04x, stat: 0x%08x, next: 0x%08x, buf: 0x%08x\n",
- pt->byte_cnt, pt->cmd_sts, pt->next_desc_ptr, pt->buf_ptr);
- }
-}
- return 0;
-}
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/porting/LICENSE b/c/src/lib/libbsp/powerpc/beatnik/network/porting/LICENSE
deleted file mode 100644
index 62b91ab03d..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/porting/LICENSE
+++ /dev/null
@@ -1,51 +0,0 @@
-/* NOTE: The terms described in this LICENSE file apply only to the
- * files created by the author (see below). Consult individual
- * file headers for more details. Some files were ported from
- * netbsd and/or freebsd and are covered by the respective
- * file header copyright notices.
- */
-
-/*
- * Authorship
- * ----------
- * This software ('RTEMS-portability wrappers for BSD network drivers') was
- * created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
- * Stanford Linear Accelerator Center, Stanford University.
- *
- * Acknowledgement of sponsorship
- * ------------------------------
- * The 'RTEMS-portability wrappers for BSD network drivers' software was produced by
- * the Stanford Linear Accelerator Center, Stanford University,
- * under Contract DE-AC03-76SFO0515 with the Department of Energy.
- *
- * Government disclaimer of liability
- * ----------------------------------
- * Neither the United States nor the United States Department of Energy,
- * nor any of their employees, makes any warranty, express or implied, or
- * assumes any legal liability or responsibility for the accuracy,
- * completeness, or usefulness of any data, apparatus, product, or process
- * disclosed, or represents that its use would not infringe privately owned
- * rights.
- *
- * Stanford disclaimer of liability
- * --------------------------------
- * Stanford University makes no representations or warranties, express or
- * implied, nor assumes any liability for the use of this software.
- *
- * Stanford disclaimer of copyright
- * --------------------------------
- * Stanford University, owner of the copyright, hereby disclaims its
- * copyright and all other rights in this software. Hence, anyone may
- * freely use it for any purpose without restriction.
- *
- * Maintenance of notices
- * ----------------------
- * In the interest of clarity regarding the origin and status of this
- * SLAC software, this and all the preceding Stanford University notices
- * are to remain affixed to any copy or derivative of this software made
- * or distributed by the recipient and are to be affixed to any copy of
- * software made or distributed by the recipient that contains a copy or
- * derivative of this software.
- *
- * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
- */
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/porting/Makefile.template b/c/src/lib/libbsp/powerpc/beatnik/network/porting/Makefile.template
deleted file mode 100644
index 3c5d6e3e33..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/porting/Makefile.template
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# Makefile.lib,v 1.5 2000/06/12 15:00:14 joel Exp
-#
-# Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
-# License: see LICENSE file.
-#
-# Templates/Makefile.lib
-# Template library Makefile
-#
-
-LIBNAME=libif_XXX.a # XXX- your library names goes here
-LIB=${ARCH}/${LIBNAME}
-
-# C and C++ source names, if any, go here -- minus the .c or .cc
-C_PIECES=if_XXX if_XXX_rtems
-C_FILES=$(C_PIECES:%=%.c)
-C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
-
-CC_PIECES=
-CC_FILES=$(CC_PIECES:%=%.cc)
-CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o)
-
-H_FILES=
-
-# Assembly source names, if any, go here -- minus the .S
-S_PIECES=
-S_FILES=$(S_PIECES:%=%.S)
-S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
-
-SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
-OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
-
-include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
-
-include $(RTEMS_CUSTOM)
-include $(RTEMS_ROOT)/make/lib.cfg
-
-#
-# Add local stuff here using +=
-#
-
-#DEFINES += -DHAVE_LIBBSPEXT -DDEBUG_MODULAR
-CPPFLAGS += -I. -Ilibchip -Iporting
-# bsdnet newproc generated daemon is non-FP;
-# prevent optimizer from generating FP instructions
-CFLAGS += -Wno-unused-variable -msoft-float
-
-#
-# Add your list of files to delete here. The config files
-# already know how to delete some stuff, so you may want
-# to just run 'make clean' first to see what gets missed.
-# 'make clobber' already includes 'make clean'
-#
-
-CLEAN_ADDITIONS +=
-CLOBBER_ADDITIONS +=
-
-all: ${ARCH} $(SRCS) $(LIB)
-
-$(LIB): ${OBJS}
- $(make-library)
-
-ifndef RTEMS_SITE_INSTALLDIR
-RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE)
-endif
-
-${RTEMS_SITE_INSTALLDIR}/include \
-${RTEMS_SITE_INSTALLDIR}/lib \
-${RTEMS_SITE_INSTALLDIR}/bin \
-${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/include \
-${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/lib \
-${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/bin :
- test -d $@ || mkdir -p $@
-
-# Install the library, appending _g or _p as appropriate.
-# for include files, just use $(INSTALL_CHANGE)
-#
-# NOTES:
-# - BSP specific libraries, headers etc. should be installed to
-# $RTEMS_SITE_INSTALLDIR)/$(RTEMS_BSP)/lib
-#
-
-install: all $(RTEMS_SITE_INSTALLDIR)/lib
- $(INSTALL_VARIANT) -m 644 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/porting/README b/c/src/lib/libbsp/powerpc/beatnik/network/porting/README
deleted file mode 100644
index b262d7797c..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/porting/README
+++ /dev/null
@@ -1,104 +0,0 @@
-Templates to help porting freebsd networking drivers
-to rtems (focus on i386 and powerpc) using a 'quick and dirty'
-approach.
-This is not an elegant piece of software -- be warned.
-
-/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
- * License: see LICENSE file.
- */
-
-Usage:
-
- A obtain the freebsd driver source. It usually is made
- up of a
- if_XXX.c -- core driver
- if_XXXreg.h -- core header
- if_XXXvar.h -- some have it, some don't
- if_XXX_<bus>.c -- glue to integrate the core
- driver with different environments
- (such as pccard, pci, ...). There
- are several of these.
-
- Note that you might have to get an older version
- as some structures and interfaces may have undergone
- significant changes since the bsd/networking version that
- was ported to rtems.
-
- B Copy the Makefile and rtemscompat_defs.h templates to the
- driver source dir and edit them.
-
- C Edit if_XXXreg.h and comment all unneeded fields from the
- 'softc' structure declaration with
-
- #ifndef __rtems__
- #endif
-
- In particular, the bushandle field (as defined in rtemscompat_defs.h)
- above, see comments in the template) must be re-declared:
-
- #ifndef __rtems__
- bus_space_handle_t XXX_bhandle;
- #else
- unsigned XXX_bhandle;
- unsigned char irq_no;
- unsigned char b,d,f; /* PCI tuple; needed for PCI only */
- rtems_id tid; /* driver task id */
- #endif
-
- Later, the compilation attempts will help identifying
- fields that need to be removed.
-
- I like the #ifdef __rtems__ construct as it minimizes changes
- to the source thus making merging updated driver versions easier.
-
- D Edit if_XXX.c; at the very top, include the lines
-
- #ifdef __rtems__
- #include <rtemscompat.h>
- #endif
-
- use the #ifndef __rtems__ #endif construct to comment
- unneeded / unsupported inclusion of headers and code pieces.
-
- - inclusion of net/if_media.h must usually be mapped to
- libchip/if_media.h
-
- comment all vm, machine, bus, mii etc. related headers.
-
- - replace inclusion of if_XXXreg.h by
-
- #include "if_XXXreg.h"
- #include <rtemscompat1.h>
-
- - work through the if_XXX.c and if_XXXreg.h files commenting
- stuff until if_XXX.c compiles. This might involve hacking
- the helper headers.
-
- - pay attention to endian issues; things may need to be fixed!
-
- - at the top where the freebsd 'methods' and the like are
- commented, add a definition of the driver methods for RTEMS:
-
- #ifdef __rtems__
- net_drv_tbl_t METHODS = {
- n_probe : XXX_probe,
- n_attach : XXX_attach,
- n_detach : XXX_detach, /* optional; */
- n_intr : XXX_intr, /* freebsd ISR; executed from daemon under RTEMS */
- };
- #endif
-
- - make sure all the if_xxx methods are set; in particular,
- set
- sc->if_output = ether_output;
-
- - on input:
- you can use DO_ETHER_INPUT_SKIPPING_ETHER_HEADER() macro
- -- if you don't MAKE SURE THE RECEIVING INTERFACE IS SET
- in the mbuf packet header!!!
-
- E create 'rtems_<chip>_setup()' to probe for devices and
- set the softc struct's base address, interrupt line and
- bus/dev/fun triple (PCI only).
- For PCI devices, a generic setup routine already comes with
- porting/if_xxx_rtems.c -> nothing needs to be written!
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/porting/if_xxx.modini.c b/c/src/lib/libbsp/powerpc/beatnik/network/porting/if_xxx.modini.c
deleted file mode 100644
index 1abad7dc22..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/porting/if_xxx.modini.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <rtems.h>
-#include <porting/rtemscompat.h>
-
-/* CEXP module initialization/finalization */
-
-/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
- * License: see LICENSE file.
- */
-
-void
-_cexpModuleInitialize(void *unused)
-{
-extern void NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringup)(char *);
- METHODSPTR = &METHODS;
-/*
-#ifdef DEBUG
- NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringup)("192.168.2.13/255.255.255.0");
-#endif
-*/
-}
-
-int
-_cexpModuleFinalize(void *unused)
-{
-#ifdef DEBUG
-extern int NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringdown)();
- if (NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringdown)())
- return -1;
- METHODSPTR = 0;
- return 0;
-#else
- return -1;
-#endif
-}
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/porting/if_xxx_rtems.c b/c/src/lib/libbsp/powerpc/beatnik/network/porting/if_xxx_rtems.c
deleted file mode 100644
index a0d459ff47..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/porting/if_xxx_rtems.c
+++ /dev/null
@@ -1,500 +0,0 @@
-#include "rtemscompat.h"
-
-/* Template for driver task, setup and attach routines. To be instantiated
- * by defining the relevant symbols in header files.
- */
-
-/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
- * License: see LICENSE file.
- */
-
-#include <rtems/irq.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <net/if_media.h>
-
-#ifdef IF_REG_HEADER
-#include IF_REG_HEADER
-#endif
-#ifdef IF_VAR_HEADER
-#include IF_VAR_HEADER
-#endif
-
-#include "rtemscompat1.h"
-
-#define EX_EVENT RTEMS_EVENT_1
-#undef IRQ_AT_8259
-
-NETDEV_DECL = { /*[0]:*/{ /* softc: */ { /* arpcom: */{ /* ac_if: */ { 0 }}}}};
-
-static void net_daemon(void *arg);
-
-#ifdef HAVE_LIBBSPEXT
-#include <bsp/bspExt.h>
-static void the_net_isr(void *);
-#else
-static void noop(const rtems_irq_connect_data *unused) {}
-static int noop1(const rtems_irq_connect_data *unused) { return 0;}
-#if ISMINVERSION(4,6,99)
-static void the_net_isr(rtems_irq_hdl_param);
-#else
-static void the_net_isr();
-#if NETDRIVER_SLOTS > 1
-#error only one instance supported (stupid IRQ API)
-#else
-static struct NET_SOFTC *thesc;
-#endif
-#endif
-#endif
-
-#if defined(NETDRIVER_PCI)
-/* Public setup routine for PCI devices;
- * TODO: currently doesn't work for subsystem vendor/id , i.e.
- * devices behind a standard PCI interface...
- */
-int
-NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_pci_setup)(int inst);
-#endif
-
-static unsigned
-NET_EMBEMB(,NETDRIVER_PREFIX,_net_driver_ticks_per_sec) = 0;
-
-/* other drivers may already have this created */
-extern unsigned net_driver_ticks_per_sec
-__attribute__((weak, alias(NET_STRSTR(NETDRIVER_PREFIX)"_net_driver_ticks_per_sec") ));
-
-#ifdef DEBUG_MODULAR
-net_drv_tbl_t * volatile METHODSPTR = 0;
-#endif
-
-
-int
-NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_attach)
- (struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- int error = 0;
- device_t dev = net_dev_get(config);
- struct NET_SOFTC *sc;
- struct ifnet *ifp;
-#ifndef HAVE_LIBBSPEXT
- rtems_irq_connect_data irq_data = {
- 0,
- the_net_isr,
-#if ISMINVERSION(4,6,99)
- 0,
-#endif
- noop,
- noop,
- noop1 };
-#endif
-
- if ( !dev )
- return 1;
-
- if ( !dev->d_softc.NET_SOFTC_BHANDLE_FIELD ) {
-#if defined(NETDRIVER_PCI)
- device_printf(dev,NETDRIVER" unit not configured; executing setup...");
- /* setup should really be performed prior to attaching.
- * Wipe the device; setup and re-obtain the device...
- */
- memset(dev,0,sizeof(*dev));
- error = NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_pci_setup)(-1);
- /* re-obtain the device */
- dev = net_dev_get(config);
- if ( !dev ) {
- printk("Unable to re-assign device structure???\n");
- return 1;
- }
- if (error <= 0) {
- device_printf(dev,NETDRIVER" FAILED; unable to attach interface, sorry\n");
- return 1;
- }
- device_printf(dev,"success\n");
-#else
- device_printf(dev,NETDRIVER" unit not configured; use 'rtems_"NETDRIVER"_setup()'\n");
- return 1;
-#endif
- }
-
- if ( !net_driver_ticks_per_sec )
- net_driver_ticks_per_sec = rtems_clock_get_ticks_per_second();
-
- sc = device_get_softc( dev );
- ifp = &sc->arpcom.ac_if;
-
-#ifdef DEBUG_MODULAR
- if (!METHODSPTR) {
- device_printf(dev,NETDRIVER": method pointer not set\n");
- return -1;
- }
-#endif
-
- if ( attaching ) {
- if ( ifp->if_init ) {
- device_printf(dev,NETDRIVER" Driver already attached.\n");
- return -1;
- }
- if ( config->hardware_address ) {
- /* use configured MAC address */
- memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
- } else {
-#ifdef NET_READ_MAC_ADDR
- NET_READ_MAC_ADDR(sc);
-#endif
- }
- if ( METHODSPTR->n_attach(dev) ) {
- device_printf(dev,NETDRIVER"_attach() failed\n");
- return -1;
- }
- } else {
- if ( !ifp->if_init ) {
- device_printf(dev,NETDRIVER" Driver not attached.\n");
- return -1;
- }
- if ( METHODSPTR->n_detach ) {
- if ( METHODSPTR->n_detach(dev) ) {
- device_printf(dev,NETDRIVER"_detach() failed\n");
- return -1;
- }
- } else {
- device_printf(dev,NETDRIVER"_detach() not implemented\n");
- return -1;
- }
- }
-
-
- if ( !sc->tid )
- sc->tid = rtems_bsdnet_newproc(NETDRIVER"d", 4096, net_daemon, sc);
-
- if (attaching) {
-#ifdef DEBUG
- printf("Installing IRQ # %i\n",sc->irq_no);
-#endif
-#ifdef HAVE_LIBBSPEXT
- if ( bspExtInstallSharedISR(sc->irq_no, the_net_isr, sc, 0) )
-#else
- /* BSP dependent :-( */
- irq_data.name = sc->irq_no;
-#if ISMINVERSION(4,6,99)
- irq_data.handle = (rtems_irq_hdl_param)sc;
-#else
- thesc = sc;
-#endif
- if ( ! BSP_install_rtems_irq_handler( &irq_data ) )
-#endif
- {
- fprintf(stderr,NETDRIVER": unable to install ISR\n");
- error = -1;
- }
- } else {
- if ( sc->irq_no ) {
-#ifdef DEBUG
- printf("Removing IRQ # %i\n",sc->irq_no);
-#endif
-#ifdef HAVE_LIBBSPEXT
- if (bspExtRemoveSharedISR(sc->irq_no, the_net_isr, sc))
-#else
- /* BSP dependent :-( */
- irq_data.name = sc->irq_no;
-#if ISMINVERSION(4,6,99)
- irq_data.handle = (rtems_irq_hdl_param)sc;
-#endif
- if ( ! BSP_remove_rtems_irq_handler( &irq_data ) )
-#endif
- {
- fprintf(stderr,NETDRIVER": unable to uninstall ISR\n");
- error = -1;
- }
- }
- }
- return error;
-}
-
-static void
-the_net_isr(
-#ifdef HAVE_LIBBSPEXT
-void *thesc
-#elif ISMINVERSION(4,6,99)
-rtems_irq_hdl_param thesc
-#endif
-)
-{
-struct NET_SOFTC *sc = thesc;
-
- /* disable interrupts */
- NET_DISABLE_IRQS(sc);
-
- rtems_bsdnet_event_send( sc->tid, EX_EVENT );
-}
-
-static void net_daemon(void *arg)
-{
-struct NET_SOFTC *sc = arg;
-rtems_event_set evs;
-
- for (;;) {
- rtems_bsdnet_event_receive(
- EX_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &evs);
-
- METHODSPTR->n_intr(sc);
-
- /* re-enable interrupts */
- NET_ENABLE_IRQS(sc);
- }
-}
-
-static struct NET_SOFTC *
-net_drv_check_unit(int unit)
-{
- unit--;
- if ( unit < 0 || unit >= NETDRIVER_SLOTS ) {
- fprintf(stderr,"Invalid unit # %i (not in %i..%i)\n", unit+1, 1, NETDRIVER_SLOTS);
- return 0;
- }
-
- if ( THEDEVS[unit].d_name ) {
- fprintf(stderr,"Unit %i already set up\n", unit+1);
- return 0;
- }
-
- memset( &THEDEVS[unit], 0, sizeof(THEDEVS[0]) );
-
- return &THEDEVS[unit].d_softc;
-}
-
-struct rtems_bsdnet_ifconfig NET_EMBEMB(NETDRIVER_PREFIX,_dbg,_config) = {
- NETDRIVER"1",
- NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_attach),
- 0
-};
-
-#ifdef DEBUG
-void
-NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringup)(char *ipaddr)
-{
-short flags;
-struct sockaddr_in addr;
-char *mask;
-
-
- if (!ipaddr) {
- printf("Need an ip[/mask] argument (dot notation)\n");
- return;
- }
-
- ipaddr = strdup(ipaddr);
-
- if ( (mask = strchr(ipaddr,'/')) ) {
- *mask++=0;
- } else {
- mask = "255.255.255.0";
- }
-
-#if defined(NETDRIVER_PCI)
- /* this fails if already setup */
- NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_pci_setup)(-1);
-#endif
- rtems_bsdnet_attach(&NET_EMBEMB(NETDRIVER_PREFIX,_dbg,_config));
-
- flags = IFF_UP /*| IFF_PROMISC*/;
- if ( rtems_bsdnet_ifconfig(NETDRIVER"1",SIOCSIFFLAGS,&flags) < 0 ) {
- printf("Can't bring '"NETDRIVER"1' up\n");
- goto cleanup;
- }
- memset(&addr,0,sizeof(addr));
- addr.sin_len = sizeof(addr);
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr(mask);
- if ( rtems_bsdnet_ifconfig(NETDRIVER"1",SIOCSIFNETMASK,&addr) < 0 ) {
- printf("Unable to set netmask on '"NETDRIVER"1'\n");
- goto cleanup;
- }
- addr.sin_addr.s_addr = inet_addr(ipaddr);
- if ( rtems_bsdnet_ifconfig(NETDRIVER"1",SIOCSIFADDR,&addr) < 0 ) {
- printf("Unable to set address on '"NETDRIVER"1'\n");
- goto cleanup;
- }
-cleanup:
- the_real_free (ipaddr);
-}
-
-int
-NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringdown)()
-{
-short flags;
- flags = 0;
- if ( rtems_bsdnet_ifconfig(NETDRIVER"1",SIOCSIFFLAGS,&flags) < 0 ) {
- printf("Can't bring '"NETDRIVER"1' down\n");
- return -1;
- }
-
- rtems_bsdnet_detach(&NET_EMBEMB(NETDRIVER_PREFIX,_dbg,_config));
- return 0;
-}
-#endif
-
-
-#if defined(NETDRIVER_PCI) && !defined(NETDRIVER_OWN_SETUP)
-/* Public setup routine for PCI devices;
- * TODO: currently doesn't work for subsystem vendor/id , i.e.
- * devices behind a standard PCI interface...
- * passing 'inst' > only sets-up the 'inst'th card; passing
- * 'inst' == 0 sets-up all matching cards.
- */
-int
-NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_pci_setup)(int inst)
-{
-unsigned b,d,f,i,isio,unit;
-rtemscompat_32_t base;
-unsigned short cmd,id;
-unsigned char h;
-struct NET_SOFTC *sc;
-unsigned try[] = { PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, 0 };
-
-#ifdef DEBUG_MODULAR
- if ( !METHODSPTR ) {
- fprintf(stderr,NETDRIVER": Methods pointer not set\n");
- return -1;
- }
-#endif
-
- /* 0 can be reached when looking for the desired instance */
- if ( 0 == inst )
- inst = -1;
-
-#ifdef HAVE_LIBBSPEXT
- /* make sure it's initialized */
- bspExtInit();
-#endif
-
- /* scan PCI for supported devices */
- for ( b=0, sc=0, unit=0; b<pci_bus_count(); b++ ) {
- for ( d=0; d<PCI_MAX_DEVICES; d++ ) {
- pci_read_config_word(b,d,0,PCI_VENDOR_ID,&id);
- if ( 0xffff == id )
- continue; /* empty slot */
-
- pci_read_config_byte(b,d,0,PCI_HEADER_TYPE,&h);
- h = h&0x80 ? PCI_MAX_FUNCTIONS : 1; /* multifunction device ? */
-
- for ( f=0; f<h; f++ ) {
- if ( !sc && !(sc=net_drv_check_unit(unit+1))) {
- fprintf(stderr,"Not enough driver slots; stop looking for more devices...\n");
- return unit;
- }
- pci_read_config_word(b,d,f,PCI_VENDOR_ID,&id);
- if ( 0xffff == id )
- continue; /* empty slot */
-
- pci_read_config_word(b,d,f,PCI_CLASS_DEVICE,&id);
- if ( PCI_CLASS_NETWORK_ETHERNET != id )
- continue; /* only look at ethernet devices */
-
- sc->b = b;
- sc->d = d;
- sc->f = f;
-
- for ( i=0, base=0, isio=0; try[i]; i++ ) {
- pci_read_config_dword(b,d,f,try[i],&base);
- if ( base ) {
- if ( (isio = (PCI_BASE_ADDRESS_SPACE_IO == (base & PCI_BASE_ADDRESS_SPACE )) ) ) {
-#ifdef NET_CHIP_PORT_IO
- base &= PCI_BASE_ADDRESS_IO_MASK;
- sc->NET_SOFTC_BHANDLE_FIELD = PCI_IO_2LOCAL(base,b);
-#ifdef DEBUG
- printf("Found PCI I/O Base 0x%08x\n", (unsigned)base);
-#endif
-#else
- base = 0;
- continue;
-#endif
- } else {
-#ifdef NET_CHIP_MEM_IO
- base &= PCI_BASE_ADDRESS_MEM_MASK;
- sc->NET_SOFTC_BHANDLE_FIELD = PCI2LOCAL(base,b);
-#ifdef DEBUG
- printf("Found PCI MEM Base 0x%08x\n", (unsigned)base);
-#endif
-#else
- base = 0;
- continue;
-#endif
- }
- break;
- }
- }
- if ( !base ) {
-#ifdef DEBUG
- fprintf(stderr, NETDRIVER": (warning) Neither PCI base address 0 nor 1 are configured; skipping bus %i, slot %i, fn %i...\n",b,d,f);
-#endif
- continue;
- }
-
- if ( 0 == METHODSPTR->n_probe(&THEDEVS[unit]) && (inst < 0 || !--inst) ) {
- pci_read_config_word(b,d,f,PCI_COMMAND,&cmd);
- pci_write_config_word(b,d,f,PCI_COMMAND,
- cmd | (isio ? PCI_COMMAND_IO : PCI_COMMAND_MEMORY) | PCI_COMMAND_MASTER );
- pci_read_config_byte(b,d,f,PCI_INTERRUPT_LINE,&sc->irq_no);
- printf(NETDRIVER": card found @PCI[%s] 0x%08x (local 0x%08x), IRQ %i\n",
- (isio ? "io" : "mem"), (unsigned)base, sc->NET_SOFTC_BHANDLE_FIELD, sc->irq_no);
-
- sc = 0; /* need to allocate a new slot */
- unit++;
-
- if ( 0 == inst ) {
- /* found desired instance */
- goto terminated;
- }
- }
- }
- }
- }
-
-terminated:
- return unit;
-}
-#else
-
-/* simple skeleton
-int
-NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_setup)(
- int unit,
- void *base_addr,
- int irq_no)
-{
-struct NET_SOFTC *sc;
- if ( !(sc=net_drv_check_unit(unit)) ) {
- fprintf(stderr,"Bad unit number -- (not enought driver slots?)\n");
- return 0;
- }
- sc->NET_SOFTC_BHANDLE_FIELD = base_addr;
- if ( 0 == METHODSPTR->n_probe(&THEDEVS[unit-1]) ) {
- sc->irq_no = irq_no;
- printf(NETDRIVER": Unit %i set up\n", unit);
- return unit;
- }
- return 0;
-}
-*/
-
-#endif
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/porting/pcireg.h b/c/src/lib/libbsp/powerpc/beatnik/network/porting/pcireg.h
deleted file mode 100644
index 8487f5b8f6..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/porting/pcireg.h
+++ /dev/null
@@ -1,405 +0,0 @@
-/*-
- * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
- * 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 unmodified, 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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: /repoman/r/ncvs/src/sys/dev/pci/pcireg.h,v 1.39.4.3 2005/04/02 05:03:34 jmg Exp $
- *
- */
-
-/*
- * PCIM_xxx: mask to locate subfield in register
- * PCIR_xxx: config register offset
- * PCIC_xxx: device class
- * PCIS_xxx: device subclass
- * PCIP_xxx: device programming interface
- * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
- * PCID_xxx: device ID
- * PCIY_xxx: capability identification number
- */
-
-/* some PCI bus constants */
-
-#define PCI_BUSMAX 255
-#define PCI_SLOTMAX 31
-#define PCI_FUNCMAX 7
-#define PCI_REGMAX 255
-#define PCI_MAXHDRTYPE 2
-
-/* PCI config header registers for all devices */
-
-#define PCIR_DEVVENDOR 0x00
-#define PCIR_VENDOR 0x00
-#define PCIR_DEVICE 0x02
-#define PCIR_COMMAND 0x04
-#define PCIM_CMD_PORTEN 0x0001
-#define PCIM_CMD_MEMEN 0x0002
-#define PCIM_CMD_BUSMASTEREN 0x0004
-#define PCIM_CMD_SPECIALEN 0x0008
-#define PCIM_CMD_MWRICEN 0x0010
-#define PCIM_CMD_PERRESPEN 0x0040
-#define PCIM_CMD_SERRESPEN 0x0100
-#define PCIM_CMD_BACKTOBACK 0x0200
-#define PCIR_STATUS 0x06
-#define PCIM_STATUS_CAPPRESENT 0x0010
-#define PCIM_STATUS_66CAPABLE 0x0020
-#define PCIM_STATUS_BACKTOBACK 0x0080
-#define PCIM_STATUS_PERRREPORT 0x0100
-#define PCIM_STATUS_SEL_FAST 0x0000
-#define PCIM_STATUS_SEL_MEDIMUM 0x0200
-#define PCIM_STATUS_SEL_SLOW 0x0400
-#define PCIM_STATUS_SEL_MASK 0x0600
-#define PCIM_STATUS_STABORT 0x0800
-#define PCIM_STATUS_RTABORT 0x1000
-#define PCIM_STATUS_RMABORT 0x2000
-#define PCIM_STATUS_SERR 0x4000
-#define PCIM_STATUS_PERR 0x8000
-#define PCIR_REVID 0x08
-#define PCIR_PROGIF 0x09
-#define PCIR_SUBCLASS 0x0a
-#define PCIR_CLASS 0x0b
-#define PCIR_CACHELNSZ 0x0c
-#define PCIR_LATTIMER 0x0d
-#define PCIR_HDRTYPE 0x0e
-#ifndef BURN_BRIDGES
-#define PCIR_HEADERTYPE PCIR_HDRTYPE
-#endif
-#define PCIM_HDRTYPE 0x7f
-#define PCIM_HDRTYPE_NORMAL 0x00
-#define PCIM_HDRTYPE_BRIDGE 0x01
-#define PCIM_HDRTYPE_CARDBUS 0x02
-#define PCIM_MFDEV 0x80
-#define PCIR_BIST 0x0f
-
-/* Capability Identification Numbers */
-
-#define PCIY_PMG 0x01 /* PCI Power Management */
-#define PCIY_AGP 0x02 /* AGP */
-#define PCIY_VPD 0x03 /* Vital Product Data */
-#define PCIY_SLOTID 0x04 /* Slot Identification */
-#define PCIY_MSI 0x05 /* Message Signaled Interrupts */
-#define PCIY_CHSWP 0x06 /* CompactPCI Hot Swap */
-#define PCIY_PCIX 0x07 /* PCI-X */
-#define PCIY_HT 0x08 /* HyperTransport */
-#define PCIY_VENDOR 0x09 /* Vendor Unique */
-#define PCIY_DEBUG 0x0a /* Debug port */
-#define PCIY_CRES 0x0b /* CompactPCI central resource control */
-#define PCIY_HOTPLUG 0x0c /* PCI Hot-Plug */
-#define PCIY_AGP8X 0x0e /* AGP 8x */
-#define PCIY_SECDEV 0x0f /* Secure Device */
-#define PCIY_EXPRESS 0x10 /* PCI Express */
-#define PCIY_MSIX 0x11 /* MSI-X */
-
-/* config registers for header type 0 devices */
-
-#define PCIR_BARS 0x10
-#define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
-#ifndef BURN_BRIDGES
-#define PCIR_MAPS PCIR_BARS
-#endif
-#define PCIR_CARDBUSCIS 0x28
-#define PCIR_SUBVEND_0 0x2c
-#define PCIR_SUBDEV_0 0x2e
-#define PCIR_BIOS 0x30
-#define PCIM_BIOS_ENABLE 0x01
-#define PCIR_CAP_PTR 0x34
-#define PCIR_INTLINE 0x3c
-#define PCIR_INTPIN 0x3d
-#define PCIR_MINGNT 0x3e
-#define PCIR_MAXLAT 0x3f
-
-/* config registers for header type 1 (PCI-to-PCI bridge) devices */
-
-#define PCIR_SECSTAT_1 0x1e
-
-#define PCIR_PRIBUS_1 0x18
-#define PCIR_SECBUS_1 0x19
-#define PCIR_SUBBUS_1 0x1a
-#define PCIR_SECLAT_1 0x1b
-
-#define PCIR_IOBASEL_1 0x1c
-#define PCIR_IOLIMITL_1 0x1d
-#define PCIR_IOBASEH_1 0x30
-#define PCIR_IOLIMITH_1 0x32
-#define PCIM_BRIO_16 0x0
-#define PCIM_BRIO_32 0x1
-#define PCIM_BRIO_MASK 0xf
-
-#define PCIR_MEMBASE_1 0x20
-#define PCIR_MEMLIMIT_1 0x22
-
-#define PCIR_PMBASEL_1 0x24
-#define PCIR_PMLIMITL_1 0x26
-#define PCIR_PMBASEH_1 0x28
-#define PCIR_PMLIMITH_1 0x2c
-
-#define PCIR_BRIDGECTL_1 0x3e
-
-#define PCIR_SUBVEND_1 0x34
-#define PCIR_SUBDEV_1 0x36
-
-/* config registers for header type 2 (CardBus) devices */
-
-#define PCIR_SECSTAT_2 0x16
-
-#define PCIR_PRIBUS_2 0x18
-#define PCIR_SECBUS_2 0x19
-#define PCIR_SUBBUS_2 0x1a
-#define PCIR_SECLAT_2 0x1b
-
-#define PCIR_MEMBASE0_2 0x1c
-#define PCIR_MEMLIMIT0_2 0x20
-#define PCIR_MEMBASE1_2 0x24
-#define PCIR_MEMLIMIT1_2 0x28
-#define PCIR_IOBASE0_2 0x2c
-#define PCIR_IOLIMIT0_2 0x30
-#define PCIR_IOBASE1_2 0x34
-#define PCIR_IOLIMIT1_2 0x38
-
-#define PCIR_BRIDGECTL_2 0x3e
-
-#define PCIR_SUBVEND_2 0x40
-#define PCIR_SUBDEV_2 0x42
-
-#define PCIR_PCCARDIF_2 0x44
-
-/* PCI device class, subclass and programming interface definitions */
-
-#define PCIC_OLD 0x00
-#define PCIS_OLD_NONVGA 0x00
-#define PCIS_OLD_VGA 0x01
-
-#define PCIC_STORAGE 0x01
-#define PCIS_STORAGE_SCSI 0x00
-#define PCIS_STORAGE_IDE 0x01
-#define PCIP_STORAGE_IDE_MODEPRIM 0x01
-#define PCIP_STORAGE_IDE_PROGINDPRIM 0x02
-#define PCIP_STORAGE_IDE_MODESEC 0x04
-#define PCIP_STORAGE_IDE_PROGINDSEC 0x08
-#define PCIP_STORAGE_IDE_MASTERDEV 0x80
-#define PCIS_STORAGE_FLOPPY 0x02
-#define PCIS_STORAGE_IPI 0x03
-#define PCIS_STORAGE_RAID 0x04
-#define PCIS_STORAGE_OTHER 0x80
-
-#define PCIC_NETWORK 0x02
-#define PCIS_NETWORK_ETHERNET 0x00
-#define PCIS_NETWORK_TOKENRING 0x01
-#define PCIS_NETWORK_FDDI 0x02
-#define PCIS_NETWORK_ATM 0x03
-#define PCIS_NETWORK_ISDN 0x04
-#define PCIS_NETWORK_OTHER 0x80
-
-#define PCIC_DISPLAY 0x03
-#define PCIS_DISPLAY_VGA 0x00
-#define PCIS_DISPLAY_XGA 0x01
-#define PCIS_DISPLAY_3D 0x02
-#define PCIS_DISPLAY_OTHER 0x80
-
-#define PCIC_MULTIMEDIA 0x04
-#define PCIS_MULTIMEDIA_VIDEO 0x00
-#define PCIS_MULTIMEDIA_AUDIO 0x01
-#define PCIS_MULTIMEDIA_TELE 0x02
-#define PCIS_MULTIMEDIA_OTHER 0x80
-
-#define PCIC_MEMORY 0x05
-#define PCIS_MEMORY_RAM 0x00
-#define PCIS_MEMORY_FLASH 0x01
-#define PCIS_MEMORY_OTHER 0x80
-
-#define PCIC_BRIDGE 0x06
-#define PCIS_BRIDGE_HOST 0x00
-#define PCIS_BRIDGE_ISA 0x01
-#define PCIS_BRIDGE_EISA 0x02
-#define PCIS_BRIDGE_MCA 0x03
-#define PCIS_BRIDGE_PCI 0x04
-#define PCIS_BRIDGE_PCMCIA 0x05
-#define PCIS_BRIDGE_NUBUS 0x06
-#define PCIS_BRIDGE_CARDBUS 0x07
-#define PCIS_BRIDGE_RACEWAY 0x08
-#define PCIS_BRIDGE_OTHER 0x80
-
-#define PCIC_SIMPLECOMM 0x07
-#define PCIS_SIMPLECOMM_UART 0x00
-#define PCIP_SIMPLECOMM_UART_16550A 0x02
-#define PCIS_SIMPLECOMM_PAR 0x01
-#define PCIS_SIMPLECOMM_MULSER 0x02
-#define PCIS_SIMPLECOMM_MODEM 0x03
-#define PCIS_SIMPLECOMM_OTHER 0x80
-
-#define PCIC_BASEPERIPH 0x08
-#define PCIS_BASEPERIPH_PIC 0x00
-#define PCIS_BASEPERIPH_DMA 0x01
-#define PCIS_BASEPERIPH_TIMER 0x02
-#define PCIS_BASEPERIPH_RTC 0x03
-#define PCIS_BASEPERIPH_PCIHOT 0x04
-#define PCIS_BASEPERIPH_OTHER 0x80
-
-#define PCIC_INPUTDEV 0x09
-#define PCIS_INPUTDEV_KEYBOARD 0x00
-#define PCIS_INPUTDEV_DIGITIZER 0x01
-#define PCIS_INPUTDEV_MOUSE 0x02
-#define PCIS_INPUTDEV_SCANNER 0x03
-#define PCIS_INPUTDEV_GAMEPORT 0x04
-#define PCIS_INPUTDEV_OTHER 0x80
-
-#define PCIC_DOCKING 0x0a
-#define PCIS_DOCKING_GENERIC 0x00
-#define PCIS_DOCKING_OTHER 0x80
-
-#define PCIC_PROCESSOR 0x0b
-#define PCIS_PROCESSOR_386 0x00
-#define PCIS_PROCESSOR_486 0x01
-#define PCIS_PROCESSOR_PENTIUM 0x02
-#define PCIS_PROCESSOR_ALPHA 0x10
-#define PCIS_PROCESSOR_POWERPC 0x20
-#define PCIS_PROCESSOR_MIPS 0x30
-#define PCIS_PROCESSOR_COPROC 0x40
-
-#define PCIC_SERIALBUS 0x0c
-#define PCIS_SERIALBUS_FW 0x00
-#define PCIS_SERIALBUS_ACCESS 0x01
-#define PCIS_SERIALBUS_SSA 0x02
-#define PCIS_SERIALBUS_USB 0x03
-#define PCIP_SERIALBUS_USB_UHCI 0x00
-#define PCIP_SERIALBUS_USB_OHCI 0x10
-#define PCIP_SERIALBUS_USB_EHCI 0x20
-#define PCIS_SERIALBUS_FC 0x04
-#define PCIS_SERIALBUS_SMBUS 0x05
-
-#define PCIC_WIRELESS 0x0d
-#define PCIS_WIRELESS_IRDA 0x00
-#define PCIS_WIRELESS_IR 0x01
-#define PCIS_WIRELESS_RF 0x10
-#define PCIS_WIRELESS_OTHER 0x80
-
-#define PCIC_INTELLIIO 0x0e
-#define PCIS_INTELLIIO_I2O 0x00
-
-#define PCIC_SATCOM 0x0f
-#define PCIS_SATCOM_TV 0x01
-#define PCIS_SATCOM_AUDIO 0x02
-#define PCIS_SATCOM_VOICE 0x03
-#define PCIS_SATCOM_DATA 0x04
-
-#define PCIC_CRYPTO 0x10
-#define PCIS_CRYPTO_NETCOMP 0x00
-#define PCIS_CRYPTO_ENTERTAIN 0x10
-#define PCIS_CRYPTO_OTHER 0x80
-
-#define PCIC_DASP 0x11
-#define PCIS_DASP_DPIO 0x00
-#define PCIS_DASP_OTHER 0x80
-
-#define PCIC_OTHER 0xff
-
-/* PCI power manangement */
-
-#define PCIR_POWER_CAP 0x2
-#define PCIM_PCAP_SPEC 0x0007
-#define PCIM_PCAP_PMEREQCLK 0x0008
-#define PCIM_PCAP_PMEREQPWR 0x0010
-#define PCIM_PCAP_DEVSPECINIT 0x0020
-#define PCIM_PCAP_DYNCLOCK 0x0040
-#define PCIM_PCAP_SECCLOCK 0x00c0
-#define PCIM_PCAP_CLOCKMASK 0x00c0
-#define PCIM_PCAP_REQFULLCLOCK 0x0100
-#define PCIM_PCAP_D1SUPP 0x0200
-#define PCIM_PCAP_D2SUPP 0x0400
-#define PCIM_PCAP_D0PME 0x1000
-#define PCIM_PCAP_D1PME 0x2000
-#define PCIM_PCAP_D2PME 0x4000
-
-#define PCIR_POWER_STATUS 0x4
-#define PCIM_PSTAT_D0 0x0000
-#define PCIM_PSTAT_D1 0x0001
-#define PCIM_PSTAT_D2 0x0002
-#define PCIM_PSTAT_D3 0x0003
-#define PCIM_PSTAT_DMASK 0x0003
-#define PCIM_PSTAT_REPENABLE 0x0010
-#define PCIM_PSTAT_PMEENABLE 0x0100
-#define PCIM_PSTAT_D0POWER 0x0000
-#define PCIM_PSTAT_D1POWER 0x0200
-#define PCIM_PSTAT_D2POWER 0x0400
-#define PCIM_PSTAT_D3POWER 0x0600
-#define PCIM_PSTAT_D0HEAT 0x0800
-#define PCIM_PSTAT_D1HEAT 0x1000
-#define PCIM_PSTAT_D2HEAT 0x1200
-#define PCIM_PSTAT_D3HEAT 0x1400
-#define PCIM_PSTAT_DATAUNKN 0x0000
-#define PCIM_PSTAT_DATADIV10 0x2000
-#define PCIM_PSTAT_DATADIV100 0x4000
-#define PCIM_PSTAT_DATADIV1000 0x6000
-#define PCIM_PSTAT_DATADIVMASK 0x6000
-#define PCIM_PSTAT_PME 0x8000
-
-#define PCIR_POWER_PMCSR 0x6
-#define PCIM_PMCSR_DCLOCK 0x10
-#define PCIM_PMCSR_B2SUPP 0x20
-#define PCIM_BMCSR_B3SUPP 0x40
-#define PCIM_BMCSR_BPCE 0x80
-
-#define PCIR_POWER_DATA 0x7
-
-/* PCI Message Signalled Interrupts (MSI) */
-#define PCIR_MSI_CTRL 0x2
-#define PCIM_MSICTRL_VECTOR 0x0100
-#define PCIM_MSICTRL_64BIT 0x0080
-#define PCIM_MSICTRL_MME_MASK 0x0070
-#define PCIM_MSICTRL_MME_1 0x0000
-#define PCIM_MSICTRL_MME_2 0x0010
-#define PCIM_MSICTRL_MME_4 0x0020
-#define PCIM_MSICTRL_MME_8 0x0030
-#define PCIM_MSICTRL_MME_16 0x0040
-#define PCIM_MSICTRL_MME_32 0x0050
-#define PCIM_MSICTRL_MMC_MASK 0x000E
-#define PCIM_MSICTRL_MMC_1 0x0000
-#define PCIM_MSICTRL_MMC_2 0x0002
-#define PCIM_MSICTRL_MMC_4 0x0004
-#define PCIM_MSICTRL_MMC_8 0x0006
-#define PCIM_MSICTRL_MMC_16 0x0008
-#define PCIM_MSICTRL_MMC_32 0x000A
-#define PCIM_MSICTRL_MSI_ENABLE 0x0001
-#define PCIR_MSI_ADDR 0x4
-#define PCIR_MSI_ADDR_HIGH 0x8
-#define PCIR_MSI_DATA 0x8
-#define PCIR_MSI_DATA_64BIT 0xc
-#define PCIR_MSI_MASK 0x10
-#define PCIR_MSI_PENDING 0x14
-
-/* PCI-X definitions */
-#define PCIXR_COMMAND 0x96
-#define PCIXR_DEVADDR 0x98
-#define PCIXM_DEVADDR_FNUM 0x0003 /* Function Number */
-#define PCIXM_DEVADDR_DNUM 0x00F8 /* Device Number */
-#define PCIXM_DEVADDR_BNUM 0xFF00 /* Bus Number */
-#define PCIXR_STATUS 0x9A
-#define PCIXM_STATUS_64BIT 0x0001 /* Active 64bit connection to device. */
-#define PCIXM_STATUS_133CAP 0x0002 /* Device is 133MHz capable */
-#define PCIXM_STATUS_SCDISC 0x0004 /* Split Completion Discarded */
-#define PCIXM_STATUS_UNEXPSC 0x0008 /* Unexpected Split Completion */
-#define PCIXM_STATUS_CMPLEXDEV 0x0010 /* Device Complexity (set == bridge) */
-#define PCIXM_STATUS_MAXMRDBC 0x0060 /* Maximum Burst Read Count */
-#define PCIXM_STATUS_MAXSPLITS 0x0380 /* Maximum Split Transactions */
-#define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */
-#define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat.h b/c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat.h
deleted file mode 100644
index 62821eb9ff..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat.h
+++ /dev/null
@@ -1,456 +0,0 @@
-#ifndef RTEMS_COMPAT_BSD_NET_H
-#define RTEMS_COMPAT_BSD_NET_H
-
-/* BSD -> rtems wrappers; stuff that must be defined
- * prior to including most BSD headers
- */
-
-/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
- * License: see LICENSE file.
- */
-
-#include <rtems.h>
-#include <sys/errno.h>
-#include <sys/types.h>
-
-#include <stdlib.h>
-
-/* Check for RTEMS version; true if >= ma.mi.re */
-#define ISMINVERSION(ma,mi,re) \
- ( __RTEMS_MAJOR__ > (ma) \
- || (__RTEMS_MAJOR__ == (ma) && __RTEMS_MINOR__ > (mi)) \
- || (__RTEMS_MAJOR__ == (ma) && __RTEMS_MINOR__ == (mi) && __RTEMS_REVISION__ >= (re)) \
- )
-
-/* 'align' ARG is evaluated more than once */
-#define _DO_ALIGN(addr, align) (((uint32_t)(addr) + (align) - 1) & ~((align)-1))
-
-
-/* malloc/free are redefined :-( */
-static inline void *the_real_malloc(size_t n)
-{
- return malloc(n);
-}
-
-static inline void the_real_free(void *p)
-{
- return free(p);
-}
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-#include <rtems/rtems_bsdnet.h>
-#include <rtems/rtems_bsdnet_internal.h>
-#ifdef __i386__
-#include <libcpu/cpu.h>
-#elif defined(__PPC__)
-#include <libcpu/io.h>
-#else
-#error "dunno what IO ops to use on this architecture"
-#endif
-#include <rtems/bspIo.h>
-
-#define NET_EMB(x,y,z) x ## y ## z
-#define NET_EMBEMB(x,y,z) NET_EMB(x,y,z)
-
-#define NET_STR(arg) #arg
-#define NET_STRSTR(arg) NET_STR(arg)
-
-#define NET_SOFTC NET_EMBEMB(,NETDRIVER_PREFIX,_softc)
-
-#define METHODS NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_methods)
-extern struct _net_drv_tbl METHODS;
-
-#ifdef DEBUG_MODULAR
-#define METHODSPTR NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_methods_p)
-extern struct _net_drv_tbl *volatile METHODSPTR;
-#else
-#define METHODSPTR (&METHODS)
-#endif
-
-#if defined(__LITTLE_ENDIAN__) || (__i386__)
-static inline uint16_t htole16(uint16_t v) { return v; }
-static inline uint32_t htole32(uint32_t v) { return v; }
-static inline uint64_t htole64(uint64_t v) { return v; }
-static inline uint16_t le16toh(uint16_t v) { return v; }
-static inline uint32_t le32toh(uint32_t v) { return v; }
-static inline uint64_t le64toh(uint64_t v) { return v; }
-#elif defined(__BIG_ENDIAN__)
-#ifdef __PPC__
-#include <libcpu/byteorder.h>
-
-/* Different RTEMS versions use different types
- * for 32-bit (unsigned vs. unsigned long which
- * always cause gcc warnings and possible alias
- * violations, sigh).
- */
-
-#if ISMINVERSION(4,8,0)
-typedef uint32_t rtemscompat_32_t;
-#else
-typedef unsigned rtemscompat_32_t;
-#endif
-
-static inline uint16_t
-htole16(uint16_t v)
-{
-uint16_t rval;
- st_le16(&rval,v);
- return rval;
-}
-
-static inline uint16_t
-le16toh(uint16_t v)
-{
- return ld_le16((unsigned short*)&v);
-}
-
-static inline uint32_t
-htole32(uint32_t v)
-{
-rtemscompat_32_t rval;
- st_le32(&rval,v);
- return rval;
-}
-
-static inline uint32_t
-le32toh(uint32_t v)
-{
-rtemscompat_32_t vv = v;
- return ld_le32(&vv);
-}
-
-/* Compiler generated floating point instructions for this
- * and rtems_bsdnet_newproc()-generated tasks are non-FP
- * :-(
- */
-static inline uint64_t
-htole64(uint64_t v)
-{
-union {
- rtemscompat_32_t tmp[2];
- uint64_t rval;
-} u;
-
- st_le32( &u.tmp[0], (unsigned)(v&0xffffffff) );
- st_le32( &u.tmp[1], (unsigned)((v>>32)&0xffffffff) );
-
- return u.rval;
-}
-
-#else
-#error "need htoleXX() implementation for this CPU arch"
-#endif
-
-#else
-#error "Unknown CPU endianness"
-#endif
-
-
-
-#ifdef __PPC__
-#define _out_byte(a,v) out_8((volatile uint8_t*)(a),(v))
-#define _inp_byte(a) in_8((volatile uint8_t*)(a))
-#ifdef NET_CHIP_LE
-#define _out_word(a,v) out_le16((volatile uint16_t*)(a),(v))
-#define _out_long(a,v) out_le32((volatile uint32_t *)(a),(v))
-#define _inp_word(a) in_le16((volatile uint16_t*)(a))
-#define _inp_long(a) in_le32((volatile uint32_t *)(a))
-#elif defined(NET_CHIP_BE)
-#define _out_word(a,v) out_be16((volatile uint16_t*)(a),(v))
-#define _out_long(a,v) out_be32((volatile uint32_t *)(a),(v))
-#define _inp_word(a) in_be16((volatile uint16_t*)(a))
-#define _inp_long(a) in_be32((volatile uint32_t *)(a))
-#else
-#error rtemscompat_defs.h must define either NET_CHIP_LE or NET_CHIP_BE
-#endif
-static inline void wrle32(unsigned *a, unsigned v)
-{
- asm volatile("stwbrx %1,0,%2":"=m"(*a):"r"(v),"r"(a));
-}
-static inline unsigned rdle32(unsigned *a)
-{
- asm volatile("lwbrx %0,0,%0":"=r"(a):"0"(a),"m"(*a));
- return (unsigned)a;
-}
-static inline void orle32(unsigned *a,unsigned v) { wrle32(a, rdle32(a) | v); }
-static inline void anle32(unsigned *a,unsigned v) { wrle32(a, rdle32(a) & v); }
-
-static inline void wrle16(unsigned short *a, unsigned short v)
-{
- asm volatile("sthbrx %1,0,%2":"=m"(*a):"r"(v),"r"(a));
-}
-static inline unsigned short rdle16(unsigned short *a)
-{
- asm volatile("lhbrx %0,0,%0":"=r"(a):"0"(a),"m"(*a));
- return (unsigned short)(unsigned)a;
-}
-static inline void orle16(unsigned short *a,unsigned short v) { wrle16(a, rdle16(a) | v); }
-static inline void anle16(unsigned short *a,unsigned short v) { wrle16(a, rdle16(a) & v); }
-#endif
-
-#ifdef __i386__
-#ifdef NET_CHIP_BE
-#error dunno how to output BE data
-#endif
-
-static inline void wrle32(volatile unsigned *p, unsigned v) { *p = v; }
-static inline void orle32(volatile unsigned *p, unsigned v) { *p |= v; }
-static inline void anle32(volatile unsigned *p, unsigned v) { *p &= v; }
-static inline unsigned rdle32(volatile unsigned *p) { return *p; }
-
-static inline void wrle16(volatile unsigned short *p, unsigned short v) { *p = v; }
-static inline void orle16(volatile unsigned short *p, unsigned short v) { *p |= v; }
-static inline void anle16(volatile unsigned short *p, unsigned short v) { *p &= v; }
-static inline unsigned short rdle16(volatile unsigned short *p) { return *p; }
-
-#ifdef NET_CHIP_MEM_IO
-
-#ifdef __i386__
-static inline void _out_byte(unsigned a, unsigned char v) { *(volatile unsigned char*)a = v; }
-static inline unsigned char _inp_byte(unsigned a) { return *(volatile unsigned char*)a; }
-#ifdef NET_CHIP_LE
-static inline void _out_word(unsigned a, unsigned short v) { *(volatile unsigned short*)a = v; }
-static inline unsigned short _inp_word(unsigned a) { return *(volatile unsigned short*)a; }
-static inline void _out_long(unsigned a, unsigned v) { *(volatile unsigned *)a = v; }
-static inline unsigned _inp_long(unsigned a) { return *(volatile unsigned *)a; }
-#elif defined(NET_CHIP_BE)
-#error "BE memory IO not implemented for i386 yet"
-#else
-#error rtemscompat_defs.h must define either NET_CHIP_LE or NET_CHIP_BE
-#endif
-#else
-
-#error "Memory IO not implemented for this CPU architecture yet"
-
-#endif
-#elif defined(NET_CHIP_PORT_IO)
-#define _out_byte(addr,val) outport_byte((addr),(val))
-#define _out_word(addr,val) outport_word((addr),(val))
-#define _out_long(addr,val) outport_long((addr),(val))
-
-static inline u_int8_t _inp_byte(volatile unsigned char *a)
-{
-register u_int8_t rval;
- inport_byte((unsigned short)(unsigned)a,rval);
- return rval;
-}
-static inline u_int16_t _inp_word(volatile unsigned short *a)
-{
-register u_int16_t rval;
- inport_word((unsigned short)(unsigned)a,rval);
- return rval;
-}
-static inline u_int32_t _inp_long(volatile unsigned *a)
-{
-register u_int32_t rval;
- inport_long((unsigned short)(unsigned)a,rval);
- return rval;
-}
-#else
-#error either NET_CHIP_MEM_IO or NET_CHIP_PORT_IO must be defined
-#endif
-#endif
-
-#ifndef __FBSDID
-#define __FBSDID(arg)
-#endif
-
-#define _KERNEL
-
-#define device_printf(device,format,args...) printk(format,## args)
-
-static inline u_int8_t bus_space_do_read_1(u_long handle, unsigned reg)
-{
- return _inp_byte((volatile unsigned char*)((handle)+(reg)));
-}
-
-static inline u_int16_t bus_space_do_read_2(u_long handle, unsigned reg)
-{
- return _inp_word((volatile unsigned short*)((handle)+(reg)));
-}
-
-static inline u_int32_t bus_space_do_read_4(u_long handle, unsigned reg)
-{
- return _inp_long((volatile unsigned *)((handle)+(reg)));
-}
-
-#define bus_space_read_1(tag,handle,reg) bus_space_do_read_1((handle),(reg))
-#define bus_space_read_2(tag,handle,reg) bus_space_do_read_2((handle),(reg))
-#define bus_space_read_4(tag,handle,reg) bus_space_do_read_4((handle),(reg))
-
-static inline void bus_space_do_write_multi_1(u_long handle, unsigned reg, unsigned char *addr, int cnt)
-{
- int i; for (i=0; i<cnt; i++) _out_byte( (handle) + (reg), (addr)[i]);
-}
-
-static inline void bus_space_do_write_multi_2(u_long handle, unsigned reg, unsigned short *addr, int cnt)
-{
- int i; for (i=0; i<cnt; i++) _out_word( (handle) + (reg), (addr)[i]);
-}
-
-static inline void bus_space_do_write_multi_4(u_long handle, unsigned reg, unsigned long *addr, int cnt)
-{
- int i; for (i=0; i<cnt; i++) _out_long( (handle) + (reg), (addr)[i]);
-}
-
-
-#define bus_space_write_multi_1(tag, handle, reg, addr, cnt) \
- bus_space_do_write_multi_1(handle, reg, addr, cnt)
-#define bus_space_write_multi_2(tag, handle, reg, addr, cnt) \
- bus_space_do_write_multi_2(handle, reg, addr, cnt)
-#define bus_space_write_multi_4(tag, handle, reg, addr, cnt) \
- bus_space_do_write_multi_4(handle, reg, addr, cnt)
-
-static inline void bus_space_do_read_multi_1(u_long handle, unsigned reg, unsigned char *addr, int cnt)
-{
- int i; for (i=0; i<cnt; i++)
- (addr)[i] = _inp_byte((volatile unsigned char*)((handle)+(reg)));
-}
-
-static inline void bus_space_do_read_multi_2(u_long handle, unsigned reg, unsigned short *addr, int cnt)
-{
- int i; for (i=0; i<cnt; i++)
- (addr)[i] = _inp_word((volatile unsigned short*)((handle)+(reg)));
-}
-
-static inline void bus_space_do_read_multi_4(u_long handle, unsigned reg, unsigned long *addr, int cnt)
-{
- int i; for (i=0; i<cnt; i++)
- (addr)[i] = _inp_long((volatile unsigned *)((handle)+(reg)));
-}
-
-#define bus_space_read_multi_1(tag, handle, reg, addr, cnt) \
- bus_space_do_read_multi_1(handle, reg, addr, cnt)
-#define bus_space_read_multi_2(tag, handle, reg, addr, cnt) \
- bus_space_do_read_multi_2(handle, reg, addr, cnt)
-#define bus_space_read_multi_4(tag, handle, reg, addr, cnt) \
- bus_space_do_read_multi_4(handle, reg, addr, cnt)
-
-
-
-#define bus_space_write_1(tag, handle, reg, val) \
- do { _out_byte( (handle) + (reg), (val)); } while (0)
-
-#define bus_space_write_2(tag, handle, reg, val) \
- do { _out_word( (handle) + (reg), (val)); } while (0)
-
-#define bus_space_write_4(tag, handle, reg, val) \
- do { _out_long( (handle) + (reg), (val)); } while (0)
-
-#define BPF_MTAP(a,b) do { } while (0)
-
-extern unsigned net_driver_ticks_per_sec;
-
-#ifdef __PPC__
-/* PPC has a timebase - based delay */
-#define DELAY(n) do { \
- if ( (n) > 10000 ) \
- rtems_task_wake_after((((n)*net_driver_ticks_per_sec)/1000000) + 1); \
- else \
- rtems_bsp_delay(n); \
- } while (0)
-#else
-#warning "Have no good usec delay implementation"
-#define DELAY(n) do { \
- rtems_task_wake_after((((n)*net_driver_ticks_per_sec)/1000000) + 1); \
- } while (0)
-#endif
-
-
-#define IRQ_LOCKED(code) \
- do { unsigned long _xtre_irq_flags; \
- rtems_interrupt_disable(_xtre_irq_flags); \
- do { code } while(0); \
- rtems_interrupt_enable(_xtre_irq_flags); \
- } while (0)
-
-typedef void (driver_intr_t)(void *);
-
-#define if_xname if_name
-
-/* need to replace those with LOCAL2PCI() and make sure the bus handle is initialized
- * (on most BSPs we get away with PCI_DRAM_OFFSET [no bus handle needed at all]
- */
-#ifndef PCI_DRAM_OFFSET
-#define PCI_DRAM_OFFSET 0
-#endif
-
-#ifndef PCI_MEM_BASE
-#define PCI_MEM_BASE 0
-#endif
-
-#define kvtop(a) ((unsigned long)(a) + PCI_DRAM_OFFSET)
-#define vtophys(a) ((unsigned long)(a) + PCI_DRAM_OFFSET)
-
-#define PCI2LOCAL(a,bus) ((unsigned long)(a) + PCI_MEM_BASE)
-
-#ifdef PCI0_IO_BASE /* special mvme5500 hack :-( */
-#define PCI_IO_2LOCAL(a,bus) ((unsigned long)(a) + PCI0_IO_BASE)
-#elif defined(PCI_IO_BASE)
-#define PCI_IO_2LOCAL(a,bus) ((unsigned long)(a) + PCI_IO_BASE)
-#elif defined(_IO_BASE)
-#define PCI_IO_2LOCAL(a,bus) ((unsigned long)(a) + _IO_BASE)
-#else
-#warning "Unable to determine base address of PCI IO space; using ZERO"
-#define PCI_IO_2LOCAL(a,bus) ((unsigned long)(a))
-#endif
-
-#define if_printf(if,fmt,args...) printf("%s:"fmt,(if)->if_name,args)
-
-#ifndef BUS_PROBE_DEFAULT
-#define BUS_PROBE_DEFAULT 0
-#endif
-
-static inline void *
-contigmalloc(
- unsigned long size,
- int type,
- int flags,
- unsigned long lo,
- unsigned long hi,
- unsigned long align,
- unsigned long bound)
-{
-void *ptr = rtems_bsdnet_malloc(size + sizeof(ptr) + align-1, type, flags);
-char *rval = 0;
- if ( ptr ) {
- unsigned tmp = (unsigned)ptr + align - 1;
- tmp -= tmp % align;
- rval = (char*)tmp;
- /* save backlink */
- *(void**)(rval+size) = ptr;
- }
- return rval;
-}
-
-static inline void
-contigfree(void *ptr, size_t size, int type)
-{
- rtems_bsdnet_free( *(void**)((unsigned)ptr + size), type);
-}
-
-/* callout stuff */
-#define callout_init(args...) do {} while (0);
-#define callout_reset(args...) do {} while (0);
-#define callout_stop(args...) do {} while (0);
-
-#define IFQ_DRV_IS_EMPTY(q) (0 == (q)->ifq_head)
-#define IFQ_DRV_DEQUEUE(q,m) IF_DEQUEUE((q),(m))
-#define IFQ_DRV_PREPEND(q,m) IF_PREPEND((q),(m))
-
-#define DO_ETHER_INPUT_SKIPPING_ETHER_HEADER(ifp,m) \
- { struct ether_header *eh; \
- eh = mtod(m, struct ether_header*); \
- m->m_data += sizeof(struct ether_header); \
- m->m_len -= sizeof(struct ether_header); \
- m->m_pkthdr.len -= sizeof(struct ether_header); \
- m->m_pkthdr.rcvif = ifp; \
- ether_input(ifp, eh, m); \
- } while (0)
-
-
-#ifndef __KERNEL_RCSID
-#define __KERNEL_RCSID(arg...)
-#endif
-
-#endif
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat1.h b/c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat1.h
deleted file mode 100644
index cee16522cc..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat1.h
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifndef RTEMS_COMPAT1_BSD_NET_H
-#define RTEMS_COMPAT1_BSD_NET_H
-
-/* BSD -> RTEMS conversion wrappers; stuff that must be defined
- * after most BSD headers are included.
- */
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
- * License: see LICENSE file.
- */
-
-typedef struct device {
- struct NET_SOFTC d_softc; /* MUST BE FIRST FIELD */
- char *d_name;
- char *d_desc;
- int d_unit;
- int flags;
- /* pointer to ifconfig only valid during excution of
- * the n_attach/n_detach methods (see below)
- */
- struct rtems_bsdnet_ifconfig *d_ifconfig;
-} netdev_t;
-
-#define THEDEVS NET_EMBEMB(the_,NETDRIVER_PREFIX,_devs)
-#define NETDEV_DECL netdev_t THEDEVS[NETDRIVER_SLOTS]
-
-extern NETDEV_DECL;
-
-typedef struct _net_drv_tbl {
- int (*n_probe)(device_t);
- int (*n_attach)(device_t);
- int (*n_detach)(device_t);
- void (*n_intr)(void *);
-} net_drv_tbl_t;
-
-static inline netdev_t *
-net_dev_get(struct rtems_bsdnet_ifconfig *config)
-{
- int unitNo;
- char *unitName;
-
- unitNo = rtems_bsdnet_parse_driver_name(config, &unitName);
- if ( unitNo < 0 )
- return 0;
-
- if ( unitNo <=0 || unitNo > NETDRIVER_SLOTS ) {
- device_printf(dev, "Bad "NETDRIVER" unit number.\n");
- return 0;
- }
-
- if ( THEDEVS[unitNo-1].d_unit && THEDEVS[unitNo-1].d_unit != unitNo ) {
- device_printf(dev, "Unit # mismatch !!??\n");
- return 0;
- }
-
- THEDEVS[unitNo-1].d_unit = unitNo;
- THEDEVS[unitNo-1].d_name = unitName;
- THEDEVS[unitNo-1].d_ifconfig = config;
-
- return &THEDEVS[unitNo - 1];
-}
-
-/* kludge; that's why softc needs to be first */
-static inline netdev_t *
-softc_get_device(struct NET_SOFTC *sc)
-{
- return (netdev_t *)sc;
-}
-
-static inline struct NET_SOFTC *
-device_get_softc(netdev_t *dev)
-{ return &dev->d_softc; }
-
-static inline int
-device_get_unit(netdev_t *dev)
-{ return dev->d_unit; }
-
-static inline char *
-device_get_name(netdev_t *dev)
-{ return dev->d_name; }
-
-static inline void
-if_initname(struct ifnet *ifp, char *name, int unit)
-{
- ifp->if_name = name;
- ifp->if_unit = unit;
-}
-
-static inline void
-device_set_desc(netdev_t *dev, char *str)
-{
- dev->d_desc = str;
-}
-
-static inline void
-device_set_desc_copy(netdev_t *dev, char *str)
-{
- dev->d_desc = strdup(str);
-}
-
-
-static inline int
-device_is_attached(netdev_t *dev)
-{
- return dev->d_softc.arpcom.ac_if.if_addrlist && dev->d_softc.arpcom.ac_if.if_init;
-}
-
-#ifdef NETDRIVER_PCI
-#include NETDRIVER_PCI
-#include "pcireg.h"
-
-static inline unsigned
-pci_read_config(device_t dev, unsigned addr, unsigned width)
-{
-rtemscompat_32_t d;
-unsigned short s;
-unsigned char b;
-struct NET_SOFTC *sc = device_get_softc(dev);
- switch (width) {
- case 1: pci_read_config_byte(sc->b, sc->d, sc->f, addr, &b);
- return b;
- case 2: pci_read_config_word(sc->b, sc->d, sc->f, addr, &s);
- return s;
- case 4: pci_read_config_dword(sc->b, sc->d, sc->f, addr, &d);
- return d;
- default:
- break;
- }
- return 0xdeadbeef;
-}
-
-static inline void
-pci_write_config(device_t dev, unsigned addr, unsigned width, unsigned val)
-{
-struct NET_SOFTC *sc = device_get_softc(dev);
- switch (width) {
- case 1: pci_write_config_byte(sc->b, sc->d, sc->f, addr, val);
- return ;
- case 2: pci_write_config_word(sc->b, sc->d, sc->f, addr, val);
- return ;
- case 4: pci_write_config_dword(sc->b, sc->d, sc->f, addr, val);
- return ;
- default:
- break;
- }
-}
-
-
-static inline unsigned short
-pci_get_vendor(device_t dev)
-{
- return pci_read_config(dev, PCIR_VENDOR, 2);
-}
-
-static inline unsigned short
-pci_get_device(device_t dev)
-{
- return pci_read_config(dev, PCIR_DEVICE, 2);
-}
-
-static inline unsigned short
-pci_get_subvendor(device_t dev)
-{
- return pci_read_config(dev, PCIR_SUBVEND_0, 2);
-}
-
-static inline unsigned short
-pci_get_subdevice(device_t dev)
-{
- return pci_read_config(dev, PCIR_SUBDEV_0, 2);
-}
-
-
-static inline void
-pci_enable_busmaster(device_t dev)
-{
- pci_write_config(
- dev,
- PCIR_COMMAND,
- 2,
- pci_read_config(dev, PCIR_COMMAND, 2)
- | PCIM_CMD_BUSMASTEREN);
-}
-
-#define mtx_init(a,b,c,d) do {} while(0)
-#define mtx_initialized(ma) (1)
-#define mtx_destroy(ma) do {} while(0)
-#define mtx_lock(a) do {} while(0)
-#define mtx_unlock(a) do {} while(0)
-#define mtx_assert(a,b) do {} while(0)
-
-#define callout_handle_init(x) do {} while (0)
-#define untimeout(a...) do {} while (0)
-
-#if !ISMINVERSION(4,6,99)
-#define pci_bus_count BusCountPCI
-#endif
-
-#endif
-
-/* Ugly hack to allow unloading/reloading the driver core.
- * Needed because rtems' bsdnet release doesn't implement
- * if_detach(). Therefore, we bring the interface down but
- * keep the device record alive...
- */
-static inline void
-__ether_ifdetach(struct ifnet *ifp)
-{
- ifp->if_flags = 0;
- ifp->if_ioctl = 0;
- ifp->if_start = 0;
- ifp->if_watchdog = 0;
- ifp->if_init = 0;
-}
-
-#endif
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat_defs.h.template b/c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat_defs.h.template
deleted file mode 100644
index 5dc8d1efff..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/porting/rtemscompat_defs.h.template
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef RTEMS_COMPAT_DEFS_H
-#define RTEMS_COMPAT_DEFS_H
-
-/* Symbol definitions for a particular driver */
-
-/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
- * License: see LICENSE file.
- */
-
-/* Number of device instances the driver should support
- * - may be limited to 1 depending on IRQ API
- * (braindamaged PC586 and powerpc)
- */
-#define NETDRIVER_SLOTS 1
-/* String name to print with error messages */
-#define NETDRIVER "PCN"
-/* Name snippet used to make global symbols unique to this driver */
-#define NETDRIVER_PREFIX pcn
-
-/* Define according to endianness of the *ethernet*chip*
- * (not the CPU - most probably are LE)
- * This must be either NET_CHIP_LE or NET_CHIP_BE
- */
-
-#define NET_CHIP_LE
-#undef NET_CHIP_BE
-
-/* Define either NET_CHIP_MEM_IO or NET_CHIP_PORT_IO,
- * depending whether the CPU sees it in memory address space
- * or (e.g. x86) uses special I/O instructions.
- */
-#define NET_CHIP_MEM_IO
-#undef NET_CHIP_PORT_IO
-
-/* The name of the hijacked 'bus handle' field in the softc
- * structure. We use this field to store the chip's base address.
- */
-#define NET_SOFTC_BHANDLE_FIELD pcn_bhandle
-
-/* define the names of the 'if_XXXreg.h' and 'if_XXXvar.h' headers
- * (only if present, i.e., if the BSDNET driver has no respective
- * header, leave this undefined).
- *
- */
-#undef IF_REG_HEADER <if_XXXreg.h>
-#undef IF_VAR_HEADER <if_XXXvar.h>
-
-/* define if a pci device */
-#define NETDRIVER_PCI <bsp/pci.h>
-
-/* Macros to disable and enable interrupts, respectively.
- * The 'disable' macro is expanded in the ISR, the 'enable'
- * macro is expanded in the driver task.
- * The global network semaphore usually provides mutex
- * protection of the device registers.
- * Special care must be taken when coding the 'disable' macro,
- * however to MAKE SURE THERE ARE NO OTHER SIDE EFFECTS such
- * as:
- * - macro must not clear any status flags
- * - macro must save/restore any context information
- * (e.g., a address register pointer or a bank switch register)
- *
- * ARGUMENT: the macro arg is a pointer to the driver's 'softc' structure
- */
-
-/* Here EXAMPLES for the pcnet chip which addresses registers indirectly
- * through a 'address-pointer' (RAP) and 'data-port' (RDP) register pair:
-#define NET_DISABLE_IRQS(sc) do { \
- unsigned rap = CSR_READ_4((sc),PCN_IO32_RAP); \
- unsigned val; \
- CSR_WRITE_4((sc),PCN_IO32_RAP,PCN_CSR_CSR); \
- val = CSR_READ_4((sc),PCN_IO32_RDP); \
- CSR_WRITE_4((sc), PCN_IO32_RDP, val & ~(CSR0_INT_STATUS_MASK | PCN_CSR_INTEN)); \
- CSR_WRITE_4((sc), PCN_IO32_RAP, rap); \
- } while (0)
-
-#define NET_ENABLE_IRQS(sc) do { \
- unsigned flags,val; \
- rtems_interrupt_disable(flags); \
- CSR_WRITE_4((sc),PCN_IO32_RAP,PCN_CSR_CSR); \
- val = CSR_READ_4((sc),PCN_IO32_RDP); \
- CSR_WRITE_4((sc), PCN_IO32_RDP, (val & ~CSR0_INT_STATUS_MASK) | PCN_CSR_INTEN); \
- rtems_interrupt_enable(flags); \
- } while (0)
-*/
-
-/* Driver may provide a macro/function to copy the hardware address
- * from the device into 'softc.arpcom'.
- * If this is undefined, the driver must to the copy itself.
- * Preferrably, it should check soft.arpcom.ac_enaddr for all
- * zeros and leave it alone if it is nonzero, i.e., write it
- * to the hardware.
-#define NET_READ_MAC_ADDR(sc)
- */
-
-#define KASSERT(a...) do {} while (0)
-#endif
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/support/bsp_attach.c b/c/src/lib/libbsp/powerpc/beatnik/network/support/bsp_attach.c
deleted file mode 100644
index 30329d90b3..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/support/bsp_attach.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/* BSP specific wrapper for rtems_bsdnet_attach(). This wrapper
- * dispatches to the correct driver attach routine depending on
- * the board type, boot parameters, link status etc.
- *
- * Also, it performs board-specific setup of driver parameters
- * (such as ethernet address, base addresses and the like)
- */
-
-/*
- * Authorship
- * ----------
- * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
- * created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
- * Stanford Linear Accelerator Center, Stanford University.
- *
- * Acknowledgement of sponsorship
- * ------------------------------
- * The 'beatnik' BSP was produced by
- * the Stanford Linear Accelerator Center, Stanford University,
- * under Contract DE-AC03-76SFO0515 with the Department of Energy.
- *
- * Government disclaimer of liability
- * ----------------------------------
- * Neither the United States nor the United States Department of Energy,
- * nor any of their employees, makes any warranty, express or implied, or
- * assumes any legal liability or responsibility for the accuracy,
- * completeness, or usefulness of any data, apparatus, product, or process
- * disclosed, or represents that its use would not infringe privately owned
- * rights.
- *
- * Stanford disclaimer of liability
- * --------------------------------
- * Stanford University makes no representations or warranties, express or
- * implied, nor assumes any liability for the use of this software.
- *
- * Stanford disclaimer of copyright
- * --------------------------------
- * Stanford University, owner of the copyright, hereby disclaims its
- * copyright and all other rights in this software. Hence, anyone may
- * freely use it for any purpose without restriction.
- *
- * Maintenance of notices
- * ----------------------
- * In the interest of clarity regarding the origin and status of this
- * SLAC software, this and all the preceding Stanford University notices
- * are to remain affixed to any copy or derivative of this software made
- * or distributed by the recipient and are to be affixed to any copy of
- * software made or distributed by the recipient that contains a copy or
- * derivative of this software.
- *
- * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
- */
-
-#include <unistd.h>
-
-#include <rtems.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <bsp/pci.h>
-
-#include <bsp/early_enet_link_status.h>
-
-#include <bsp/if_mve_pub.h>
-#include <bsp/if_gfe_pub.h>
-#include <bsp/if_em_pub.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#define IS_6100() (MVME6100 == BSP_getBoardType())
-#define IS_5500() (MVME5500 == BSP_getBoardType())
-
-static int bsp_gfe_attach(struct rtems_bsdnet_ifconfig *, int);
-static int mvme5500_em_attach (struct rtems_bsdnet_ifconfig *, int);
-static int mvme5500_em_find_onboard_unit(void);
-
-char BSP_auto_network_driver_name[20] = {0,};
-
-static BSP_NetIFDescRec mvme6100_netifs[] = {
- {
- name: "mve1",
- description: "MV64360 built-in 10/100/1000 Ethernet 1",
- attach_fn: rtems_mve_attach
- },
- {
- name: "mve2",
- description: "MV64360 built-in 10/100/1000 Ethernet 2",
- attach_fn: rtems_mve_attach
- },
- {
- name: 0,
- }
-};
-
-static BSP_NetIFDescRec mvme5500_netifs[] = {
- {
- name: "em1",
- description: "Intel 82544 on-board 10/100/1000 Ethernet (port 1)",
- attach_fn: mvme5500_em_attach,
- },
- {
- name: "gfe1",
- description: "GT64260 built-in 10/100 Ethernet (port 2)",
- attach_fn: bsp_gfe_attach,
- },
- {
- name: 0,
- }
-};
-
-
-/* wrap the 'gfe' and 'em' attach functions.
- * RATIONALE: 'rtems_gfe_attach()' and 'rtems_em_attach()' are
- * *chip* specific functions. However, they require
- * some *board* specific parameter setup prior to
- * being attached which is what these wrappers do...
- */
-
-static unsigned em_info[];
-
-static int scan4irqLine(int bus, int dev, int fn, void *uarg)
-{
-unsigned char byte;
-unsigned short word;
-int i;
-
- /* count the number of 82544 we find */
- pci_read_config_word(bus, dev, fn, PCI_VENDOR_ID, &word);
- if ( 0x8086 != word )
- return 0;
-
- pci_read_config_word(bus, dev, fn, PCI_DEVICE_ID, &word);
- for ( i = 0; em_info[i]; i++ ) {
- if ( em_info[i] == word )
- break;
- }
-
- if ( !em_info[i] )
- return 0;
-
- /* found a candidate; bump unit number */
- (*(int *)uarg)++;
-
- pci_read_config_byte(bus, dev, fn, PCI_INTERRUPT_LINE, &byte);
-
- /* On the mvme5500 the 82544 is hooked to GPP IRQ 20 */
-
- return ( BSP_IRQ_GPP_0 + 20 == byte ) ? 1 : 0;
-}
-
-/* Setup only once */
-static void
-onboard_em_setup_once(void)
-{
-static char done = 0;
-
- /* If scanning didn't do anything, passing 0 will setup all interfaces */
- if ( !done
- && rtems_em_pci_setup( mvme5500_em_find_onboard_unit() > 0 ) ) {
- done=1;
- }
-}
-
-static void
-onboard_gfe_setup_once(void)
-{
-static char done = 0;
-
- /* must setup HW address -- note that the label on the
- * board indicates that the gfe is the second interface
- * but motLoad etc. interprets the order actually
- * the other way round...
- */
- if ( !done
- && rtems_gfe_setup( 1, BSP_enetAddr0, BSP_MV64x60_BASE ) > 0 ) {
- done=1;
- }
-}
-
-
-/* Find the unit number of the on-board 82544 (even if there is another one
- * plugged into PMC...
- *
- * RETURNS: unit # (>0) or zero if nothing at all was found. (New board rev.
- * with the 82544 hooked to a different IRQ line, new PCI device ID,
- * ...)
- */
-static int
-mvme5500_em_find_onboard_unit(void)
-{
-int unit = 0;
-void *h;
- /* Determine the on-board 'em' adapter; we know it's interrupt line :-) */
- for ( h=0; (h=BSP_pciScan(h, scan4irqLine, &unit)); )
- /* nothing else to do */;
- return h ? unit : 0;
-}
-
-static int
-mvme5500_em_attach(struct rtems_bsdnet_ifconfig *ifcfg, int attaching)
-{
- if ( attaching ) {
- onboard_em_setup_once();
-
- /* Make sure there is no conflict in MAC address -- see below
- * why we 'swap' the addresses. (We actually don't but swap the
- * order of the interfaces so they match the label.)
- */
- if ( !ifcfg->hardware_address )
- ifcfg->hardware_address = BSP_enetAddr1;
- }
-
- return rtems_em_attach(ifcfg, attaching);
-}
-
-static int
-bsp_gfe_attach(struct rtems_bsdnet_ifconfig *ifcfg, int attaching)
-{
- if ( attaching ) {
- onboard_gfe_setup_once();
- }
- return rtems_gfe_attach(ifcfg, attaching);
-}
-
-BSP_NetIFDesc
-BSP_availableNetIFs(void)
-{
- if ( IS_6100() )
- return mvme6100_netifs;
- if ( IS_5500() )
- return mvme5500_netifs;
-
- fprintf(stderr,"BSP_availableNetIFs() -- productIdent not set? unable to identify board type\n");
-
- return 0;
-}
-
-typedef int (*read_op_t)(int,unsigned);
-typedef int (*write_op_t)(int,unsigned,unsigned);
-
-struct poll_job {
- read_op_t rdop;
- write_op_t wrop;
- int unit;
-};
-
-static int
-check_phys(struct poll_job *job)
-{
-struct poll_job *j;
-int rval = -2;
- for ( j=job; j->rdop; j++ ) {
- unsigned w;
- w = j->rdop(j->unit, 1/*status*/);
- if ( 0x04 & w ) /* active link */
- return j-job;
- if ( !(0x20 & w) ) /* aneg not done */
- rval = -1;
- }
- return rval;
-}
-
-/* check a number of phys
- * RETURNS: -1 if at least one is still busy
- * -2 if all are terminated but no link is found
- * >=0 index of first IF with a live link
- */
-static int
-poll_phys(struct poll_job *job)
-{
-int rval;
-struct poll_job *j = job;
-int retry = 4;
-
- /* see if we already have a link */
- if ( (rval=check_phys(job)) < 0 ) {
- /* no - start negotiation */
- for ( j = job; j->rdop; j++ ) {
- j->wrop(j->unit, 0/* ctrl */, 0x1200 /* start aneg */);
- }
-
- do {
- sleep(1);
- } while ( -1 == (rval = check_phys(job)) && retry-- );
- }
-
- return rval;
-}
-
-
-/* note that detaching is not supported by the current version of the BSD stack */
-int
-BSP_auto_enet_attach(struct rtems_bsdnet_ifconfig *ifcfg, int attaching)
-{
-int i = -1;
-BSP_NetIFDesc d = BSP_availableNetIFs();
-struct poll_job job[3];
-
- if ( !d )
- return -1;
-
- /* If they pass a name, find the attach fn */
- if ( ifcfg->name && RTEMS_BSP_NETWORK_DRIVER_NAME != ifcfg->name && attaching ) {
- for (i = 0; d[i].name; i++ ) {
- if ( !strcmp(d[i].name, ifcfg->name) ) {
- ifcfg->attach = d[i].attach_fn;
- break;
- }
- }
- if ( !d[i].name ) {
- fprintf(stderr,"WARNING: have no '%s' interface - using default\n", ifcfg->name);
- ifcfg->name = 0;
- }
- }
-
- if ( !ifcfg->name || ifcfg->name == RTEMS_BSP_NETWORK_DRIVER_NAME ) {
- /* automatically choose and attach an interface */
- if ( RTEMS_BSP_NETWORK_DRIVER_NAME[0] ) {
- fprintf(stderr,
- "Configuration error: 'auto' network if already chosen (%s)\n",
- RTEMS_BSP_NETWORK_DRIVER_NAME);
- return -1;
- }
- if ( IS_6100() ) {
-#define ops rtems_mve_early_link_check_ops
- assert(ops.num_slots >= 2);
- ops.init(0);
- ops.init(1);
- job[0].rdop = ops.read_phy;
- job[0].wrop = ops.write_phy;
- job[0].unit = 0;
- job[1].rdop = ops.read_phy;
- job[1].wrop = ops.write_phy;
- job[1].unit = 1;
-#undef ops
- } else if ( IS_5500() ) {
-#define opsgfe rtems_gfe_early_link_check_ops
-#define opsem rtems_em_early_link_check_ops
- assert(opsgfe.num_slots >= 1);
- onboard_gfe_setup_once();
- opsgfe.init(0);
- assert(opsem.num_slots >= 1);
- onboard_em_setup_once();
- opsem.init(0);
- job[0].rdop = opsem.read_phy;
- job[0].wrop = opsem.write_phy;
- job[0].unit = 0;
- job[1].rdop = opsgfe.read_phy;
- job[1].wrop = opsgfe.write_phy;
- job[1].unit = 0;
-#undef opsgfe
-#undef opsem
- }
- job[2].rdop = 0; /* tag end */
- i = poll_phys(job);
- if ( i >= 0 ) {
- printf("L");
- } else {
- i = 0;
- printf("No l");
- }
- printf("ink detected; attaching %s\n",d[i].name);
-
- /* set attach function and IF name */
- ifcfg->attach = d[i].attach_fn;
- ifcfg->name = RTEMS_BSP_NETWORK_DRIVER_NAME;
- strcpy(RTEMS_BSP_NETWORK_DRIVER_NAME, d[i].name);
- }
- return ifcfg->attach(ifcfg, attaching);
-}
-
-/* from 'em' */
-
-/* PCI Device IDs */
-#define E1000_DEV_ID_82542 0x1000
-#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_82541ER_LOM 0x1014
-#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_82541EI 0x1013
-#define E1000_DEV_ID_82541EI_MOBILE 0x1018
-#define E1000_DEV_ID_82541ER 0x1078
-#define E1000_DEV_ID_82547GI 0x1075
-#define E1000_DEV_ID_82541GI 0x1076
-#define E1000_DEV_ID_82541GI_MOBILE 0x1077
-#define E1000_DEV_ID_82541GI_LF 0x107C
-#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_82547EI 0x1019
-#define E1000_DEV_ID_82547EI_MOBILE 0x101A
-#define E1000_DEV_ID_82573E 0x108B
-#define E1000_DEV_ID_82573E_IAMT 0x108C
-
-#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
-
-static unsigned em_info[] =
-{
- /* Intel(R) PRO/1000 Network Connection */
- E1000_DEV_ID_82540EM,
- E1000_DEV_ID_82540EM_LOM,
- E1000_DEV_ID_82540EP,
- E1000_DEV_ID_82540EP_LOM,
- E1000_DEV_ID_82540EP_LP,
-
- E1000_DEV_ID_82541EI,
- E1000_DEV_ID_82541ER,
- E1000_DEV_ID_82541ER_LOM,
- E1000_DEV_ID_82541EI_MOBILE,
- E1000_DEV_ID_82541GI,
- E1000_DEV_ID_82541GI_LF,
- E1000_DEV_ID_82541GI_MOBILE,
-
- E1000_DEV_ID_82542,
-
- E1000_DEV_ID_82543GC_FIBER,
- E1000_DEV_ID_82543GC_COPPER,
-
- E1000_DEV_ID_82544EI_COPPER,
- E1000_DEV_ID_82544EI_FIBER,
- E1000_DEV_ID_82544GC_COPPER,
- E1000_DEV_ID_82544GC_LOM,
-
- E1000_DEV_ID_82545EM_COPPER,
- E1000_DEV_ID_82545EM_FIBER,
- E1000_DEV_ID_82545GM_COPPER,
- E1000_DEV_ID_82545GM_FIBER,
- E1000_DEV_ID_82545GM_SERDES,
-
- E1000_DEV_ID_82546EB_COPPER,
- E1000_DEV_ID_82546EB_FIBER,
- E1000_DEV_ID_82546EB_QUAD_COPPER,
- E1000_DEV_ID_82546GB_COPPER,
- E1000_DEV_ID_82546GB_FIBER,
- E1000_DEV_ID_82546GB_SERDES,
- E1000_DEV_ID_82546GB_PCIE,
- E1000_DEV_ID_82546GB_QUAD_COPPER,
-
- E1000_DEV_ID_82547EI,
- E1000_DEV_ID_82547EI_MOBILE,
- E1000_DEV_ID_82547GI,
-
- E1000_DEV_ID_82573E,
- E1000_DEV_ID_82573E_IAMT,
-
- /* required last entry */
- 0,
-};
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/support/early_link_status.c b/c/src/lib/libbsp/powerpc/beatnik/network/support/early_link_status.c
deleted file mode 100644
index 271f970212..0000000000
--- a/c/src/lib/libbsp/powerpc/beatnik/network/support/early_link_status.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <rtems.h>
-#include <bsp/early_enet_link_status.h>
-#include <rtems/bspIo.h>
-
-/* T. Straumann, 2005; see ../../LICENSE */
-
-static const char *ename = ": rtems_em_early_check_link_status() - ";
-
-int
-BSP_early_check_link_status(int unit, rtems_bsdnet_early_link_check_ops *ops)
-{
-int status;
-
- unit--;
- if ( unit < 0 || unit >= ops->num_slots ) {
- printk("%s%sinvalid unit # %i (not in %i..%i)\n",
- ops->name, ename, unit+1, 1, ops->num_slots);
- return -1;
- }
-
- if ( !ops->initialized ) {
- if ( ops->init(unit) ) {
- printk("%s%sFAILURE to init hardware\n",ops->name, ename);
- return -1;
- }
- /* Start autoneg */
- if ( ops->write_phy(unit, 0, 0x1200) ) {
- printk("%s%sFAILURE to start autonegotiation\n",ops->name, ename);
- return -1;
- }
- /* Dont wait here; the caller can do this on various interfaces
- * and wait herself.
- */
- ops->initialized = 1;
- }
- if ( (status = ops->read_phy(unit, 1)) < 0 ) {
- printk("%s%sFAILURE to read phy status\n", ops->name, ename);
- }
- return status;
-}