diff options
| author | cvs2svn <cvs2svn@FreeBSD.org> | 2001-12-02 07:37:18 +0000 |
|---|---|---|
| committer | cvs2svn <cvs2svn@FreeBSD.org> | 2001-12-02 07:37:18 +0000 |
| commit | 2a4a2b21407ac7f41a63c104b4dfb2d6725d28c9 (patch) | |
| tree | b3417cf80a5272f174873d972fec985e3baefbb6 /sys/dev/em | |
| parent | 7d5307bebea0b558542fd06dc77ecc009df9b144 (diff) | |
Notes
Diffstat (limited to 'sys/dev/em')
| -rw-r--r-- | sys/dev/em/if_em.h | 410 | ||||
| -rw-r--r-- | sys/dev/em/if_em_fxhw.h | 1338 | ||||
| -rw-r--r-- | sys/dev/em/if_em_osdep.h | 95 | ||||
| -rw-r--r-- | sys/dev/em/if_em_phy.c | 1223 | ||||
| -rw-r--r-- | sys/dev/em/if_em_phy.h | 418 |
5 files changed, 3484 insertions, 0 deletions
diff --git a/sys/dev/em/if_em.h b/sys/dev/em/if_em.h new file mode 100644 index 000000000000..b1919cb25848 --- /dev/null +++ b/sys/dev/em/if_em.h @@ -0,0 +1,410 @@ +/************************************************************************** +************************************************************************** + +Copyright (c) 2001 Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms of the Software, with or +without modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code of the Software may retain the above + copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form of the Software may 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 shall 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 INTEL OR ITS CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +$FreeBSD$ +*************************************************************************** +***************************************************************************/ + +#ifndef _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> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_media.h> +#include <net/bpf.h> +#include <net/ethernet.h> +#include <net/if_arp.h> +#include <sys/sockio.h> + +#include <netinet/in_systm.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> + +#include <sys/bus.h> +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> +#include <vm/vm.h> +#include <vm/pmap.h> +#include <machine/clock.h> +#include <pci/pcivar.h> +#include <pci/pcireg.h> +#include <stddef.h> + +#include "opt_bdg.h" + +#include <dev/em/if_em_fxhw.h> +#include <dev/em/if_em_phy.h> + +/* Tunables */ +#define MAX_TXD 256 +#define MAX_RXD 256 +#define TX_CLEANUP_THRESHOLD MAX_TXD / 8 +#define TIDV 128 +#define RIDV 28 +#define DO_AUTO_NEG 1 +#define WAIT_FOR_AUTO_NEG_DEFAULT 1 +#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \ + ADVERTISE_100_HALF | ADVERTISE_100_FULL | \ + ADVERTISE_1000_FULL) +#define EM_ENABLE_RXCSUM_OFFLOAD 1 +#define EM_REPORT_TX_EARLY 2 +#define EM_CHECKSUM_FEATURES (CSUM_TCP | CSUM_UDP) +#define EM_MAX_INTR 3 +#define EM_TX_TIMEOUT 5 /* set to 5 seconds */ +#define EM_JUMBO_ENABLE_DEFAULT 0 + + +#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 IOCTL_CMD_TYPE u_long +#define ETH_LENGTH_OF_ADDRESS ETHER_ADDR_LEN +#define PCI_COMMAND_REGISTER PCIR_COMMAND +#define MAX_NUM_MULTICAST_ADDRESSES 128 +#define PCI_ANY_ID (~0U) +#define ETHER_ALIGN 2 +#define CMD_MEM_WRT_INVALIDATE 0x0010 + +/* Defines for printing debug information */ +#define DEBUG_INIT 0 +#define DEBUG_IOCTL 0 +#define DEBUG_HW 0 +#define DEBUG_TXRX 0 +#define DEBUG_RXCSUM 0 +#define DEBUG_TXCSUM 0 + +#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n") +#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A) +#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B) +#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n") +#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A) +#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B) +#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n") +#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A) +#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B) +#define TXRX_DEBUGOUT(S) if (DEBUG_TXRX) printf(S "\n") +#define TXRX_DEBUGOUT1(S, A) if (DEBUG_TXRX) printf(S "\n", A) +#define TXRX_DEBUGOUT2(S, A, B) if (DEBUG_TXRX) printf(S "\n", A, B) +#define RXCSUM_DEBUGOUT(S) if (DEBUG_RXCSUM) printf(S "\n") +#define RXCSUM_DEBUGOUT1(S, A) if (DEBUG_RXCSUM) printf(S "\n", A) +#define RXCSUM_DEBUGOUT2(S, A, B) if (DEBUG_RXCSUM) printf(S "\n", A, B) +#define TXCSUM_DEBUGOUT(S) if (DEBUG_TXCSUM) printf(S "\n") +#define TXCSUM_DEBUGOUT1(S, A) if (DEBUG_TXCSUM) printf(S "\n", A) +#define TXCSUM_DEBUGOUT2(S, A, B) if (DEBUG_TXCSUM) printf(S "\n", A, B) + +/* Device ID defines */ +#define PCI_DEVICE_ID_82542 0x1000 +#define PCI_DEVICE_ID_82543GC_FIBER 0x1001 +#define PCI_DEVICE_ID_82543GC_COPPER 0x1004 +#define PCI_DEVICE_ID_82544EI_FIBER 0x1009 +#define PCI_DEVICE_ID_82544EI_COPPER 0x1008 +#define PCI_DEVICE_ID_82544GC_STRG 0x100C +#define PCI_DEVICE_ID_82544GC_COPPER 0x100D + +/* Supported RX Buffer Sizes */ +#define EM_RXBUFFER_2048 2048 +#define EM_RXBUFFER_4096 4096 +#define EM_RXBUFFER_8192 8192 +#define EM_RXBUFFER_16384 16384 + + +/* Jumbo Frame */ +#define EM_JSLOTS 384 +#define EM_JUMBO_FRAMELEN 9018 +#define EM_JUMBO_MTU (EM_JUMBO_FRAMELEN - ETHER_HDR_LEN - ETHER_CRC_LEN) +#define EM_JRAWLEN (EM_JUMBO_FRAMELEN + ETHER_ALIGN + sizeof(u_int64_t)) +#define EM_JLEN (EM_JRAWLEN + (sizeof(u_int64_t) - \ + (EM_JRAWLEN % sizeof(u_int64_t)))) +#define EM_JPAGESZ PAGE_SIZE +#define EM_RESID (EM_JPAGESZ - (EM_JLEN * EM_JSLOTS) % EM_JPAGESZ) +#define EM_JMEM ((EM_JLEN * EM_JSLOTS) + EM_RESID) + +struct em_jslot { + caddr_t em_buf; + int em_inuse; +}; + +struct em_jpool_entry { + int slot; + SLIST_ENTRY(em_jpool_entry) em_jpool_entries; +}; + + + +/* ****************************************************************************** + * 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_tx_buffer { + STAILQ_ENTRY(em_tx_buffer) em_tx_entry; + struct mbuf *Packet; + u_int32_t NumTxDescriptorsUsed; +}; + + +/* ****************************************************************************** + * This structure stores information about the 2k aligned receive buffer + * into which the E1000 DMA's frames. + * ******************************************************************************/ +struct em_rx_buffer { + STAILQ_ENTRY(em_rx_buffer) em_rx_entry; + struct mbuf *Packet; + u_int32_t LowPhysicalAddress; + u_int32_t HighPhysicalAddress; +}; + +typedef enum _XSUM_CONTEXT_T { + OFFLOAD_NONE, + OFFLOAD_TCP_IP, + OFFLOAD_UDP_IP +} XSUM_CONTEXT_T; + +/* Our adapter structure */ +struct adapter { + struct arpcom interface_data; + struct adapter *next; + struct adapter *prev; + + /* FreeBSD operating-system-specific structures */ + bus_space_tag_t bus_space_tag; + bus_space_handle_t bus_space_handle; + struct device *dev; + struct resource *res_memory; + struct resource *res_interrupt; + void *int_handler_tag; + struct ifmedia media; + struct callout_handle timer_handle; + u_int8_t unit; + + /* PCI Info */ + u_int16_t VendorId; + u_int16_t DeviceId; + u_int8_t RevId; + u_int16_t SubVendorId; + u_int16_t SubSystemId; + u_int16_t PciCommandWord; + + /* PCI Bus Info */ + E1000_BUS_TYPE_ENUM BusType; + E1000_BUS_SPEED_ENUM BusSpeed; + E1000_BUS_WIDTH_ENUM BusWidth; + + /* Info about the board itself */ + u_int8_t MacType; + u_int8_t MediaType; + u_int32_t PhyId; + u_int32_t PhyAddress; + uint8_t CurrentNetAddress[ETH_LENGTH_OF_ADDRESS]; + uint8_t PermNetAddress[ETH_LENGTH_OF_ADDRESS]; + u_int32_t PartNumber; + + u_int8_t AdapterStopped; + u_int8_t DmaFairness; + u_int8_t ReportTxEarly; + u_int32_t MulticastFilterType; + u_int32_t NumberOfMcAddresses; + u_int8_t MulticastAddressList[MAX_NUM_MULTICAST_ADDRESSES][ETH_LENGTH_OF_ADDRESS]; + + u_int8_t GetLinkStatus; + u_int8_t LinkStatusChanged; + u_int8_t LinkIsActive; + u_int32_t AutoNegFailed; + u_int8_t AutoNeg; + u_int16_t AutoNegAdvertised; + u_int8_t WaitAutoNegComplete; + u_int8_t ForcedSpeedDuplex; + u_int16_t LineSpeed; + u_int16_t FullDuplex; + u_int8_t TbiCompatibilityEnable; + u_int8_t TbiCompatibilityOn; + u_int32_t TxcwRegValue; + u_int32_t OriginalFlowControl; + u_int32_t FlowControl; + u_int16_t FlowControlHighWatermark; + u_int16_t FlowControlLowWatermark; + u_int16_t FlowControlPauseTime; + u_int8_t FlowControlSendXon; + + u_int32_t MaxFrameSize; + u_int32_t TxIntDelay; + u_int32_t RxIntDelay; + + u_int8_t RxChecksum; + XSUM_CONTEXT_T ActiveChecksumContext; + + u_int8_t MdiX; + u_int8_t DisablePolarityCorrection; + + /* Transmit definitions */ + struct _E1000_TRANSMIT_DESCRIPTOR *FirstTxDescriptor; + struct _E1000_TRANSMIT_DESCRIPTOR *LastTxDescriptor; + struct _E1000_TRANSMIT_DESCRIPTOR *NextAvailTxDescriptor; + struct _E1000_TRANSMIT_DESCRIPTOR *OldestUsedTxDescriptor; + struct _E1000_TRANSMIT_DESCRIPTOR *TxDescBase; + volatile u_int16_t NumTxDescriptorsAvail; + u_int16_t NumTxDescriptors; + u_int32_t TxdCmd; + struct em_tx_buffer *tx_buffer_area; + STAILQ_HEAD(__em_tx_buffer_free, em_tx_buffer) FreeSwTxPacketList; + STAILQ_HEAD(__em_tx_buffer_used, em_tx_buffer) UsedSwTxPacketList; + + /* Receive definitions */ + struct _E1000_RECEIVE_DESCRIPTOR *FirstRxDescriptor; + struct _E1000_RECEIVE_DESCRIPTOR *LastRxDescriptor; + struct _E1000_RECEIVE_DESCRIPTOR *NextRxDescriptorToCheck; + struct _E1000_RECEIVE_DESCRIPTOR *RxDescBase; + u_int16_t NumRxDescriptors; + u_int16_t NumRxDescriptorsEmpty; + u_int16_t NextRxDescriptorToFill; + u_int32_t RxBufferLen; + struct em_rx_buffer *rx_buffer_area; + STAILQ_HEAD(__em_rx_buffer, em_rx_buffer) RxSwPacketList; + + /* Jumbo frame */ + u_int8_t JumboEnable; + struct em_jslot em_jslots[EM_JSLOTS]; + void *em_jumbo_buf; + SLIST_HEAD(__em_jfreehead, em_jpool_entry) em_jfree_listhead; + SLIST_HEAD(__em_jinusehead, em_jpool_entry) em_jinuse_listhead; + + + /* Misc stats maintained by the driver */ + unsigned long DroppedPackets; + unsigned long NoJumboBufAvail; + unsigned long JumboMbufFailed; + unsigned long JumboClusterFailed; + unsigned long StdMbufFailed; + unsigned long StdClusterFailed; +#ifdef DBG_STATS + unsigned long NoTxDescAvail; + unsigned long NoPacketsAvail; + unsigned long CleanTxInterrupts; + unsigned long NoTxBufferAvail1; + unsigned long NoTxBufferAvail2; +#endif + + /* Statistics registers present in the 82542 */ + unsigned long Crcerrs; + unsigned long Symerrs; + unsigned long Mpc; + unsigned long Scc; + unsigned long Ecol; + unsigned long Mcc; + unsigned long Latecol; + unsigned long Colc; + unsigned long Dc; + unsigned long Sec; + unsigned long Rlec; + unsigned long Xonrxc; + unsigned long Xontxc; + unsigned long Xoffrxc; + unsigned long Xofftxc; + unsigned long Fcruc; + unsigned long Prc64; + unsigned long Prc127; + unsigned long Prc255; + unsigned long Prc511; + unsigned long Prc1023; + unsigned long Prc1522; + unsigned long Gprc; + unsigned long Bprc; + unsigned long Mprc; + unsigned long Gptc; + unsigned long Gorcl; + unsigned long Gorch; + unsigned long Gotcl; + unsigned long Gotch; + unsigned long Rnbc; + unsigned long Ruc; + unsigned long Rfc; + unsigned long Roc; + unsigned long Rjc; + unsigned long Torcl; + unsigned long Torch; + unsigned long Totcl; + unsigned long Totch; + unsigned long Tpr; + unsigned long Tpt; + unsigned long Ptc64; + unsigned long Ptc127; + unsigned long Ptc255; + unsigned long Ptc511; + unsigned long Ptc1023; + unsigned long Ptc1522; + unsigned long Mptc; + unsigned long Bptc; + /* Statistics registers added in the 82543 */ + unsigned long Algnerrc; + unsigned long Rxerrc; + unsigned long Tuc; + unsigned long Tncrs; + unsigned long Cexterr; + unsigned long Rutec; + unsigned long Tsctc; + unsigned long Tsctfc; + +}; + +extern void em_adjust_tbi_accepted_stats(struct adapter * Adapter, + u32 FrameLength, u8 * MacAddress); + +#endif /* _EM_H_DEFINED_ */ diff --git a/sys/dev/em/if_em_fxhw.h b/sys/dev/em/if_em_fxhw.h new file mode 100644 index 000000000000..86447e583631 --- /dev/null +++ b/sys/dev/em/if_em_fxhw.h @@ -0,0 +1,1338 @@ +/************************************************************************* +************************************************************************** +Copyright (c) 2001 Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms of the Software, with or +without modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code of the Software may retain the above + copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form of the Software may 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 shall 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 INTEL OR ITS CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +$FreeBSD$ +*************************************************************************** +**************************************************************************/ + +#ifndef _EM_FXHW_H_ +#define _EM_FXHW_H_ + +/* +* Workfile: fxhw.h +* Date: 9/25/01 2:40p +* Revision: 43 +*/ + +#define _FXHW_ + +struct adapter; +struct _E1000_TRANSMIT_DESCRIPTOR; +struct _E1000_RECEIVE_DESCRIPTOR; +struct E1000_REGISTERS; + +typedef enum _MAC_TYPE { + MAC_WISEMAN_2_0 = 0, + MAC_WISEMAN_2_1, + MAC_LIVENGOOD, + MAC_WAINWRIGHT, + MAC_CORDOVA, + NUM_MACS +} MAC_TYPE, *PMAC_TYPE; + +typedef enum _GIGABIT_MEDIA_TYPE { + MEDIA_TYPE_COPPER = 0, + MEDIA_TYPE_FIBER = 1, + NUM_MEDIA_TYPES +} GIGABIT_MEDIA_TYPE, *PGIGABIT_MEDIA_TYPE; + +typedef enum _SPEED_DUPLEX_TYPE { + HALF_10 = 0, + FULL_10 = 1, + HALF_100 = 2, + FULL_100 = 3 +} SPEED_DUPLEX_TYPE, *PSPEED_DUPLEX_TYPE; + +typedef enum _FLOW_CONTROL_TYPE { + FLOW_CONTROL_NONE = 0, + FLOW_CONTROL_RECEIVE_PAUSE = 1, + FLOW_CONTROL_TRANSMIT_PAUSE = 2, + FLOW_CONTROL_FULL = 3, + FLOW_CONTROL_HW_DEFAULT = 0xFF +} FLOW_CONTROL_TYPE, *PFLOW_CONTROL_TYPE; + +typedef enum { + E1000_BUS_TYPE_UNKNOWN = 0, + E1000_BUS_TYPE_PCI, + E1000_BUS_TYPE_PCIX +} E1000_BUS_TYPE_ENUM; + +typedef enum { + E1000_BUS_SPEED_UNKNOWN = 0, + E1000_BUS_SPEED_PCI_33MHZ, + E1000_BUS_SPEED_PCI_66MHZ, + E1000_BUS_SPEED_PCIX_50_66MHZ, + E1000_BUS_SPEED_PCIX_66_100MHZ, + E1000_BUS_SPEED_PCIX_100_133MHZ, + E1000_BUS_SPEED_PCIX_RESERVED +} E1000_BUS_SPEED_ENUM; + +typedef enum { + E1000_BUS_WIDTH_UNKNOWN = 0, + E1000_BUS_WIDTH_32_BIT, + E1000_BUS_WIDTH_64_BIT +} E1000_BUS_WIDTH_ENUM; + +#include <dev/em/if_em_osdep.h> + +void em_adapter_stop(struct adapter *Adapter); +u8 em_initialize_hardware(struct adapter *Adapter); +void em_init_rx_addresses(struct adapter *Adapter); + +void em_multicast_address_list_update(struct adapter *Adapter, + u8 * MulticastAddressList, + u32 MulticastAddressCount, + + u32 Padding); +u32 em_hash_multicast_address(struct adapter *Adapter, + + u8 * MulticastAddress); +void em_mta_set(struct adapter *Adapter, u32 HashValue); +void em_rar_set(struct adapter *Adapter, + + u8 * MulticastAddress, u32 RarIndex); +void em_write_vfta(struct adapter *Adapter, u32 Offset, u32 Value); +void em_clear_vfta(struct adapter *Adapter); + +u8 em_setup_flow_control_and_link(struct adapter *Adapter); +u8 em_setup_pcs_link(struct adapter *Adapter, u32 DeviceControlReg); +void em_config_flow_control_after_link_up(struct adapter *Adapter); +void em_force_mac_flow_control_setting(struct adapter *Adapter); +void em_check_for_link(struct adapter *Adapter); +void em_get_speed_and_duplex(struct adapter *Adapter, + + u16 * Speed, u16 * Duplex); + +void em_cleanup_eeprom(struct adapter *Adapter); +void em_clock_eeprom(struct adapter *Adapter); +void em_setup_eeprom(struct adapter *Adapter); +void em_standby_eeprom(struct adapter *Adapter); +u16 em_read_eeprom_word(struct adapter *Adapter, u16 Reg); +u8 em_validate_eeprom_checksum(struct adapter *Adapter); +void em_update_eeprom_checksum(struct adapter *Adapter); +u8 em_write_eeprom_word(struct adapter *Adapter, u16 reg, u16 data); + +void em_clear_hw_stats_counters(struct adapter *Adapter); +u8 em_read_part_number(struct adapter *Adapter, u32 * PartNumber); +void em_id_led_on(struct adapter *Adapter); +void em_id_led_off(struct adapter *Adapter); +void em_set_id_led_for_pc_ix(struct adapter *Adapter); +u8 em_is_low_profile(struct adapter *Adapter); +void em_get_bus_type_speed_width(struct adapter *Adapter); + +#define MAC_DECODE_SIZE (128 * 1024) + +#define WISEMAN_2_0_REV_ID 2 +#define WISEMAN_2_1_REV_ID 3 + +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 +#define HALF_DUPLEX 1 +#define FULL_DUPLEX 2 + +#define ENET_HEADER_SIZE 14 +#define MAXIMUM_ETHERNET_PACKET_SIZE 1514 +#define MINIMUM_ETHERNET_PACKET_SIZE 60 +#define CRC_LENGTH 4 + +#define MAX_JUMBO_FRAME_SIZE (0x3F00) + +#define ISL_CRC_LENGTH 4 + +#define MAXIMUM_VLAN_ETHERNET_PACKET_SIZE 1514 +#define MINIMUM_VLAN_ETHERNET_PACKET_SIZE 60 +#define VLAN_TAG_SIZE 4 + +#define ETHERNET_IEEE_VLAN_TYPE 0x8100 +#define ETHERNET_IP_TYPE 0x0800 +#define ETHERNET_IPX_TYPE 0x8037 +#define ETHERNET_IPX_OLD_TYPE 0x8137 +#define MAX_802_3_LEN_FIELD 0x05DC + +#define ETHERNET_ARP_TYPE 0x0806 +#define ETHERNET_XNS_TYPE 0x0600 +#define ETHERNET_X25_TYPE 0x0805 +#define ETHERNET_BANYAN_TYPE 0x0BAD +#define ETHERNET_DECNET_TYPE 0x6003 +#define ETHERNET_APPLETALK_TYPE 0x809B +#define ETHERNET_SNA_TYPE 0x80D5 +#define ETHERNET_SNMP_TYPE 0x814C + +#define IP_OFF_MF_BIT 0x0002 +#define IP_OFF_OFFSET_MASK 0xFFF8 +#define IP_PROTOCOL_ICMP 1 +#define IP_PROTOCOL_IGMP 2 +#define IP_PROTOCOL_TCP 6 +#define IP_PROTOCOL_UDP 0x11 +#define IP_PROTOCOL_IPRAW 0xFF + +#define POLL_IMS_ENABLE_MASK (E1000_IMS_RXDMT0 | E1000_IMS_RXSEQ) + +#define IMS_ENABLE_MASK (E1000_IMS_RXT0 | E1000_IMS_TXDW | E1000_IMS_RXDMT0 | E1000_IMS_RXSEQ | E1000_IMS_LSC) + +#define E1000_RAR_ENTRIES 16 + +typedef struct _E1000_RECEIVE_DESCRIPTOR { + E1000_64_BIT_PHYSICAL_ADDRESS BufferAddress; + + u16 Length; + u16 Csum; + u8 ReceiveStatus; + u8 Errors; + u16 Special; + +} E1000_RECEIVE_DESCRIPTOR, *PE1000_RECEIVE_DESCRIPTOR; + +#define MIN_NUMBER_OF_DESCRIPTORS (8) +#define MAX_NUMBER_OF_DESCRIPTORS (0xFFF8) + +#define E1000_RXD_STAT_DD (0x01) +#define E1000_RXD_STAT_EOP (0x02) + +#define E1000_RXD_STAT_ISL (0x04) +#define E1000_RXD_STAT_IXSM (0x04) +#define E1000_RXD_STAT_VP (0x08) +#define E1000_RXD_STAT_BPDU (0x10) +#define E1000_RXD_STAT_TCPCS (0x20) +#define E1000_RXD_STAT_IPCS (0x40) + +#define E1000_RXD_STAT_PIF (0x80) + +#define E1000_RXD_ERR_CE (0x01) +#define E1000_RXD_ERR_SE (0x02) +#define E1000_RXD_ERR_SEQ (0x04) + +#define E1000_RXD_ERR_ICE (0x08) + +#define E1000_RXD_ERR_CXE (0x10) + +#define E1000_RXD_ERR_TCPE (0x20) +#define E1000_RXD_ERR_IPE (0x40) + +#define E1000_RXD_ERR_RXE (0x80) + +#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) + +#define E1000_RXD_SPC_VLAN_MASK (0x0FFF) +#define E1000_RXD_SPC_PRI_MASK (0xE000) +#define E1000_RXD_SPC_PRI_SHIFT (0x000D) +#define E1000_RXD_SPC_CFI_MASK (0x1000) +#define E1000_RXD_SPC_CFI_SHIFT (0x000C) + +#define E1000_TXD_DTYP_D (0x00100000) +#define E1000_TXD_DTYP_C (0x00000000) +#define E1000_TXD_POPTS_IXSM (0x01) +#define E1000_TXD_POPTS_TXSM (0x02) + +typedef struct _E1000_TRANSMIT_DESCRIPTOR { + E1000_64_BIT_PHYSICAL_ADDRESS BufferAddress; + + union { + u32 DwordData; + struct _TXD_FLAGS { + u16 Length; + u8 Cso; + u8 Cmd; + } Flags; + } Lower; + + union { + u32 DwordData; + struct _TXD_FIELDS { + u8 TransmitStatus; + u8 Css; + u16 Special; + } Fields; + } Upper; + +} E1000_TRANSMIT_DESCRIPTOR, *PE1000_TRANSMIT_DESCRIPTOR; + +typedef struct _E1000_TCPIP_CONTEXT_TRANSMIT_DESCRIPTOR { + union { + u32 IpXsumConfig; + struct _IP_XSUM_FIELDS { + u8 Ipcss; + u8 Ipcso; + u16 Ipcse; + } IpFields; + } LowerXsumSetup; + + union { + u32 TcpXsumConfig; + struct _TCP_XSUM_FIELDS { + u8 Tucss; + u8 Tucso; + u16 Tucse; + } TcpFields; + } UpperXsumSetup; + + u32 CmdAndLength; + + union { + u32 DwordData; + struct _TCP_SEG_FIELDS { + u8 Status; + u8 HdrLen; + u16 Mss; + } Fields; + } TcpSegSetup; + +} E1000_TCPIP_CONTEXT_TRANSMIT_DESCRIPTOR, + + *PE1000_TCPIP_CONTEXT_TRANSMIT_DESCRIPTOR; + +typedef struct _E1000_TCPIP_DATA_TRANSMIT_DESCRIPTOR { + E1000_64_BIT_PHYSICAL_ADDRESS BufferAddress; + + union { + u32 DwordData; + struct _TXD_OD_FLAGS { + u16 Length; + u8 TypLenExt; + u8 Cmd; + } Flags; + } Lower; + + union { + u32 DwordData; + struct _TXD_OD_FIELDS { + u8 TransmitStatus; + u8 Popts; + u16 Special; + } Fields; + } Upper; + +} E1000_TCPIP_DATA_TRANSMIT_DESCRIPTOR, + + *PE1000_TCPIP_DATA_TRANSMIT_DESCRIPTOR; + +#define E1000_TXD_CMD_EOP (0x01000000) +#define E1000_TXD_CMD_IFCS (0x02000000) + +#define E1000_TXD_CMD_IC (0x04000000) + +#define E1000_TXD_CMD_RS (0x08000000) +#define E1000_TXD_CMD_RPS (0x10000000) + +#define E1000_TXD_CMD_DEXT (0x20000000) +#define E1000_TXD_CMD_ISLVE (0x40000000) + +#define E1000_TXD_CMD_IDE (0x80000000) + +#define E1000_TXD_STAT_DD (0x00000001) +#define E1000_TXD_STAT_EC (0x00000002) +#define E1000_TXD_STAT_LC (0x00000004) +#define E1000_TXD_STAT_TU (0x00000008) + +#define E1000_TXD_CMD_TCP (0x01000000) +#define E1000_TXD_CMD_IP (0x02000000) +#define E1000_TXD_CMD_TSE (0x04000000) + +#define E1000_TXD_STAT_TC (0x00000004) + +#define E1000_NUM_UNICAST (16) +#define E1000_MC_TBL_SIZE (128) + +#define E1000_VLAN_FILTER_TBL_SIZE (128) + +typedef struct { + volatile u32 Low; + volatile u32 High; +} RECEIVE_ADDRESS_REGISTER_PAIR; + +#define E1000_NUM_MTA_REGISTERS 128 + +typedef struct { + volatile u32 IpAddress; + volatile u32 Reserved; +} IPAT_ENTRY; + +#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX (4) +#define E1000_IPAT_SIZE E1000_WAKEUP_IP_ADDRESS_COUNT_MAX + +typedef struct { + volatile u32 Length; + volatile u32 Reserved; +} FFLT_ENTRY; + +typedef struct { + volatile u32 Mask; + volatile u32 Reserved; +} FFMT_ENTRY; + +typedef struct { + volatile u32 Value; + volatile u32 Reserved; +} FFVT_ENTRY; + +#define E1000_FLEXIBLE_FILTER_COUNT_MAX (4) + +#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 + +typedef struct _E1000_REGISTERS { + + volatile u32 Ctrl; + volatile u32 Pad1; + volatile u32 Status; + volatile u32 Pad2; + volatile u32 Eecd; + volatile u32 Pad3; + volatile u32 Exct; + volatile u32 Pad4; + volatile u32 Mdic; + volatile u32 Pad5; + volatile u32 Fcal; + volatile u32 Fcah; + volatile u32 Fct; + volatile u32 Pad6; + + volatile u32 Vet; + volatile u32 Pad7; + + RECEIVE_ADDRESS_REGISTER_PAIR Rar[16]; + + volatile u32 Icr; + volatile u32 Pad8; + volatile u32 Ics; + volatile u32 Pad9; + volatile u32 Ims; + volatile u32 Pad10; + volatile u32 Imc; + volatile u8 Pad11[0x24]; + + volatile u32 Rctl; + volatile u32 Pad12; + volatile u32 PadRdtr0; + volatile u32 Pad13; + volatile u32 PadRdbal0; + volatile u32 PadRdbah0; + volatile u32 PadRdlen0; + volatile u32 Pad14; + volatile u32 PadRdh0; + volatile u32 Pad15; + volatile u32 PadRdt0; + volatile u32 Pad16; + volatile u32 Rdtr1; + volatile u32 Pad17; + volatile u32 Rdbal1; + volatile u32 Rdbah1; + volatile u32 Rdlen1; + volatile u32 Pad18; + volatile u32 Rdh1; + volatile u32 Pad19; + volatile u32 Rdt1; + volatile u8 Pad20[0x0C]; + volatile u32 PadFcrth; + volatile u32 Pad21; + volatile u32 PadFcrtl; + volatile u32 Pad22; + volatile u32 Fcttv; + volatile u32 Pad23; + volatile u32 Txcw; + volatile u32 Pad24; + volatile u32 Rxcw; + volatile u8 Pad25[0x7C]; + volatile u32 Mta[(128)]; + + volatile u32 Tctl; + volatile u32 Pad26; + volatile u32 Tqsal; + volatile u32 Tqsah; + volatile u32 Tipg; + volatile u32 Pad27; + volatile u32 Tqc; + volatile u32 Pad28; + volatile u32 PadTdbal; + volatile u32 PadTdbah; + volatile u32 PadTdl; + volatile u32 Pad29; + volatile u32 PadTdh; + volatile u32 Pad30; + volatile u32 PadTdt; + volatile u32 Pad31; + volatile u32 PadTidv; + volatile u32 Pad32; + volatile u32 Tbt; + volatile u8 Pad33[0x0C]; + + volatile u32 Ait; + volatile u8 Pad34[0xA4]; + + volatile u32 Ftr[8]; + volatile u32 Fcr; + volatile u32 Pad35; + volatile u32 Trcr; + + volatile u8 Pad36[0xD4]; + + volatile u32 Vfta[(128)]; + volatile u8 Pad37[0x700]; + volatile u32 Circ; + volatile u8 Pad37a[0xFC]; + + volatile u32 Pba; + volatile u8 Pad38[0xFFC]; + + volatile u8 Pad39[0x8]; + volatile u32 Ert; + volatile u8 Pad40[0xf4]; + + volatile u8 Pad41[0x60]; + volatile u32 Fcrtl; + volatile u32 Pad42; + volatile u32 Fcrth; + volatile u8 Pad43[0x294]; + + volatile u8 Pad44[0x10]; + volatile u32 Rdfh; + volatile u32 Pad45; + volatile u32 Rdft; + volatile u32 Pad45a; + volatile u32 Rdfhs; + volatile u32 Pad45b; + volatile u32 Rdfts; + volatile u32 Pad45c; + volatile u32 Rdfpc; + volatile u8 Pad46[0x3cc]; + + volatile u32 Rdbal0; + volatile u32 Rdbah0; + volatile u32 Rdlen0; + volatile u32 Pad47; + volatile u32 Rdh0; + volatile u32 Pad48; + volatile u32 Rdt0; + volatile u32 Pad49; + volatile u32 Rdtr0; + volatile u32 Pad50; + volatile u32 Rxdctl; + volatile u32 Pad51; + volatile u32 Rddh0; + volatile u32 Pad52; + volatile u32 Rddt0; + volatile u8 Pad53[0x7C4]; + + volatile u32 Txdmac; + volatile u32 Pad54; + volatile u32 Ett; + volatile u8 Pad55[0x3f4]; + + volatile u8 Pad56[0x10]; + volatile u32 Tdfh; + volatile u32 Pad57; + volatile u32 Tdft; + volatile u32 Pad57a; + volatile u32 Tdfhs; + volatile u32 Pad57b; + volatile u32 Tdfts; + volatile u32 Pad57c; + volatile u32 Tdfpc; + volatile u8 Pad58[0x3cc]; + + volatile u32 Tdbal; + volatile u32 Tdbah; + volatile u32 Tdl; + volatile u32 Pad59; + volatile u32 Tdh; + volatile u32 Pad60; + volatile u32 Tdt; + volatile u32 Pad61; + volatile u32 Tidv; + volatile u32 Pad62; + volatile u32 Txdctl; + volatile u32 Pad63; + volatile u32 Tddh; + volatile u32 Pad64; + volatile u32 Tddt; + volatile u8 Pad65[0x7C4]; + + volatile u32 Crcerrs; + volatile u32 Algnerrc; + volatile u32 Symerrs; + volatile u32 Rxerrc; + volatile u32 Mpc; + volatile u32 Scc; + volatile u32 Ecol; + volatile u32 Mcc; + volatile u32 Latecol; + volatile u32 Pad66; + volatile u32 Colc; + volatile u32 Tuc; + volatile u32 Dc; + volatile u32 Tncrs; + volatile u32 Sec; + volatile u32 Cexterr; + volatile u32 Rlec; + volatile u32 Rutec; + volatile u32 Xonrxc; + volatile u32 Xontxc; + volatile u32 Xoffrxc; + volatile u32 Xofftxc; + volatile u32 Fcruc; + volatile u32 Prc64; + volatile u32 Prc127; + volatile u32 Prc255; + volatile u32 Prc511; + volatile u32 Prc1023; + volatile u32 Prc1522; + volatile u32 Gprc; + volatile u32 Bprc; + volatile u32 Mprc; + volatile u32 Gptc; + volatile u32 Pad67; + volatile u32 Gorl; + volatile u32 Gorh; + volatile u32 Gotl; + volatile u32 Goth; + volatile u8 Pad68[8]; + volatile u32 Rnbc; + volatile u32 Ruc; + volatile u32 Rfc; + volatile u32 Roc; + volatile u32 Rjc; + volatile u8 Pad69[0xC]; + volatile u32 Torl; + volatile u32 Torh; + volatile u32 Totl; + volatile u32 Toth; + volatile u32 Tpr; + volatile u32 Tpt; + volatile u32 Ptc64; + volatile u32 Ptc127; + volatile u32 Ptc255; + volatile u32 Ptc511; + volatile u32 Ptc1023; + volatile u32 Ptc1522; + volatile u32 Mptc; + volatile u32 Bptc; + + volatile u32 Tsctc; + volatile u32 Tsctfc; + volatile u8 Pad70[0x0F00]; + + volatile u32 Rxcsum; + volatile u8 Pad71[0x07FC]; + + volatile u32 Wuc; + volatile u32 Pad72; + volatile u32 Wufc; + volatile u32 Pad73; + volatile u32 Wus; + volatile u8 Pad74[0x24]; + volatile u32 Ipav; + volatile u32 Pad75; + IPAT_ENTRY Ipat[(4)]; + volatile u8 Pad76[0xA0]; + volatile u32 Wupl; + volatile u8 Pad77[0xFC]; + volatile u8 Wupm[0x80]; + volatile u8 Pad78[0x480]; + FFLT_ENTRY Fflt[(4)]; + volatile u8 Pad79[0x20E0]; + + volatile u32 PadRdfh; + volatile u32 Pad80; + volatile u32 PadRdft; + volatile u32 Pad81; + volatile u32 PadTdfh; + volatile u32 Pad82; + volatile u32 PadTdft; + volatile u8 Pad83[0xFE4]; + + FFMT_ENTRY Ffmt[(128)]; + volatile u8 Pad84[0x0400]; + FFVT_ENTRY Ffvt[(128)]; + + volatile u8 Pad85[0x6400]; + + volatile u32 Pbm[0x4000]; + +} E1000_REGISTERS, *PE1000_REGISTERS; + +typedef struct _OLD_REGISTERS { + + volatile u32 Ctrl; + volatile u32 Pad1; + volatile u32 Status; + volatile u32 Pad2; + volatile u32 Eecd; + volatile u32 Pad3; + volatile u32 Exct; + volatile u32 Pad4; + volatile u32 Mdic; + volatile u32 Pad5; + volatile u32 Fcal; + volatile u32 Fcah; + volatile u32 Fct; + volatile u32 Pad6; + + volatile u32 Vet; + volatile u32 Pad7; + + RECEIVE_ADDRESS_REGISTER_PAIR Rar[16]; + + volatile u32 Icr; + volatile u32 Pad8; + volatile u32 Ics; + volatile u32 Pad9; + volatile u32 Ims; + volatile u32 Pad10; + volatile u32 Imc; + volatile u8 Pad11[0x24]; + + volatile u32 Rctl; + volatile u32 Pad12; + volatile u32 Rdtr0; + volatile u32 Pad13; + volatile u32 Rdbal0; + volatile u32 Rdbah0; + volatile u32 Rdlen0; + volatile u32 Pad14; + volatile u32 Rdh0; + volatile u32 Pad15; + volatile u32 Rdt0; + volatile u32 Pad16; + volatile u32 Rdtr1; + volatile u32 Pad17; + volatile u32 Rdbal1; + volatile u32 Rdbah1; + volatile u32 Rdlen1; + volatile u32 Pad18; + volatile u32 Rdh1; + volatile u32 Pad19; + volatile u32 Rdt1; + volatile u8 Pad20[0x0C]; + volatile u32 Fcrth; + volatile u32 Pad21; + volatile u32 Fcrtl; + volatile u32 Pad22; + volatile u32 Fcttv; + volatile u32 Pad23; + volatile u32 Txcw; + volatile u32 Pad24; + volatile u32 Rxcw; + volatile u8 Pad25[0x7C]; + volatile u32 Mta[(128)]; + + volatile u32 Tctl; + volatile u32 Pad26; + volatile u32 Tqsal; + volatile u32 Tqsah; + volatile u32 Tipg; + volatile u32 Pad27; + volatile u32 Tqc; + volatile u32 Pad28; + volatile u32 Tdbal; + volatile u32 Tdbah; + volatile u32 Tdl; + volatile u32 Pad29; + volatile u32 Tdh; + volatile u32 Pad30; + volatile u32 Tdt; + volatile u32 Pad31; + volatile u32 Tidv; + volatile u32 Pad32; + volatile u32 Tbt; + volatile u8 Pad33[0x0C]; + + volatile u32 Ait; + volatile u8 Pad34[0xA4]; + + volatile u32 Ftr[8]; + volatile u32 Fcr; + volatile u32 Pad35; + volatile u32 Trcr; + + volatile u8 Pad36[0xD4]; + + volatile u32 Vfta[(128)]; + volatile u8 Pad37[0x700]; + volatile u32 Circ; + volatile u8 Pad37a[0xFC]; + + volatile u32 Pba; + volatile u8 Pad38[0xFFC]; + + volatile u8 Pad39[0x8]; + volatile u32 Ert; + volatile u8 Pad40[0x1C]; + volatile u32 Rxdctl; + volatile u8 Pad41[0xFD4]; + + volatile u32 Txdmac; + volatile u32 Pad42; + volatile u32 Ett; + volatile u8 Pad43[0x1C]; + volatile u32 Txdctl; + volatile u8 Pad44[0xFD4]; + + volatile u32 Crcerrs; + volatile u32 Algnerrc; + volatile u32 Symerrs; + volatile u32 Rxerrc; + volatile u32 Mpc; + volatile u32 Scc; + volatile u32 Ecol; + volatile u32 Mcc; + volatile u32 Latecol; + volatile u32 Pad45; + volatile u32 Colc; + volatile u32 Tuc; + volatile u32 Dc; + volatile u32 Tncrs; + volatile u32 Sec; + volatile u32 Cexterr; + volatile u32 Rlec; + volatile u32 Rutec; + volatile u32 Xonrxc; + volatile u32 Xontxc; + volatile u32 Xoffrxc; + volatile u32 Xofftxc; + volatile u32 Fcruc; + volatile u32 Prc64; + volatile u32 Prc127; + volatile u32 Prc255; + volatile u32 Prc511; + volatile u32 Prc1023; + volatile u32 Prc1522; + volatile u32 Gprc; + volatile u32 Bprc; + volatile u32 Mprc; + volatile u32 Gptc; + volatile u32 Pad46; + volatile u32 Gorl; + volatile u32 Gorh; + volatile u32 Gotl; + volatile u32 Goth; + volatile u8 Pad47[8]; + volatile u32 Rnbc; + volatile u32 Ruc; + volatile u32 Rfc; + volatile u32 Roc; + volatile u32 Rjc; + volatile u8 Pad48[0xC]; + volatile u32 Torl; + volatile u32 Torh; + volatile u32 Totl; + volatile u32 Toth; + volatile u32 Tpr; + volatile u32 Tpt; + volatile u32 Ptc64; + volatile u32 Ptc127; + volatile u32 Ptc255; + volatile u32 Ptc511; + volatile u32 Ptc1023; + volatile u32 Ptc1522; + volatile u32 Mptc; + volatile u32 Bptc; + + volatile u32 Tsctc; + volatile u32 Tsctfc; + volatile u8 Pad49[0x0F00]; + + volatile u32 Rxcsum; + volatile u8 Pad50[0x07FC]; + + volatile u32 Wuc; + volatile u32 Pad51; + volatile u32 Wufc; + volatile u32 Pad52; + volatile u32 Wus; + volatile u8 Pad53[0x24]; + volatile u32 Ipav; + volatile u32 Pad54; + IPAT_ENTRY Ipat[(4)]; + volatile u8 Pad55[0xA0]; + volatile u32 Wupl; + volatile u8 Pad56[0xFC]; + volatile u8 Wupm[0x80]; + volatile u8 Pad57[0x480]; + FFLT_ENTRY Fflt[(4)]; + volatile u8 Pad58[0x20E0]; + + volatile u32 Rdfh; + volatile u32 Pad59; + volatile u32 Rdft; + volatile u32 Pad60; + volatile u32 Tdfh; + volatile u32 Pad61; + volatile u32 Tdft; + volatile u32 Pad62; + volatile u32 Tdfhs; + volatile u32 Pad63; + volatile u32 Tdfts; + volatile u32 Pad64; + volatile u32 Tdfpc; + volatile u8 Pad65[0x0FCC]; + + FFMT_ENTRY Ffmt[(128)]; + volatile u8 Pad66[0x0400]; + FFVT_ENTRY Ffvt[(128)]; + + volatile u8 Pad67[0x6400]; + + volatile u32 Pbm[0x4000]; + +} OLD_REGISTERS, *POLD_REGISTERS; + +#define E1000_EEPROM_SWDPIN0 (0x00000001) +#define E1000_EEPROM_LED_LOGIC (0x0020) + +#define E1000_CTRL_FD (0x00000001) +#define E1000_CTRL_BEM (0x00000002) +#define E1000_CTRL_PRIOR (0x00000004) +#define E1000_CTRL_LRST (0x00000008) +#define E1000_CTRL_TME (0x00000010) +#define E1000_CTRL_SLE (0x00000020) +#define E1000_CTRL_ASDE (0x00000020) +#define E1000_CTRL_SLU (0x00000040) + +#define E1000_CTRL_ILOS (0x00000080) +#define E1000_CTRL_SPD_SEL (0x00000300) +#define E1000_CTRL_SPD_10 (0x00000000) +#define E1000_CTRL_SPD_100 (0x00000100) +#define E1000_CTRL_SPD_1000 (0x00000200) +#define E1000_CTRL_BEM32 (0x00000400) +#define E1000_CTRL_FRCSPD (0x00000800) +#define E1000_CTRL_FRCDPX (0x00001000) + +#define E1000_CTRL_SWDPIN0 (0x00040000) +#define E1000_CTRL_SWDPIN1 (0x00080000) +#define E1000_CTRL_SWDPIN2 (0x00100000) +#define E1000_CTRL_SWDPIN3 (0x00200000) +#define E1000_CTRL_SWDPIO0 (0x00400000) +#define E1000_CTRL_SWDPIO1 (0x00800000) +#define E1000_CTRL_SWDPIO2 (0x01000000) +#define E1000_CTRL_SWDPIO3 (0x02000000) +#define E1000_CTRL_RST (0x04000000) +#define E1000_CTRL_RFCE (0x08000000) +#define E1000_CTRL_TFCE (0x10000000) + +#define E1000_CTRL_RTE (0x20000000) +#define E1000_CTRL_VME (0x40000000) + +#define E1000_CTRL_PHY_RST (0x80000000) + +#define E1000_STATUS_FD (0x00000001) +#define E1000_STATUS_LU (0x00000002) +#define E1000_STATUS_TCKOK (0x00000004) +#define E1000_STATUS_RBCOK (0x00000008) +#define E1000_STATUS_TXOFF (0x00000010) +#define E1000_STATUS_TBIMODE (0x00000020) +#define E1000_STATUS_SPEED_10 (0x00000000) +#define E1000_STATUS_SPEED_100 (0x00000040) +#define E1000_STATUS_SPEED_1000 (0x00000080) +#define E1000_STATUS_ASDV (0x00000300) +#define E1000_STATUS_MTXCKOK (0x00000400) +#define E1000_STATUS_PCI66 (0x00000800) +#define E1000_STATUS_BUS64 (0x00001000) +#define E1000_STATUS_PCIX_MODE (0x00002000) +#define E1000_STATUS_PCIX_SPEED (0x0000C000) + +#define E1000_STATUS_PCIX_SPEED_66 (0x00000000) +#define E1000_STATUS_PCIX_SPEED_100 (0x00004000) +#define E1000_STATUS_PCIX_SPEED_133 (0x00008000) + +#define E1000_EESK (0x00000001) +#define E1000_EECS (0x00000002) +#define E1000_EEDI (0x00000004) +#define E1000_EEDO (0x00000008) +#define E1000_FLASH_WRITE_DIS (0x00000010) +#define E1000_FLASH_WRITE_EN (0x00000020) + +#define E1000_EXCTRL_GPI_EN0 (0x00000001) +#define E1000_EXCTRL_GPI_EN1 (0x00000002) +#define E1000_EXCTRL_GPI_EN2 (0x00000004) +#define E1000_EXCTRL_GPI_EN3 (0x00000008) +#define E1000_EXCTRL_SWDPIN4 (0x00000010) +#define E1000_EXCTRL_SWDPIN5 (0x00000020) +#define E1000_EXCTRL_SWDPIN6 (0x00000040) +#define E1000_EXCTRL_SWDPIN7 (0x00000080) +#define E1000_EXCTRL_SWDPIO4 (0x00000100) +#define E1000_EXCTRL_SWDPIO5 (0x00000200) +#define E1000_EXCTRL_SWDPIO6 (0x00000400) +#define E1000_EXCTRL_SWDPIO7 (0x00000800) +#define E1000_EXCTRL_ASDCHK (0x00001000) +#define E1000_EXCTRL_EE_RST (0x00002000) +#define E1000_EXCTRL_IPS (0x00004000) +#define E1000_EXCTRL_SPD_BYPS (0x00008000) + +#define E1000_MDI_WRITE (0x04000000) +#define E1000_MDI_READ (0x08000000) +#define E1000_MDI_READY (0x10000000) +#define E1000_MDI_INT (0x20000000) +#define E1000_MDI_ERR (0x40000000) + +#define E1000_RAH_RDR (0x40000000) +#define E1000_RAH_AV (0x80000000) + +#define E1000_ICR_TXDW (0x00000001) +#define E1000_ICR_TXQE (0x00000002) +#define E1000_ICR_LSC (0x00000004) +#define E1000_ICR_RXSEQ (0x00000008) +#define E1000_ICR_RXDMT0 (0x00000010) +#define E1000_ICR_RXDMT1 (0x00000020) +#define E1000_ICR_RXO (0x00000040) +#define E1000_ICR_RXT0 (0x00000080) +#define E1000_ICR_RXT1 (0x00000100) +#define E1000_ICR_MDAC (0x00000200) +#define E1000_ICR_RXCFG (0x00000400) +#define E1000_ICR_GPI_EN0 (0x00000800) +#define E1000_ICR_GPI_EN1 (0x00001000) +#define E1000_ICR_GPI_EN2 (0x00002000) +#define E1000_ICR_GPI_EN3 (0x00004000) + +#define E1000_ICS_TXDW E1000_ICR_TXDW +#define E1000_ICS_TXQE E1000_ICR_TXQE +#define E1000_ICS_LSC E1000_ICR_LSC +#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ +#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 +#define E1000_ICS_RXDMT1 E1000_ICR_RXDMT1 +#define E1000_ICS_RXO E1000_ICR_RXO +#define E1000_ICS_RXT0 E1000_ICR_RXT0 +#define E1000_ICS_RXT1 E1000_ICR_RXT1 +#define E1000_ICS_MDAC E1000_ICR_MDAC +#define E1000_ICS_RXCFG E1000_ICR_RXCFG +#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 +#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 +#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 +#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 + +#define E1000_IMS_TXDW E1000_ICR_TXDW +#define E1000_IMS_TXQE E1000_ICR_TXQE +#define E1000_IMS_LSC E1000_ICR_LSC +#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ +#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 +#define E1000_IMS_RXDMT1 E1000_ICR_RXDMT1 +#define E1000_IMS_RXO E1000_ICR_RXO +#define E1000_IMS_RXT0 E1000_ICR_RXT0 +#define E1000_IMS_RXT1 E1000_ICR_RXT1 +#define E1000_IMS_MDAC E1000_ICR_MDAC +#define E1000_IMS_RXCFG E1000_ICR_RXCFG +#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 +#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 +#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 +#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 + +#define E1000_IMC_TXDW E1000_ICR_TXDW +#define E1000_IMC_TXQE E1000_ICR_TXQE +#define E1000_IMC_LSC E1000_ICR_LSC +#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ +#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 +#define E1000_IMC_RXDMT1 E1000_ICR_RXDMT1 +#define E1000_IMC_RXO E1000_ICR_RXO +#define E1000_IMC_RXT0 E1000_ICR_RXT0 +#define E1000_IMC_RXT1 E1000_ICR_RXT1 +#define E1000_IMC_MDAC E1000_ICR_MDAC +#define E1000_IMC_RXCFG E1000_ICR_RXCFG +#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 +#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 +#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 +#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 + +#define E1000_TINT_RINT_PCI (E1000_TXDW|E1000_ICR_RXT0) +#define E1000_CAUSE_ERR (E1000_ICR_RXSEQ|E1000_ICR_RXO) + +#define E1000_RCTL_RST (0x00000001) +#define E1000_RCTL_EN (0x00000002) +#define E1000_RCTL_SBP (0x00000004) +#define E1000_RCTL_UPE (0x00000008) +#define E1000_RCTL_MPE (0x00000010) +#define E1000_RCTL_LPE (0x00000020) +#define E1000_RCTL_LBM_NO (0x00000000) +#define E1000_RCTL_LBM_MAC (0x00000040) +#define E1000_RCTL_LBM_SLP (0x00000080) +#define E1000_RCTL_LBM_TCVR (0x000000c0) +#define E1000_RCTL_RDMTS0_HALF (0x00000000) +#define E1000_RCTL_RDMTS0_QUAT (0x00000100) +#define E1000_RCTL_RDMTS0_EIGTH (0x00000200) +#define E1000_RCTL_RDMTS1_HALF (0x00000000) +#define E1000_RCTL_RDMTS1_QUAT (0x00000400) +#define E1000_RCTL_RDMTS1_EIGTH (0x00000800) +#define E1000_RCTL_MO_SHIFT 12 + +#define E1000_RCTL_MO_0 (0x00000000) +#define E1000_RCTL_MO_1 (0x00001000) +#define E1000_RCTL_MO_2 (0x00002000) +#define E1000_RCTL_MO_3 (0x00003000) + +#define E1000_RCTL_MDR (0x00004000) +#define E1000_RCTL_BAM (0x00008000) + +#define E1000_RCTL_SZ_2048 (0x00000000) +#define E1000_RCTL_SZ_1024 (0x00010000) +#define E1000_RCTL_SZ_512 (0x00020000) +#define E1000_RCTL_SZ_256 (0x00030000) + +#define E1000_RCTL_SZ_16384 (0x00010000) +#define E1000_RCTL_SZ_8192 (0x00020000) +#define E1000_RCTL_SZ_4096 (0x00030000) + +#define E1000_RCTL_VFE (0x00040000) + +#define E1000_RCTL_CFIEN (0x00080000) +#define E1000_RCTL_CFI (0x00100000) +#define E1000_RCTL_ISLE (0x00200000) + +#define E1000_RCTL_DPF (0x00400000) +#define E1000_RCTL_PMCF (0x00800000) + +#define E1000_RCTL_SISLH (0x01000000) + +#define E1000_RCTL_BSEX (0x02000000) +#define E1000_RDT0_DELAY (0x0000ffff) +#define E1000_RDT0_FPDB (0x80000000) + +#define E1000_RDT1_DELAY (0x0000ffff) +#define E1000_RDT1_FPDB (0x80000000) + +#define E1000_RDLEN0_LEN (0x0007ff80) + +#define E1000_RDLEN1_LEN (0x0007ff80) + +#define E1000_RDH0_RDH (0x0000ffff) + +#define E1000_RDH1_RDH (0x0000ffff) + +#define E1000_RDT0_RDT (0x0000ffff) + +#define E1000_FCRTH_RTH (0x0000FFF8) +#define E1000_FCRTH_XFCE (0x80000000) + +#define E1000_FCRTL_RTL (0x0000FFF8) +#define E1000_FCRTL_XONE (0x80000000) + +#define E1000_RXDCTL_PTHRESH 0x0000003F +#define E1000_RXDCTL_HTHRESH 0x00003F00 +#define E1000_RXDCTL_WTHRESH 0x003F0000 +#define E1000_RXDCTL_GRAN 0x01000000 + +#define E1000_TXDCTL_PTHRESH 0x000000FF +#define E1000_TXDCTL_HTHRESH 0x0000FF00 +#define E1000_TXDCTL_WTHRESH 0x00FF0000 +#define E1000_TXDCTL_GRAN 0x01000000 + +#define E1000_TXCW_FD (0x00000020) +#define E1000_TXCW_HD (0x00000040) +#define E1000_TXCW_PAUSE (0x00000080) +#define E1000_TXCW_ASM_DIR (0x00000100) +#define E1000_TXCW_PAUSE_MASK (0x00000180) +#define E1000_TXCW_RF (0x00003000) +#define E1000_TXCW_NP (0x00008000) +#define E1000_TXCW_CW (0x0000ffff) +#define E1000_TXCW_TXC (0x40000000) +#define E1000_TXCW_ANE (0x80000000) + +#define E1000_RXCW_CW (0x0000ffff) +#define E1000_RXCW_NC (0x04000000) +#define E1000_RXCW_IV (0x08000000) +#define E1000_RXCW_CC (0x10000000) +#define E1000_RXCW_C (0x20000000) +#define E1000_RXCW_SYNCH (0x40000000) +#define E1000_RXCW_ANC (0x80000000) + +#define E1000_TCTL_RST (0x00000001) +#define E1000_TCTL_EN (0x00000002) +#define E1000_TCTL_BCE (0x00000004) +#define E1000_TCTL_PSP (0x00000008) +#define E1000_TCTL_CT (0x00000ff0) +#define E1000_TCTL_COLD (0x003ff000) +#define E1000_TCTL_SWXOFF (0x00400000) +#define E1000_TCTL_PBE (0x00800000) +#define E1000_TCTL_RTLC (0x01000000) +#define E1000_TCTL_NRTU (0x02000000) + +#define E1000_TQSAL_TQSAL (0xffffffc0) +#define E1000_TQSAH_TQSAH (0xffffffff) + +#define E1000_TQC_SQ (0x00000001) +#define E1000_TQC_RQ (0x00000002) + +#define E1000_TDBAL_TDBAL (0xfffff000) +#define E1000_TDBAH_TDBAH (0xffffffff) + +#define E1000_TDL_LEN (0x0007ff80) + +#define E1000_TDH_TDH (0x0000ffff) + +#define E1000_TDT_TDT (0x0000ffff) + +#define E1000_RXCSUM_PCSS (0x000000ff) +#define E1000_RXCSUM_IPOFL (0x00000100) +#define E1000_RXCSUM_TUOFL (0x00000200) + +#define E1000_WUC_APME (0x00000001) +#define E1000_WUC_PME_EN (0x00000002) +#define E1000_WUC_PME_STATUS (0x00000004) +#define E1000_WUC_APMPME (0x00000008) + +#define E1000_WUFC_LNKC (0x00000001) +#define E1000_WUFC_MAG (0x00000002) +#define E1000_WUFC_EX (0x00000004) +#define E1000_WUFC_MC (0x00000008) +#define E1000_WUFC_BC (0x00000010) +#define E1000_WUFC_ARP (0x00000020) +#define E1000_WUFC_IP (0x00000040) +#define E1000_WUFC_FLX0 (0x00010000) +#define E1000_WUFC_FLX1 (0x00020000) +#define E1000_WUFC_FLX2 (0x00040000) +#define E1000_WUFC_FLX3 (0x00080000) +#define E1000_WUFC_ALL_FILTERS (0x000F007F) + +#define E1000_WUFC_FLX_OFFSET (16) +#define E1000_WUFC_FLX_FILTERS (0x000F0000) + +#define E1000_WUS_LNKC (0x00000001) +#define E1000_WUS_MAG (0x00000002) +#define E1000_WUS_EX (0x00000004) +#define E1000_WUS_MC (0x00000008) +#define E1000_WUS_BC (0x00000010) +#define E1000_WUS_ARP (0x00000020) +#define E1000_WUS_IP (0x00000040) +#define E1000_WUS_FLX0 (0x00010000) +#define E1000_WUS_FLX1 (0x00020000) +#define E1000_WUS_FLX2 (0x00040000) +#define E1000_WUS_FLX3 (0x00080000) +#define E1000_WUS_FLX_FILTERS (0x000F0000) + +#define E1000_WUPL_LENGTH_MASK (0x0FFF) + +#define E1000_MDALIGN (4096) + +#define EEPROM_READ_OPCODE (0x6) +#define EEPROM_WRITE_OPCODE (0x5) +#define EEPROM_ERASE_OPCODE (0x7) +#define EEPROM_EWEN_OPCODE (0x13) +#define EEPROM_EWDS_OPCODE (0x10) + +#define EEPROM_INIT_CONTROL1_REG (0x000A) +#define EEPROM_INIT_CONTROL2_REG (0x000F) +#define EEPROM_CHECKSUM_REG (0x003F) + +#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) + +#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) + +#define EEPROM_SUM (0xBABA) + +#define EEPROM_NODE_ADDRESS_BYTE_0 (0) +#define EEPROM_PBA_BYTE_1 (8) + +#define EEPROM_WORD_SIZE (64) + +#define NODE_ADDRESS_SIZE (6) +#define PBA_SIZE (4) + +#define E1000_COLLISION_THRESHOLD 16 +#define E1000_CT_SHIFT 4 + +#define E1000_FDX_COLLISION_DISTANCE 64 +#define E1000_HDX_COLLISION_DISTANCE 64 +#define E1000_GB_HDX_COLLISION_DISTANCE 512 +#define E1000_COLD_SHIFT 12 + +#define REQ_TX_DESCRIPTOR_MULTIPLE 8 +#define REQ_RX_DESCRIPTOR_MULTIPLE 8 + +#define DEFAULT_WSMN_TIPG_IPGT 10 +#define DEFAULT_LVGD_TIPG_IPGT_FIBER 6 +#define DEFAULT_LVGD_TIPG_IPGT_COPPER 8 + +#define E1000_TIPG_IPGT_MASK 0x000003FF +#define E1000_TIPG_IPGR1_MASK 0x000FFC00 +#define E1000_TIPG_IPGR2_MASK 0x3FF00000 + +#define DEFAULT_WSMN_TIPG_IPGR1 2 +#define DEFAULT_LVGD_TIPG_IPGR1 8 +#define E1000_TIPG_IPGR1_SHIFT 10 + +#define DEFAULT_WSMN_TIPG_IPGR2 10 +#define DEFAULT_LVGD_TIPG_IPGR2 6 +#define E1000_TIPG_IPGR2_SHIFT 20 + +#define E1000_TXDMAC_DPP 0x00000001 + +#define E1000_PBA_16K (0x0010) +#define E1000_PBA_24K (0x0018) +#define E1000_PBA_40K (0x0028) +#define E1000_PBA_48K (0x0030) + +#define FLOW_CONTROL_ADDRESS_LOW (0x00C28001) +#define FLOW_CONTROL_ADDRESS_HIGH (0x00000100) +#define FLOW_CONTROL_TYPE (0x8808) + +#define FC_DEFAULT_HI_THRESH (0x8000) +#define FC_DEFAULT_LO_THRESH (0x4000) +#define FC_DEFAULT_TX_TIMER (0x100) + +#define PAUSE_SHIFT 5 + +#define SWDPIO_SHIFT 17 + +#define SWDPIO__EXT_SHIFT 4 + +#define ILOS_SHIFT 3 + +#define MDI_REGADD_SHIFT 16 + +#define MDI_PHYADD_SHIFT 21 + +#define RECEIVE_BUFFER_ALIGN_SIZE (256) + +#define LINK_UP_TIMEOUT 500 + +#define E1000_TX_BUFFER_SIZE ((u32)1514) + +#define E1000_MIN_SIZE_OF_RECEIVE_BUFFERS (2048) + +#define CARRIER_EXTENSION 0x0F + +#define TBI_ACCEPT(RxErrors, LastByteInFrame, HwFrameLength) (Adapter->TbiCompatibilityOn && (((RxErrors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE)&& ((LastByteInFrame) == CARRIER_EXTENSION) && ((HwFrameLength) > 64) && ((HwFrameLength) <= Adapter->MaxFrameSize+1)) + +#define E1000_WAIT_PERIOD 10 + +#endif /* _EM_FXHW_H_ */ + diff --git a/sys/dev/em/if_em_osdep.h b/sys/dev/em/if_em_osdep.h new file mode 100644 index 000000000000..6097b51e609d --- /dev/null +++ b/sys/dev/em/if_em_osdep.h @@ -0,0 +1,95 @@ +/************************************************************************** +************************************************************************** + +Copyright (c) 2001 Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms of the Software, with or +without modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code of the Software may retain the above + copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form of the Software may 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 shall 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 INTEL OR ITS CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +$FreeBSD$ +*************************************************************************** +***************************************************************************/ + +#ifndef _FREEBSD_OS_H_ +#define _FREEBSD_OS_H_ + +#include <sys/types.h> + +#define ASSERT(x) if(!(x)) panic("EM: x") + +/* The happy-fun DELAY macro is defined in /usr/src/sys/i386/include/clock.h */ +#define DelayInMicroseconds(x) DELAY(x) +#define DelayInMilliseconds(x) DELAY(1000*(x)) + +typedef u_int8_t u8; +typedef u_int16_t u16; +typedef u_int32_t u32; +typedef struct _E1000_64_BIT_PHYSICAL_ADDRESS { + u32 Lo32; + u32 Hi32; +} E1000_64_BIT_PHYSICAL_ADDRESS, *PE1000_64_BIT_PHYSICAL_ADDRESS; + +#define IN +#define OUT +#define STATIC static + +#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 DEBUGOUT7(S,A,B,C,D,E,F,G) printf(S "\n",A,B,C,D,E,F,G) +#else + #define DEBUGOUT(S) + #define DEBUGOUT1(S,A) + #define DEBUGOUT2(S,A,B) + #define DEBUGOUT3(S,A,B,C) + #define DEBUGOUT7(S,A,B,C,D,E,F,G) +#endif + + +#define E1000_READ_REG(reg) \ + bus_space_read_4(Adapter->bus_space_tag, Adapter->bus_space_handle, \ + (Adapter->MacType >= MAC_LIVENGOOD)?offsetof(E1000_REGISTERS, reg): \ + offsetof(OLD_REGISTERS, reg)) + +#define E1000_WRITE_REG(reg, value) \ + bus_space_write_4(Adapter->bus_space_tag, Adapter->bus_space_handle, \ + (Adapter->MacType >= MAC_LIVENGOOD)?offsetof(E1000_REGISTERS, reg): \ + offsetof(OLD_REGISTERS, reg), value) + +#define WritePciConfigWord(Reg, PValue) pci_write_config(Adapter->dev, Reg, *PValue, 2); + + +#include <dev/em/if_em.h> + +#endif /* _FREEBSD_OS_H_ */ + diff --git a/sys/dev/em/if_em_phy.c b/sys/dev/em/if_em_phy.c new file mode 100644 index 000000000000..470e516028cf --- /dev/null +++ b/sys/dev/em/if_em_phy.c @@ -0,0 +1,1223 @@ +/************************************************************************* +************************************************************************** +Copyright (c) 2001 Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms of the Software, with or +without modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code of the Software may retain the above + copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form of the Software may 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 shall 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 INTEL OR ITS 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$ +*************************************************************************** +**************************************************************************/ +/* +* Workfile: phy.c +* Date: 9/25/01 2:40p +* Revision: 37 +*/ + +#include <dev/em/if_em_fxhw.h> +#include <dev/em/if_em_phy.h> + +static void em_mii_shift_out_phy_data(struct adapter *Adapter, + u32 Data, u16 Count); +static void em_raise_mdc_clock(struct adapter *Adapter, + + u32 * CtrlRegValue); +static void em_lower_mdc_clock(struct adapter *Adapter, + + u32 * CtrlRegValue); +static u16 em_mii_shift_in_phy_data(struct adapter *Adapter); +static u8 em_phy_setup_auto_neg_advertisement(struct adapter *Adapter); +static void em_phy_force_speed_and_duplex(struct adapter *Adapter); + +#define GOOD_MII_IF 0 + +u16 em_read_phy_register(struct adapter *Adapter, + u32 RegAddress, u32 PhyAddress) + { + u32 i; + u32 Data = 0; + u32 Command = 0; + + ASSERT(RegAddress <= MAX_PHY_REG_ADDRESS); + + if (Adapter->MacType > MAC_LIVENGOOD) { + + Command = ((RegAddress << MDI_REGADD_SHIFT) | + (PhyAddress << MDI_PHYADD_SHIFT) | + (E1000_MDI_READ)); + + E1000_WRITE_REG(Mdic, Command); + + for (i = 0; i < 32; i++) { + DelayInMicroseconds(10); + + Data = E1000_READ_REG(Mdic); + + if (Data & E1000_MDI_READY) + break; + } + } else { + + em_mii_shift_out_phy_data(Adapter, PHY_PREAMBLE, + PHY_PREAMBLE_SIZE); + + Command = ((RegAddress) | + (PhyAddress << 5) | + (PHY_OP_READ << 10) | (PHY_SOF << 12)); + + em_mii_shift_out_phy_data(Adapter, Command, 14); + + Data = (u32) em_mii_shift_in_phy_data(Adapter); + } + + ASSERT(!(Data & E1000_MDI_ERR)); + + return ((u16) Data); +} + +void em_write_phy_register(struct adapter *Adapter, + u32 RegAddress, u32 PhyAddress, u16 Data) + { + u32 i; + u32 Command = 0; + u32 MdicRegValue; + + ASSERT(RegAddress <= MAX_PHY_REG_ADDRESS); + + if (Adapter->MacType > MAC_LIVENGOOD) { + + Command = (((u32) Data) | + (RegAddress << MDI_REGADD_SHIFT) | + (PhyAddress << MDI_PHYADD_SHIFT) | + (E1000_MDI_WRITE)); + + E1000_WRITE_REG(Mdic, Command); + + for (i = 0; i < 10; i++) { + DelayInMicroseconds(10); + + MdicRegValue = E1000_READ_REG(Mdic); + + if (MdicRegValue & E1000_MDI_READY) + break; + } + + } else { + + em_mii_shift_out_phy_data(Adapter, PHY_PREAMBLE, + PHY_PREAMBLE_SIZE); + + Command = ((PHY_TURNAROUND) | + (RegAddress << 2) | + (PhyAddress << 7) | + (PHY_OP_WRITE << 12) | (PHY_SOF << 14)); + Command <<= 16; + Command |= ((u32) Data); + + em_mii_shift_out_phy_data(Adapter, Command, 32); + } + + return; +} + +static u16 em_mii_shift_in_phy_data(struct adapter *Adapter) + { + u32 CtrlRegValue; + u16 Data = 0; + u8 i; + + CtrlRegValue = E1000_READ_REG(Ctrl); + + CtrlRegValue &= ~E1000_CTRL_MDIO_DIR; + CtrlRegValue &= ~E1000_CTRL_MDIO; + + E1000_WRITE_REG(Ctrl, CtrlRegValue); + + em_raise_mdc_clock(Adapter, &CtrlRegValue); + em_lower_mdc_clock(Adapter, &CtrlRegValue); + + for (Data = 0, i = 0; i < 16; i++) { + Data = Data << 1; + em_raise_mdc_clock(Adapter, &CtrlRegValue); + + CtrlRegValue = E1000_READ_REG(Ctrl); + + if (CtrlRegValue & E1000_CTRL_MDIO) + Data |= 1; + + em_lower_mdc_clock(Adapter, &CtrlRegValue); + } + + em_raise_mdc_clock(Adapter, &CtrlRegValue); + em_lower_mdc_clock(Adapter, &CtrlRegValue); + + CtrlRegValue &= ~E1000_CTRL_MDIO; + + return (Data); +} + +static void em_mii_shift_out_phy_data(struct adapter *Adapter, + u32 Data, u16 Count) + { + u32 CtrlRegValue; + u32 Mask; + + if (Count > 32) + ASSERT(0); + + Mask = 0x01; + Mask <<= (Count - 1); + + CtrlRegValue = E1000_READ_REG(Ctrl); + + CtrlRegValue |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR); + + while (Mask) { + + if (Data & Mask) + CtrlRegValue |= E1000_CTRL_MDIO; + else + CtrlRegValue &= ~E1000_CTRL_MDIO; + + E1000_WRITE_REG(Ctrl, CtrlRegValue); + + DelayInMicroseconds(2); + + em_raise_mdc_clock(Adapter, &CtrlRegValue); + em_lower_mdc_clock(Adapter, &CtrlRegValue); + + Mask = Mask >> 1; + } + + CtrlRegValue &= ~E1000_CTRL_MDIO; +} + +static void em_raise_mdc_clock(struct adapter *Adapter, u32 * CtrlRegValue) + { + + E1000_WRITE_REG(Ctrl, (*CtrlRegValue | E1000_CTRL_MDC)); + + DelayInMicroseconds(2); +} + +static void em_lower_mdc_clock(struct adapter *Adapter, u32 * CtrlRegValue) + { + + E1000_WRITE_REG(Ctrl, (*CtrlRegValue & ~E1000_CTRL_MDC)); + + DelayInMicroseconds(2); +} + +void em_phy_hardware_reset(struct adapter *Adapter) + { + u32 ExtCtrlRegValue, CtrlRegValue; + + DEBUGFUNC("em_phy_hardware_reset") + + DEBUGOUT("Resetting Phy...\n"); + + if (Adapter->MacType > MAC_LIVENGOOD) { + + CtrlRegValue = E1000_READ_REG(Ctrl); + + CtrlRegValue |= E1000_CTRL_PHY_RST; + + E1000_WRITE_REG(Ctrl, CtrlRegValue); + + DelayInMilliseconds(20); + + CtrlRegValue &= ~E1000_CTRL_PHY_RST; + + E1000_WRITE_REG(Ctrl, CtrlRegValue); + + DelayInMilliseconds(20); + } else { + + ExtCtrlRegValue = E1000_READ_REG(Exct); + + ExtCtrlRegValue |= E1000_CTRL_PHY_RESET_DIR4; + + E1000_WRITE_REG(Exct, ExtCtrlRegValue); + + DelayInMilliseconds(20); + + ExtCtrlRegValue = E1000_READ_REG(Exct); + + ExtCtrlRegValue &= ~E1000_CTRL_PHY_RESET4; + + E1000_WRITE_REG(Exct, ExtCtrlRegValue); + + DelayInMilliseconds(20); + + ExtCtrlRegValue = E1000_READ_REG(Exct); + + ExtCtrlRegValue |= E1000_CTRL_PHY_RESET4; + + E1000_WRITE_REG(Exct, ExtCtrlRegValue); + + DelayInMilliseconds(20); + } + + return; +} + +u8 em_phy_reset(struct adapter * Adapter) + { + u16 RegData; + u16 i; + + DEBUGFUNC("em_phy_reset") + + RegData = em_read_phy_register(Adapter, + PHY_MII_CTRL_REG, + Adapter->PhyAddress); + + RegData |= MII_CR_RESET; + + em_write_phy_register(Adapter, + PHY_MII_CTRL_REG, + Adapter->PhyAddress, RegData); + + i = 0; + while ((RegData & MII_CR_RESET) && i++ < 500) { + RegData = em_read_phy_register(Adapter, + PHY_MII_CTRL_REG, + Adapter->PhyAddress); + DelayInMicroseconds(1); + } + + if (i >= 500) { + DEBUGOUT("Timeout waiting for PHY to reset.\n"); + return 0; + } + + return 1; +} + +u8 em_phy_setup(struct adapter * Adapter, u32 DeviceControlReg) + { + u16 MiiCtrlReg, MiiStatusReg; + u16 PhySpecCtrlReg; + u16 MiiAutoNegAdvertiseReg, Mii1000TCtrlReg; + u16 i, Data; + u16 AutoNegHwSetting; + u16 AutoNegFCSetting; + u8 RestartAutoNeg = 0; + u8 ForceAutoNegRestart = 0; + + DEBUGFUNC("em_phy_setup") + + ASSERT(Adapter->MacType >= MAC_LIVENGOOD); + + if (Adapter->MacType > MAC_WAINWRIGHT) { + DeviceControlReg |= (E1000_CTRL_ASDE | E1000_CTRL_SLU); + E1000_WRITE_REG(Ctrl, DeviceControlReg); + } else { + DeviceControlReg |= (E1000_CTRL_FRCSPD | + E1000_CTRL_FRCDPX | E1000_CTRL_SLU); + E1000_WRITE_REG(Ctrl, DeviceControlReg); + + if (Adapter->MacType == MAC_LIVENGOOD) + em_phy_hardware_reset(Adapter); + } + + Adapter->PhyAddress = em_auto_detect_gigabit_phy(Adapter); + + if (Adapter->PhyAddress > MAX_PHY_REG_ADDRESS) { + + DEBUGOUT + ("em_phy_setup failure, did not detect valid phy.\n"); + return (0); + } + + DEBUGOUT1("Phy ID = %x \n", Adapter->PhyId); + + MiiCtrlReg = em_read_phy_register(Adapter, + PHY_MII_CTRL_REG, + Adapter->PhyAddress); + + DEBUGOUT1("MII Ctrl Reg contents = %x\n", MiiCtrlReg); + + if (!(MiiCtrlReg & MII_CR_AUTO_NEG_EN)) + ForceAutoNegRestart = 1; + + MiiCtrlReg &= ~(MII_CR_ISOLATE); + + em_write_phy_register(Adapter, + PHY_MII_CTRL_REG, + Adapter->PhyAddress, MiiCtrlReg); + + Data = em_read_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress); + + Data |= PXN_PSCR_ASSERT_CRS_ON_TX; + + DEBUGOUT1("Paxson PSCR: %x \n", Data); + + em_write_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress, Data); + + Data = em_read_phy_register(Adapter, + PXN_EXT_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress); + + Data |= PXN_EPSCR_TX_CLK_25; + + em_write_phy_register(Adapter, + PXN_EXT_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress, Data); + + MiiAutoNegAdvertiseReg = em_read_phy_register(Adapter, + PHY_AUTONEG_ADVERTISEMENT, + Adapter->PhyAddress); + + AutoNegHwSetting = (MiiAutoNegAdvertiseReg >> 5) & 0xF; + + Mii1000TCtrlReg = em_read_phy_register(Adapter, + PHY_1000T_CTRL_REG, + Adapter->PhyAddress); + + AutoNegHwSetting |= ((Mii1000TCtrlReg & 0x0300) >> 4); + + AutoNegFCSetting = ((MiiAutoNegAdvertiseReg & 0x0C00) >> 10); + + Adapter->AutoNegAdvertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT; + + if (Adapter->AutoNegAdvertised == 0) + Adapter->AutoNegAdvertised = + AUTONEG_ADVERTISE_SPEED_DEFAULT; + + if (!ForceAutoNegRestart && Adapter->AutoNeg && + (Adapter->AutoNegAdvertised == AutoNegHwSetting) && + (Adapter->FlowControl == AutoNegFCSetting)) { + DEBUGOUT("No overrides - Reading MII Status Reg..\n"); + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + + DEBUGOUT1("MII Status Reg contents = %x\n", MiiStatusReg); + + if (MiiStatusReg & MII_SR_LINK_STATUS) { + Data = em_read_phy_register(Adapter, + PXN_PHY_SPEC_STAT_REG, + Adapter->PhyAddress); + DEBUGOUT1 + ("Paxson Phy Specific Status Reg contents = %x\n", + Data); + + if (Adapter->MacType > MAC_WAINWRIGHT) + em_configure_collision_distance(Adapter); + else + em_configure_mac_to_phy_settings(Adapter, + Data); + + em_config_flow_control_after_link_up(Adapter); + + return (1); + } + } + + PhySpecCtrlReg = em_read_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress); + + PhySpecCtrlReg &= ~PXN_PSCR_AUTO_X_MODE; + + switch (Adapter->MdiX) { + case 1: + PhySpecCtrlReg |= PXN_PSCR_MDI_MANUAL_MODE; + break; + case 2: + PhySpecCtrlReg |= PXN_PSCR_MDIX_MANUAL_MODE; + break; + case 3: + PhySpecCtrlReg |= PXN_PSCR_AUTO_X_1000T; + break; + case 0: + default: + PhySpecCtrlReg |= PXN_PSCR_AUTO_X_MODE; + break; + } + + em_write_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress, PhySpecCtrlReg); + + PhySpecCtrlReg = em_read_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress); + + PhySpecCtrlReg &= ~PXN_PSCR_POLARITY_REVERSAL; + + if (Adapter->DisablePolarityCorrection == 1) + PhySpecCtrlReg |= PXN_PSCR_POLARITY_REVERSAL; + + em_write_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress, PhySpecCtrlReg); + + if (Adapter->AutoNeg) { + DEBUGOUT + ("Livengood - Reconfiguring auto-neg advertisement params\n"); + RestartAutoNeg = + em_phy_setup_auto_neg_advertisement(Adapter); + } else { + DEBUGOUT("Livengood - Forcing speed and duplex\n"); + em_phy_force_speed_and_duplex(Adapter); + } + + if (RestartAutoNeg) { + DEBUGOUT("Restarting Auto-Neg\n"); + + MiiCtrlReg = em_read_phy_register(Adapter, + PHY_MII_CTRL_REG, + Adapter->PhyAddress); + + MiiCtrlReg |= + (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); + + em_write_phy_register(Adapter, + PHY_MII_CTRL_REG, + Adapter->PhyAddress, MiiCtrlReg); + + if (Adapter->WaitAutoNegComplete) + em_wait_for_auto_neg(Adapter); + + } + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + + DEBUGOUT1 + ("Checking for link status - MII Status Reg contents = %x\n", + MiiStatusReg); + + for (i = 0; i < 10; i++) { + if (MiiStatusReg & MII_SR_LINK_STATUS) { + break; + } + DelayInMicroseconds(10); + DEBUGOUT(". "); + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + } + + if (MiiStatusReg & MII_SR_LINK_STATUS) { + + Data = em_read_phy_register(Adapter, + PXN_PHY_SPEC_STAT_REG, + Adapter->PhyAddress); + + DEBUGOUT1("Paxson Phy Specific Status Reg contents = %x\n", + Data); + + if (Adapter->MacType > MAC_WAINWRIGHT) + em_configure_collision_distance(Adapter); + else + em_configure_mac_to_phy_settings(Adapter, Data); + + em_config_flow_control_after_link_up(Adapter); + + DEBUGOUT("Valid link established!!!\n"); + } else { + DEBUGOUT("Unable to establish link!!!\n"); + } + + return (1); +} + +u8 em_phy_setup_auto_neg_advertisement(struct adapter * Adapter) + { + u16 MiiAutoNegAdvertiseReg, Mii1000TCtrlReg; + + DEBUGFUNC("em_phy_setup_auto_neg_advertisement") + + MiiAutoNegAdvertiseReg = em_read_phy_register(Adapter, + PHY_AUTONEG_ADVERTISEMENT, + Adapter-> + PhyAddress); + + Mii1000TCtrlReg = em_read_phy_register(Adapter, + PHY_1000T_CTRL_REG, + Adapter->PhyAddress); + + MiiAutoNegAdvertiseReg &= ~REG4_SPEED_MASK; + Mii1000TCtrlReg &= ~REG9_SPEED_MASK; + + DEBUGOUT1("AutoNegAdvertised %x\n", Adapter->AutoNegAdvertised); + + if (Adapter->AutoNegAdvertised & ADVERTISE_10_HALF) { + DEBUGOUT("Advertise 10mb Half duplex\n"); + MiiAutoNegAdvertiseReg |= NWAY_AR_10T_HD_CAPS; + } + + if (Adapter->AutoNegAdvertised & ADVERTISE_10_FULL) { + DEBUGOUT("Advertise 10mb Full duplex\n"); + MiiAutoNegAdvertiseReg |= NWAY_AR_10T_FD_CAPS; + } + + if (Adapter->AutoNegAdvertised & ADVERTISE_100_HALF) { + DEBUGOUT("Advertise 100mb Half duplex\n"); + MiiAutoNegAdvertiseReg |= NWAY_AR_100TX_HD_CAPS; + } + + if (Adapter->AutoNegAdvertised & ADVERTISE_100_FULL) { + DEBUGOUT("Advertise 100mb Full duplex\n"); + MiiAutoNegAdvertiseReg |= NWAY_AR_100TX_FD_CAPS; + } + + if (Adapter->AutoNegAdvertised & ADVERTISE_1000_HALF) { + DEBUGOUT + ("Advertise 1000mb Half duplex requested, request denied!\n"); + } + + if (Adapter->AutoNegAdvertised & ADVERTISE_1000_FULL) { + DEBUGOUT("Advertise 1000mb Full duplex\n"); + Mii1000TCtrlReg |= CR_1000T_FD_CAPS; + } + + switch (Adapter->FlowControl) { + case FLOW_CONTROL_NONE: + + MiiAutoNegAdvertiseReg &= + ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); + + break; + + case FLOW_CONTROL_RECEIVE_PAUSE: + + MiiAutoNegAdvertiseReg |= + (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); + + break; + + case FLOW_CONTROL_TRANSMIT_PAUSE: + + MiiAutoNegAdvertiseReg |= NWAY_AR_ASM_DIR; + MiiAutoNegAdvertiseReg &= ~NWAY_AR_PAUSE; + + break; + + case FLOW_CONTROL_FULL: + + MiiAutoNegAdvertiseReg |= + (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); + + break; + + default: + + DEBUGOUT("Flow control param set incorrectly\n"); + ASSERT(0); + break; + } + + em_write_phy_register(Adapter, + PHY_AUTONEG_ADVERTISEMENT, + Adapter->PhyAddress, MiiAutoNegAdvertiseReg); + + DEBUGOUT1("Auto-Neg Advertising %x\n", MiiAutoNegAdvertiseReg); + + em_write_phy_register(Adapter, + PHY_1000T_CTRL_REG, + Adapter->PhyAddress, Mii1000TCtrlReg); + return (1); +} + +static void em_phy_force_speed_and_duplex(struct adapter *Adapter) + { + u16 MiiCtrlReg; + u16 MiiStatusReg; + u16 PhyData; + u16 i; + u32 TctlReg; + u32 DeviceCtrlReg; + u32 Shift32; + + DEBUGFUNC("em_phy_force_speed_and_duplex") + + Adapter->FlowControl = FLOW_CONTROL_NONE; + + DEBUGOUT1("Adapter->FlowControl = %d\n", Adapter->FlowControl); + + DeviceCtrlReg = E1000_READ_REG(Ctrl); + + DeviceCtrlReg |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); + DeviceCtrlReg &= ~(DEVICE_SPEED_MASK); + + DeviceCtrlReg &= ~E1000_CTRL_ASDE; + + MiiCtrlReg = em_read_phy_register(Adapter, + PHY_MII_CTRL_REG, + Adapter->PhyAddress); + + MiiCtrlReg &= ~MII_CR_AUTO_NEG_EN; + + if (Adapter->ForcedSpeedDuplex == FULL_100 || + Adapter->ForcedSpeedDuplex == FULL_10) { + + DeviceCtrlReg |= E1000_CTRL_FD; + MiiCtrlReg |= MII_CR_FULL_DUPLEX; + + DEBUGOUT("Full Duplex\n"); + } else { + + DeviceCtrlReg &= ~E1000_CTRL_FD; + MiiCtrlReg &= ~MII_CR_FULL_DUPLEX; + + DEBUGOUT("Half Duplex\n"); + } + + if (Adapter->ForcedSpeedDuplex == FULL_100 || + Adapter->ForcedSpeedDuplex == HALF_100) { + + DeviceCtrlReg |= E1000_CTRL_SPD_100; + MiiCtrlReg |= MII_CR_SPEED_100; + MiiCtrlReg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10); + + DEBUGOUT("Forcing 100mb "); + } else { + + DeviceCtrlReg &= + ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); + MiiCtrlReg |= MII_CR_SPEED_10; + MiiCtrlReg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100); + + DEBUGOUT("Forcing 10mb "); + } + + TctlReg = E1000_READ_REG(Tctl); + DEBUGOUT1("TctlReg = %x\n", TctlReg); + + if (!(MiiCtrlReg & MII_CR_FULL_DUPLEX)) { + + TctlReg &= ~E1000_TCTL_COLD; + Shift32 = E1000_HDX_COLLISION_DISTANCE; + Shift32 <<= E1000_COLD_SHIFT; + TctlReg |= Shift32; + } else { + + TctlReg &= ~E1000_TCTL_COLD; + Shift32 = E1000_FDX_COLLISION_DISTANCE; + Shift32 <<= E1000_COLD_SHIFT; + TctlReg |= Shift32; + } + + E1000_WRITE_REG(Tctl, TctlReg); + + E1000_WRITE_REG(Ctrl, DeviceCtrlReg); + + PhyData = em_read_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress); + + PhyData &= ~PXN_PSCR_AUTO_X_MODE; + + em_write_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress, PhyData); + + DEBUGOUT1("Paxson PSCR: %x \n", PhyData); + + MiiCtrlReg |= MII_CR_RESET; + + em_write_phy_register(Adapter, + PHY_MII_CTRL_REG, + Adapter->PhyAddress, MiiCtrlReg); + + if (Adapter->WaitAutoNegComplete) { + + DEBUGOUT("Waiting for forced speed/duplex link.\n"); + MiiStatusReg = 0; + +#define PHY_WAIT_FOR_FORCED_TIME 20 + + for (i = 20; i > 0; i--) { + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter-> + PhyAddress); + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter-> + PhyAddress); + + if (MiiStatusReg & MII_SR_LINK_STATUS) { + break; + } + DelayInMilliseconds(100); + } + + if (i == 0) { + + em_pxn_phy_reset_dsp(Adapter); + } + + for (i = 20; i > 0; i--) { + if (MiiStatusReg & MII_SR_LINK_STATUS) { + break; + } + + DelayInMilliseconds(100); + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter-> + PhyAddress); + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter-> + PhyAddress); + + } + } + + PhyData = em_read_phy_register(Adapter, + PXN_EXT_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress); + + PhyData |= PXN_EPSCR_TX_CLK_25; + + em_write_phy_register(Adapter, + PXN_EXT_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress, PhyData); + + PhyData = em_read_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress); + + PhyData |= PXN_PSCR_ASSERT_CRS_ON_TX; + + em_write_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress, PhyData); + DEBUGOUT1("After force, Paxson Phy Specific Ctrl Reg = %4x\r\n", + PhyData); + + return; +} + +void em_configure_mac_to_phy_settings(struct adapter *Adapter, + u16 MiiRegisterData) + { + u32 DeviceCtrlReg, TctlReg; + u32 Shift32; + + DEBUGFUNC("em_configure_mac_to_phy_settings") + + TctlReg = E1000_READ_REG(Tctl); + DEBUGOUT1("TctlReg = %x\n", TctlReg); + + DeviceCtrlReg = E1000_READ_REG(Ctrl); + + DeviceCtrlReg |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); + DeviceCtrlReg &= ~(DEVICE_SPEED_MASK); + + DEBUGOUT1("MII Register Data = %x\r\n", MiiRegisterData); + + DeviceCtrlReg &= ~E1000_CTRL_ILOS; + + if (MiiRegisterData & PXN_PSSR_DPLX) { + DeviceCtrlReg |= E1000_CTRL_FD; + + TctlReg &= ~E1000_TCTL_COLD; + Shift32 = E1000_FDX_COLLISION_DISTANCE; + Shift32 <<= E1000_COLD_SHIFT; + TctlReg |= Shift32; + } else { + DeviceCtrlReg &= ~E1000_CTRL_FD; + + if ((MiiRegisterData & PXN_PSSR_SPEED) == PXN_PSSR_1000MBS) { + TctlReg &= ~E1000_TCTL_COLD; + Shift32 = E1000_GB_HDX_COLLISION_DISTANCE; + Shift32 <<= E1000_COLD_SHIFT; + TctlReg |= Shift32; + + TctlReg |= E1000_TCTL_PBE; + + } else { + TctlReg &= ~E1000_TCTL_COLD; + Shift32 = E1000_HDX_COLLISION_DISTANCE; + Shift32 <<= E1000_COLD_SHIFT; + TctlReg |= Shift32; + } + } + + if ((MiiRegisterData & PXN_PSSR_SPEED) == PXN_PSSR_1000MBS) + DeviceCtrlReg |= E1000_CTRL_SPD_1000; + else if ((MiiRegisterData & PXN_PSSR_SPEED) == PXN_PSSR_100MBS) + DeviceCtrlReg |= E1000_CTRL_SPD_100; + else + DeviceCtrlReg &= + ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); + + E1000_WRITE_REG(Tctl, TctlReg); + + E1000_WRITE_REG(Ctrl, DeviceCtrlReg); + + return; +} + +void em_configure_collision_distance(struct adapter *Adapter) + { + u32 TctlReg; + u16 Speed; + u16 Duplex; + u32 Shift32; + + DEBUGFUNC("em_configure_collision_distance") + + em_get_speed_and_duplex(Adapter, &Speed, &Duplex); + + TctlReg = E1000_READ_REG(Tctl); + DEBUGOUT1("TctlReg = %x\n", TctlReg); + + TctlReg &= ~E1000_TCTL_COLD; + + if (Duplex == FULL_DUPLEX) { + + Shift32 = E1000_FDX_COLLISION_DISTANCE; + Shift32 <<= E1000_COLD_SHIFT; + TctlReg |= Shift32; + } else { + + if (Speed == SPEED_1000) { + Shift32 = E1000_GB_HDX_COLLISION_DISTANCE; + Shift32 <<= E1000_COLD_SHIFT; + TctlReg |= Shift32; + + TctlReg |= E1000_TCTL_PBE; + + } else { + Shift32 = E1000_HDX_COLLISION_DISTANCE; + Shift32 <<= E1000_COLD_SHIFT; + TctlReg |= Shift32; + } + } + + E1000_WRITE_REG(Tctl, TctlReg); + + return; +} + +void em_display_mii_contents(struct adapter *Adapter, u8 PhyAddress) + { + u16 Data, PhyIDHi, PhyIDLo; + u32 PhyID; + + DEBUGFUNC("em_display_mii_contents") + + DEBUGOUT1("Adapter Base Address = %x\n", + Adapter->HardwareVirtualAddress); + + Data = em_read_phy_register(Adapter, PHY_MII_CTRL_REG, PhyAddress); + + DEBUGOUT1("MII Ctrl Reg contents = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, PhyAddress); + + Data = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, PhyAddress); + + DEBUGOUT1("MII Status Reg contents = %x\n", Data); + + PhyIDHi = em_read_phy_register(Adapter, + PHY_PHY_ID_REG1, PhyAddress); + + DelayInMicroseconds(2); + + PhyIDLo = em_read_phy_register(Adapter, + PHY_PHY_ID_REG2, PhyAddress); + + PhyID = (PhyIDLo | (PhyIDHi << 16)) & PHY_REVISION_MASK; + + DEBUGOUT1("Phy ID = %x \n", PhyID); + + Data = em_read_phy_register(Adapter, + PHY_AUTONEG_ADVERTISEMENT, PhyAddress); + + DEBUGOUT1("Reg 4 contents = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PHY_AUTONEG_LP_BPA, PhyAddress); + + DEBUGOUT1("Reg 5 contents = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PHY_AUTONEG_EXPANSION_REG, PhyAddress); + + DEBUGOUT1("Reg 6 contents = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PHY_AUTONEG_NEXT_PAGE_TX, PhyAddress); + + DEBUGOUT1("Reg 7 contents = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PHY_AUTONEG_LP_RX_NEXT_PAGE, + PhyAddress); + + DEBUGOUT1("Reg 8 contents = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PHY_1000T_CTRL_REG, PhyAddress); + + DEBUGOUT1("Reg 9 contents = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PHY_1000T_STATUS_REG, PhyAddress); + + DEBUGOUT1("Reg A contents = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PHY_IEEE_EXT_STATUS_REG, PhyAddress); + + DEBUGOUT1("Reg F contents = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, PhyAddress); + + DEBUGOUT1("Paxson Specific Control Reg (0x10) = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PXN_PHY_SPEC_STAT_REG, PhyAddress); + + DEBUGOUT1("Paxson Specific Status Reg (0x11) = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PXN_INT_ENABLE_REG, PhyAddress); + + DEBUGOUT1("Paxson Interrupt Enable Reg (0x12) = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PXN_INT_STATUS_REG, PhyAddress); + + DEBUGOUT1("Paxson Interrupt Status Reg (0x13) = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PXN_EXT_PHY_SPEC_CTRL_REG, PhyAddress); + + DEBUGOUT1("Paxson Ext. Phy Specific Control (0x14) = %x\n", Data); + + Data = em_read_phy_register(Adapter, + PXN_RX_ERROR_COUNTER, PhyAddress); + + DEBUGOUT1("Paxson Receive Error Counter (0x15) = %x\n", Data); + + Data = em_read_phy_register(Adapter, PXN_LED_CTRL_REG, PhyAddress); + + DEBUGOUT1("Paxson LED control reg (0x18) = %x\n", Data); +} + +u32 em_auto_detect_gigabit_phy(struct adapter *Adapter) +{ + u32 PhyAddress = 1; + u32 PhyIDHi; + u16 PhyIDLo; + u8 GotOne = 0; + + DEBUGFUNC("em_auto_detect_gigabit_phy") + + while ((!GotOne) && (PhyAddress <= MAX_PHY_REG_ADDRESS)) { + + PhyIDHi = em_read_phy_register(Adapter, + PHY_PHY_ID_REG1, + PhyAddress); + + DelayInMicroseconds(2); + + PhyIDLo = em_read_phy_register(Adapter, + PHY_PHY_ID_REG2, + PhyAddress); + + Adapter->PhyId = + (PhyIDLo | (PhyIDHi << 16)) & PHY_REVISION_MASK; + + if (Adapter->PhyId == PAXSON_PHY_88E1000 || + Adapter->PhyId == PAXSON_PHY_88E1000S || + Adapter->PhyId == PAXSON_PHY_INTEGRATED) { + DEBUGOUT2("PhyId 0x%x detected at address 0x%x\n", + Adapter->PhyId, PhyAddress); + + GotOne = 1; + } else { + PhyAddress++; + } + + } + + if (PhyAddress > MAX_PHY_REG_ADDRESS) { + DEBUGOUT("Could not auto-detect Phy!\n"); + } + + return (PhyAddress); +} + +void em_pxn_phy_reset_dsp(struct adapter *Adapter) +{ + em_write_phy_register(Adapter, 29, Adapter->PhyAddress, 0x1d); + em_write_phy_register(Adapter, 30, Adapter->PhyAddress, 0xc1); + em_write_phy_register(Adapter, 30, Adapter->PhyAddress, 0x00); +} + +u8 em_wait_for_auto_neg(struct adapter *Adapter) +{ + u8 AutoNegComplete = 0; + u16 i; + u16 MiiStatusReg; + + DEBUGFUNC("em_wait_for_auto_neg"); + + DEBUGOUT("Waiting for Auto-Neg to complete.\n"); + MiiStatusReg = 0; + + for (i = PHY_AUTO_NEG_TIME; i > 0; i--) { + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + + MiiStatusReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + + if (MiiStatusReg & MII_SR_AUTONEG_COMPLETE) { + AutoNegComplete = 1; + break; + } + + DelayInMilliseconds(100); + } + + return (AutoNegComplete); +} + +u8 em_phy_get_status_info(struct adapter * Adapter, + phy_status_info_struct * PhyStatusInfo) +{ + u16 PhyMIIStatReg; + u16 PhySpecCtrlReg; + u16 PhySpecStatReg; + u16 PhyExtSpecCtrlReg; + u16 Phy1000BTStatReg; + + PhyStatusInfo->CableLength = PXN_PSSR_CABLE_LENGTH_UNDEFINED; + PhyStatusInfo->Extended10BTDistance = + PXN_PSCR_10BT_EXT_DIST_ENABLE_UNDEFINED; + PhyStatusInfo->CablePolarity = PXN_PSSR_REV_POLARITY_UNDEFINED; + PhyStatusInfo->PolarityCorrection = + PXN_PSCR_POLARITY_REVERSAL_UNDEFINED; + PhyStatusInfo->LinkReset = PXN_EPSCR_DOWN_NO_IDLE_UNDEFINED; + PhyStatusInfo->MDIXMode = PXN_PSCR_AUTO_X_MODE_UNDEFINED; + PhyStatusInfo->LocalRx = SR_1000T_RX_STATUS_UNDEFINED; + PhyStatusInfo->RemoteRx = SR_1000T_RX_STATUS_UNDEFINED; + + if (Adapter == NULL || Adapter->MediaType != MEDIA_TYPE_COPPER) + return 0; + + PhyMIIStatReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + PhyMIIStatReg = em_read_phy_register(Adapter, + PHY_MII_STATUS_REG, + Adapter->PhyAddress); + if ((PhyMIIStatReg & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) + return 0; + + PhySpecCtrlReg = em_read_phy_register(Adapter, + PXN_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress); + PhySpecStatReg = em_read_phy_register(Adapter, + PXN_PHY_SPEC_STAT_REG, + Adapter->PhyAddress); + PhyExtSpecCtrlReg = em_read_phy_register(Adapter, + PXN_EXT_PHY_SPEC_CTRL_REG, + Adapter->PhyAddress); + Phy1000BTStatReg = em_read_phy_register(Adapter, + PHY_1000T_STATUS_REG, + Adapter->PhyAddress); + + PhyStatusInfo->CableLength = (PXN_PSSR_CABLE_LENGTH_ENUM) + ((PhySpecStatReg & PXN_PSSR_CABLE_LENGTH) >> + PXN_PSSR_CABLE_LENGTH_SHIFT); + + PhyStatusInfo->Extended10BTDistance = + (PXN_PSCR_10BT_EXT_DIST_ENABLE_ENUM) (PhySpecCtrlReg & + PXN_PSCR_10BT_EXT_DIST_ENABLE) + >> PXN_PSCR_10BT_EXT_DIST_ENABLE_SHIFT; + + PhyStatusInfo->CablePolarity = (PXN_PSSR_REV_POLARITY_ENUM) + (PhySpecStatReg & PXN_PSSR_REV_POLARITY) >> + PXN_PSSR_REV_POLARITY_SHIFT; + + PhyStatusInfo->PolarityCorrection = + (PXN_PSCR_POLARITY_REVERSAL_ENUM) (PhySpecCtrlReg & + PXN_PSCR_POLARITY_REVERSAL) + >> PXN_PSCR_POLARITY_REVERSAL_SHIFT; + + PhyStatusInfo->LinkReset = (PXN_EPSCR_DOWN_NO_IDLE_ENUM) + (PhyExtSpecCtrlReg & PXN_EPSCR_DOWN_NO_IDLE) >> + PXN_EPSCR_DOWN_NO_IDLE_SHIFT; + + PhyStatusInfo->MDIXMode = (PXN_PSCR_AUTO_X_MODE_ENUM) + (PhySpecCtrlReg & PXN_PSCR_AUTO_X_MODE) >> + PXN_PSCR_AUTO_X_MODE_SHIFT; + + PhyStatusInfo->LocalRx = (SR_1000T_RX_STATUS_ENUM) + (Phy1000BTStatReg & SR_1000T_LOCAL_RX_STATUS) >> + SR_1000T_LOCAL_RX_STATUS_SHIFT; + + PhyStatusInfo->RemoteRx = (SR_1000T_RX_STATUS_ENUM) + (Phy1000BTStatReg & SR_1000T_REMOTE_RX_STATUS) >> + SR_1000T_REMOTE_RX_STATUS_SHIFT; + + return 1; +} diff --git a/sys/dev/em/if_em_phy.h b/sys/dev/em/if_em_phy.h new file mode 100644 index 000000000000..737f3b17bb6e --- /dev/null +++ b/sys/dev/em/if_em_phy.h @@ -0,0 +1,418 @@ +/************************************************************************* +************************************************************************** +Copyright (c) 2001 Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms of the Software, with or +without modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code of the Software may retain the above + copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form of the Software may 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 shall 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 INTEL OR ITS CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +$FreeBSD$ +*************************************************************************** +**************************************************************************/ + +#ifndef _EM_PHY_H_ +#define _EM_PHY_H_ + +/* +* Workfile: phy.h +* Date: 9/25/01 2:40p +* Revision: 9 +*/ + +#define _PHY_ + +#include <dev/em/if_em_osdep.h> + +typedef enum { + PXN_PSSR_CABLE_LENGTH_50 = 0, + PXN_PSSR_CABLE_LENGTH_50_80, + PXN_PSSR_CABLE_LENGTH_80_110, + PXN_PSSR_CABLE_LENGTH_110_140, + PXN_PSSR_CABLE_LENGTH_140, + PXN_PSSR_CABLE_LENGTH_UNDEFINED = 0xFF +} PXN_PSSR_CABLE_LENGTH_ENUM; + +typedef enum { + PXN_PSCR_10BT_EXT_DIST_ENABLE_NORMAL = 0, + PXN_PSCR_10BT_EXT_DIST_ENABLE_LOWER, + PXN_PSCR_10BT_EXT_DIST_ENABLE_UNDEFINED = 0xFF +} PXN_PSCR_10BT_EXT_DIST_ENABLE_ENUM; + +typedef enum { + PXN_PSSR_REV_POLARITY_NORMAL = 0, + PXN_PSSR_REV_POLARITY_REVERSED, + PXN_PSSR_REV_POLARITY_UNDEFINED = 0xFF +} PXN_PSSR_REV_POLARITY_ENUM; + +typedef enum { + PXN_PSCR_POLARITY_REVERSAL_ENABLED = 0, + PXN_PSCR_POLARITY_REVERSAL_DISABLED, + PXN_PSCR_POLARITY_REVERSAL_UNDEFINED = 0xFF +} PXN_PSCR_POLARITY_REVERSAL_ENUM; + +typedef enum { + PXN_EPSCR_DOWN_NO_IDLE_NO_DETECT = 0, + PXN_EPSCR_DOWN_NO_IDLE_DETECT, + PXN_EPSCR_DOWN_NO_IDLE_UNDEFINED = 0xFF +} PXN_EPSCR_DOWN_NO_IDLE_ENUM; + +typedef enum { + PXN_PSCR_AUTO_X_MODE_MANUAL_MDI = 0, + PXN_PSCR_AUTO_X_MODE_MANUAL_MDIX, + PXN_PSCR_AUTO_X_MODE_AUTO_1, + PXN_PSCR_AUTO_X_MODE_AUTO_2, + PXN_PSCR_AUTO_X_MODE_UNDEFINED = 0xFF +} PXN_PSCR_AUTO_X_MODE_ENUM; + +typedef enum { + SR_1000T_RX_STATUS_NOT_OK = 0, + SR_1000T_RX_STATUS_OK, + SR_1000T_RX_STATUS_UNDEFINED = 0xFF +} SR_1000T_RX_STATUS_ENUM; + +typedef struct { + PXN_PSSR_CABLE_LENGTH_ENUM CableLength; + PXN_PSCR_10BT_EXT_DIST_ENABLE_ENUM Extended10BTDistance; + PXN_PSSR_REV_POLARITY_ENUM CablePolarity; + PXN_PSCR_POLARITY_REVERSAL_ENUM PolarityCorrection; + PXN_EPSCR_DOWN_NO_IDLE_ENUM LinkReset; + PXN_PSCR_AUTO_X_MODE_ENUM MDIXMode; + SR_1000T_RX_STATUS_ENUM LocalRx; + SR_1000T_RX_STATUS_ENUM RemoteRx; +} phy_status_info_struct; + +u16 em_read_phy_register(struct adapter *Adapter, + + u32 RegAddress, u32 PhyAddress); +void em_write_phy_register(struct adapter *Adapter, + u32 RegAddress, u32 PhyAddress, u16 Data); +void em_phy_hardware_reset(struct adapter *Adapter); +u8 em_phy_reset(struct adapter *Adapter); +u8 em_phy_setup(struct adapter *Adapter, u32 DeviceControlReg); +void em_configure_mac_to_phy_settings(struct adapter *Adapter, + + u16 MiiRegisterData); +void em_configure_collision_distance(struct adapter *Adapter); +void em_display_mii_contents(struct adapter *Adapter, u8 PhyAddress); +u32 em_auto_detect_gigabit_phy(struct adapter *Adapter); +void em_pxn_phy_reset_dsp(struct adapter *Adapter); +void PxnIntegratedPhyLoopback(struct adapter *Adapter, u16 Speed); +void PxnPhyEnableReceiver(struct adapter *Adapter); +void PxnPhyDisableReceiver(struct adapter *Adapter); +u8 em_wait_for_auto_neg(struct adapter *Adapter); +u8 em_phy_get_status_info(struct adapter *Adapter, + + phy_status_info_struct * PhyStatusInfo); + +#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_EXCTRL_SWDPIO4 +#define E1000_CTRL_PHY_RESET4 E1000_EXCTRL_SWDPIN4 + +#define PHY_MII_CTRL_REG 0x00 +#define PHY_MII_STATUS_REG 0x01 +#define PHY_PHY_ID_REG1 0x02 +#define PHY_PHY_ID_REG2 0x03 +#define PHY_AUTONEG_ADVERTISEMENT 0x04 +#define PHY_AUTONEG_LP_BPA 0x05 +#define PHY_AUTONEG_EXPANSION_REG 0x06 +#define PHY_AUTONEG_NEXT_PAGE_TX 0x07 +#define PHY_AUTONEG_LP_RX_NEXT_PAGE 0x08 +#define PHY_1000T_CTRL_REG 0x09 +#define PHY_1000T_STATUS_REG 0x0A +#define PHY_IEEE_EXT_STATUS_REG 0x0F + +#define PXN_PHY_SPEC_CTRL_REG 0x10 +#define PXN_PHY_SPEC_STAT_REG 0x11 +#define PXN_INT_ENABLE_REG 0x12 +#define PXN_INT_STATUS_REG 0x13 +#define PXN_EXT_PHY_SPEC_CTRL_REG 0x14 +#define PXN_RX_ERROR_COUNTER 0x15 +#define PXN_LED_CTRL_REG 0x18 + +#define MAX_PHY_REG_ADDRESS 0x1F + +#define MII_CR_SPEED_SELECT_MSB 0x0040 +#define MII_CR_COLL_TEST_ENABLE 0x0080 +#define MII_CR_FULL_DUPLEX 0x0100 +#define MII_CR_RESTART_AUTO_NEG 0x0200 +#define MII_CR_ISOLATE 0x0400 +#define MII_CR_POWER_DOWN 0x0800 +#define MII_CR_AUTO_NEG_EN 0x1000 +#define MII_CR_SPEED_SELECT_LSB 0x2000 +#define MII_CR_LOOPBACK 0x4000 +#define MII_CR_RESET 0x8000 + +#define MII_SR_EXTENDED_CAPS 0x0001 +#define MII_SR_JABBER_DETECT 0x0002 +#define MII_SR_LINK_STATUS 0x0004 +#define MII_SR_AUTONEG_CAPS 0x0008 +#define MII_SR_REMOTE_FAULT 0x0010 +#define MII_SR_AUTONEG_COMPLETE 0x0020 +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 +#define MII_SR_EXTENDED_STATUS 0x0100 +#define MII_SR_100T2_HD_CAPS 0x0200 +#define MII_SR_100T2_FD_CAPS 0x0400 +#define MII_SR_10T_HD_CAPS 0x0800 +#define MII_SR_10T_FD_CAPS 0x1000 +#define MII_SR_100X_HD_CAPS 0x2000 +#define MII_SR_100X_FD_CAPS 0x4000 +#define MII_SR_100T4_CAPS 0x8000 + +#define NWAY_AR_SELECTOR_FIELD 0x0001 +#define NWAY_AR_10T_HD_CAPS 0x0020 +#define NWAY_AR_10T_FD_CAPS 0x0040 +#define NWAY_AR_100TX_HD_CAPS 0x0080 +#define NWAY_AR_100TX_FD_CAPS 0x0100 +#define NWAY_AR_100T4_CAPS 0x0200 +#define NWAY_AR_PAUSE 0x0400 +#define NWAY_AR_ASM_DIR 0x0800 +#define NWAY_AR_REMOTE_FAULT 0x2000 +#define NWAY_AR_NEXT_PAGE 0x8000 + +#define NWAY_LPAR_SELECTOR_FIELD 0x0000 +#define NWAY_LPAR_10T_HD_CAPS 0x0020 +#define NWAY_LPAR_10T_FD_CAPS 0x0040 +#define NWAY_LPAR_100TX_HD_CAPS 0x0080 +#define NWAY_LPAR_100TX_FD_CAPS 0x0100 +#define NWAY_LPAR_100T4_CAPS 0x0200 +#define NWAY_LPAR_PAUSE 0x0400 +#define NWAY_LPAR_ASM_DIR 0x0800 +#define NWAY_LPAR_REMOTE_FAULT 0x2000 +#define NWAY_LPAR_ACKNOWLEDGE 0x4000 +#define NWAY_LPAR_NEXT_PAGE 0x8000 + +#define NWAY_ER_LP_NWAY_CAPS 0x0001 +#define NWAY_ER_PAGE_RXD 0x0002 +#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 +#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 +#define NWAY_ER_PAR_DETECT_FAULT 0x0100 + +#define NPTX_MSG_CODE_FIELD 0x0001 +#define NPTX_TOGGLE 0x0800 + +#define NPTX_ACKNOWLDGE2 0x1000 + +#define NPTX_MSG_PAGE 0x2000 +#define NPTX_NEXT_PAGE 0x8000 + +#define LP_RNPR_MSG_CODE_FIELD 0x0001 +#define LP_RNPR_TOGGLE 0x0800 + +#define LP_RNPR_ACKNOWLDGE2 0x1000 + +#define LP_RNPR_MSG_PAGE 0x2000 +#define LP_RNPR_ACKNOWLDGE 0x4000 +#define LP_RNPR_NEXT_PAGE 0x8000 + +#define CR_1000T_ASYM_PAUSE 0x0080 +#define CR_1000T_HD_CAPS 0x0100 + +#define CR_1000T_FD_CAPS 0x0200 + +#define CR_1000T_REPEATER_DTE 0x0400 + +#define CR_1000T_MS_VALUE 0x0800 + +#define CR_1000T_MS_ENABLE 0x1000 + +#define CR_1000T_TEST_MODE_NORMAL 0x0000 +#define CR_1000T_TEST_MODE_1 0x2000 +#define CR_1000T_TEST_MODE_2 0x4000 +#define CR_1000T_TEST_MODE_3 0x6000 +#define CR_1000T_TEST_MODE_4 0x8000 + +#define SR_1000T_IDLE_ERROR_CNT 0x00FF +#define SR_1000T_ASYM_PAUSE_DIR 0x0100 +#define SR_1000T_LP_HD_CAPS 0x0400 + +#define SR_1000T_LP_FD_CAPS 0x0800 + +#define SR_1000T_REMOTE_RX_STATUS 0x1000 +#define SR_1000T_LOCAL_RX_STATUS 0x2000 +#define SR_1000T_MS_CONFIG_RES 0x4000 +#define SR_1000T_MS_CONFIG_FAULT 0x8000 + +#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12 +#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13 + +#define IEEE_ESR_1000T_HD_CAPS 0x1000 + +#define IEEE_ESR_1000T_FD_CAPS 0x2000 + +#define IEEE_ESR_1000X_HD_CAPS 0x4000 + +#define IEEE_ESR_1000X_FD_CAPS 0x8000 + +#define PHY_TX_POLARITY_MASK 0x0100 +#define PHY_TX_NORMAL_POLARITY 0 + +#define AUTO_POLARITY_DISABLE 0x0010 + +#define PXN_PSCR_JABBER_DISABLE 0x0001 +#define PXN_PSCR_POLARITY_REVERSAL 0x0002 +#define PXN_PSCR_SQE_TEST 0x0004 +#define PXN_PSCR_INT_FIFO_DISABLE 0x0008 + +#define PXN_PSCR_CLK125_DISABLE 0x0010 +#define PXN_PSCR_MDI_MANUAL_MODE 0x0000 + +#define PXN_PSCR_MDIX_MANUAL_MODE 0x0020 +#define PXN_PSCR_AUTO_X_1000T 0x0040 +#define PXN_PSCR_AUTO_X_MODE 0x0060 +#define PXN_PSCR_10BT_EXT_DIST_ENABLE 0x0080 +#define PXN_PSCR_MII_5BIT_ENABLE 0x0100 +#define PXN_PSCR_SCRAMBLER_DISABLE 0x0200 +#define PXN_PSCR_FORCE_LINK_GOOD 0x0400 +#define PXN_PSCR_ASSERT_CRS_ON_TX 0x0800 +#define PXN_PSCR_RX_FIFO_DEPTH_6 0x0000 +#define PXN_PSCR_RX_FIFO_DEPTH_8 0x1000 +#define PXN_PSCR_RX_FIFO_DEPTH_10 0x2000 +#define PXN_PSCR_RX_FIFO_DEPTH_12 0x3000 + +#define PXN_PSCR_TXFR_FIFO_DEPTH_6 0x0000 +#define PXN_PSCR_TXFR_FIFO_DEPTH_8 0x4000 +#define PXN_PSCR_TXFR_FIFO_DEPTH_10 0x8000 +#define PXN_PSCR_TXFR_FIFO_DEPTH_12 0xC000 + +#define PXN_PSCR_POLARITY_REVERSAL_SHIFT 1 +#define PXN_PSCR_AUTO_X_MODE_SHIFT 5 +#define PXN_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7 + +#define PXN_PSSR_JABBER 0x0001 +#define PXN_PSSR_REV_POLARITY 0x0002 +#define PXN_PSSR_MDIX 0x0040 +#define PXN_PSSR_CABLE_LENGTH 0x0380 +#define PXN_PSSR_LINK 0x0400 +#define PXN_PSSR_SPD_DPLX_RESOLVED 0x0800 +#define PXN_PSSR_PAGE_RCVD 0x1000 +#define PXN_PSSR_DPLX 0x2000 +#define PXN_PSSR_SPEED 0xC000 +#define PXN_PSSR_10MBS 0x0000 +#define PXN_PSSR_100MBS 0x4000 +#define PXN_PSSR_1000MBS 0x8000 + +#define PXN_PSSR_REV_POLARITY_SHIFT 1 +#define PXN_PSSR_CABLE_LENGTH_SHIFT 7 + +#define PXN_IER_JABBER 0x0001 +#define PXN_IER_POLARITY_CHANGE 0x0002 +#define PXN_IER_MDIX_CHANGE 0x0040 +#define PXN_IER_FIFO_OVER_UNDERUN 0x0080 +#define PXN_IER_FALSE_CARRIER 0x0100 +#define PXN_IER_SYMBOL_ERROR 0x0200 +#define PXN_IER_LINK_STAT_CHANGE 0x0400 +#define PXN_IER_AUTO_NEG_COMPLETE 0x0800 +#define PXN_IER_PAGE_RECEIVED 0x1000 +#define PXN_IER_DUPLEX_CHANGED 0x2000 +#define PXN_IER_SPEED_CHANGED 0x4000 +#define PXN_IER_AUTO_NEG_ERR 0x8000 + +#define PXN_ISR_JABBER 0x0001 +#define PXN_ISR_POLARITY_CHANGE 0x0002 +#define PXN_ISR_MDIX_CHANGE 0x0040 +#define PXN_ISR_FIFO_OVER_UNDERUN 0x0080 +#define PXN_ISR_FALSE_CARRIER 0x0100 +#define PXN_ISR_SYMBOL_ERROR 0x0200 +#define PXN_ISR_LINK_STAT_CHANGE 0x0400 +#define PXN_ISR_AUTO_NEG_COMPLETE 0x0800 +#define PXN_ISR_PAGE_RECEIVED 0x1000 +#define PXN_ISR_DUPLEX_CHANGED 0x2000 +#define PXN_ISR_SPEED_CHANGED 0x4000 +#define PXN_ISR_AUTO_NEG_ERR 0x8000 + +#define PXN_EPSCR_FIBER_LOOPBACK 0x4000 +#define PXN_EPSCR_DOWN_NO_IDLE 0x8000 + +#define PXN_EPSCR_TX_CLK_2_5 0x0060 +#define PXN_EPSCR_TX_CLK_25 0x0070 +#define PXN_EPSCR_TX_CLK_0 0x0000 + +#define PXN_EPSCR_DOWN_NO_IDLE_SHIFT 15 + +#define PXN_LCR_LED_TX 0x0001 +#define PXN_LCR_LED_RX 0x0002 +#define PXN_LCR_LED_DUPLEX 0x0004 +#define PXN_LCR_LINK 0x0008 +#define PXN_LCR_BLINK_RATE_42MS 0x0000 +#define PXN_LCR_BLINK_RATE_84MS 0x0100 +#define PXN_LCR_BLINK_RATE_170MS 0x0200 +#define PXN_LCR_BLINK_RATE_340MS 0x0300 +#define PXN_LCR_BLINK_RATE_670MS 0x0400 + +#define PXN_LCR_PULSE_STRETCH_OFF 0x0000 +#define PXN_LCR_PULSE_STRETCH_21_42MS 0x1000 +#define PXN_LCR_PULSE_STRETCH_42_84MS 0x2000 +#define PXN_LCR_PULSE_STRETCH_84_170MS 0x3000 +#define PXN_LCR_PULSE_STRETCH_170_340MS 0x4000 +#define PXN_LCR_PULSE_STRETCH_340_670MS 0x5000 +#define PXN_LCR_PULSE_STRETCH_670_13S 0x6000 +#define PXN_LCR_PULSE_STRETCH_13_26S 0x7000 + +#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 E1000_10MB_PHY_ADDRESS 0x02 + +#define PHY_AUTO_NEG_TIME 45 + +#define PAXSON_PHY_88E1000 0x01410C50 +#define PAXSON_PHY_88E1000S 0x01410C40 +#define PAXSON_PHY_INTEGRATED 0x01410C30 + +#define PHY_REVISION_MASK 0xFFFFFFF0 +#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F + +#define DEVICE_SPEED_MASK 0x00000300 + +#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 + +#endif /* _EM_PHY_H_ */ + |
