diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2005-07-02 06:15:45 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2005-07-02 06:15:45 +0000 |
commit | b2ef76cc19eb3be670c62f26e8e78c3efcf5f5f0 (patch) | |
tree | 56f1ce5a8a15d6fd9dcadc184565b6bfdb352f86 /sys/dev/pci | |
parent | 209b6ce6ddc4b3c6444133acbbd0a11e6340ab53 (diff) |
sync
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_em.c | 36 | ||||
-rw-r--r-- | sys/dev/pci/if_em.h | 9 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.c | 2327 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.h | 595 | ||||
-rw-r--r-- | sys/dev/pci/if_em_osdep.h | 80 | ||||
-rw-r--r-- | sys/dev/pci/pcidevs.h | 28 | ||||
-rw-r--r-- | sys/dev/pci/pcidevs_data.h | 28 |
7 files changed, 2522 insertions, 581 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c index 10a5f5daef6..fc830c275a8 100644 --- a/sys/dev/pci/if_em.c +++ b/sys/dev/pci/if_em.c @@ -31,8 +31,8 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ +/* $OpenBSD: if_em.c,v 1.59 2005/07/02 06:15:44 deraadt Exp $ */ /* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */ -/* $OpenBSD: if_em.c,v 1.58 2005/06/14 03:27:58 brad Exp $ */ #include "bpfilter.h" #include "vlan.h" @@ -93,7 +93,7 @@ struct em_softc *em_adapter_list = NULL; * Driver version *********************************************************************/ -char em_driver_version[] = "1.7.35"; +char em_driver_version[] = "2.1.7"; /********************************************************************* * PCI Device ID Table @@ -134,6 +134,8 @@ const struct pci_matchid em_devices[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82547EI }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82547EI_MOBILE }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82547GI }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82573E }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82573E_IAMT }, }; /********************************************************************* @@ -310,8 +312,13 @@ em_attach(struct device *parent, struct device *self, void *aux) * Set the max frame size assuming standard ethernet * sized frames */ - sc->hw.max_frame_size = - ETHER_MAX_LEN_JUMBO; + if (sc->hw.mac_type == em_82573) { + sc->hw.max_frame_size = + ETHER_MAX_LEN; + } else { + sc->hw.max_frame_size = + MAX_JUMBO_FRAME_SIZE; + } sc->hw.min_frame_size = ETHER_MIN_LEN + ETHER_CRC_LEN; @@ -545,7 +552,9 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; case SIOCSIFMTU: IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)"); - if (ifr->ifr_mtu > MAX_JUMBO_FRAME_SIZE - ETHER_HDR_LEN) { + if (ifr->ifr_mtu > MAX_JUMBO_FRAME_SIZE - ETHER_HDR_LEN || \ + /* 82573 does not support Jumbo frames */ + (sc->hw.mac_type == em_82573 && ifr->ifr_mtu > ETHERMTU)) { error = EINVAL; } else { EM_LOCK(sc); @@ -1934,6 +1943,8 @@ em_initialize_transmit_unit(struct em_softc *sc) /* Program the Transmit Control Register */ reg_tctl = E1000_TCTL_PSP | E1000_TCTL_EN | (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); + if (sc->hw.mac_type >= em_82573) + reg_tctl |= E1000_TCTL_MULR; if (sc->link_duplex == 1) { reg_tctl |= E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT; } else { @@ -2091,9 +2102,6 @@ em_clean_transmit_interrupts(struct em_softc *sc) if (sc->num_tx_desc_avail == sc->num_tx_desc) return; -#ifdef DBG_STATS - sc->clean_tx_interrupts++; -#endif num_avail = sc->num_tx_desc_avail; i = sc->oldest_used_tx_desc; @@ -2353,7 +2361,8 @@ em_initialize_receive_unit(struct em_softc *sc) break; } - reg_rctl |= E1000_RCTL_LPE; + if (sc->hw.mac_type != em_82573) + reg_rctl |= E1000_RCTL_LPE; /* Enable 82543 Receive Checksum Offload for TCP and UDP */ if (sc->hw.mac_type >= em_82543) { @@ -2434,9 +2443,6 @@ em_process_receive_interrupts(struct em_softc *sc, int count) current_desc = &sc->rx_desc_base[i]; if (!((current_desc->status) & E1000_RXD_STAT_DD)) { -#ifdef DBG_STATS - sc->no_pkts_avail++; -#endif return; } @@ -2948,12 +2954,6 @@ em_print_debug_info(struct em_softc *sc) E1000_READ_REG(&sc->hw, RDTR), E1000_READ_REG(&sc->hw, RADV)); -#ifdef DBG_STATS - printf("%s: Packets not Avail = %ld\n", unit, - sc->no_pkts_avail); - printf("%s: CleanTxInterrupts = %ld\n", unit, - sc->clean_tx_interrupts); -#endif printf("%s: fifo workaround = %lld, fifo_reset = %lld\n", unit, (long long)sc->tx_fifo_wrk_cnt, (long long)sc->tx_fifo_reset_cnt); diff --git a/sys/dev/pci/if_em.h b/sys/dev/pci/if_em.h index dafbe30d45f..a488becd186 100644 --- a/sys/dev/pci/if_em.h +++ b/sys/dev/pci/if_em.h @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ /* $FreeBSD: if_em.h,v 1.26 2004/09/01 23:22:41 pdeuskar Exp $ */ -/* $OpenBSD: if_em.h,v 1.11 2005/05/04 02:33:31 brad Exp $ */ +/* $OpenBSD: if_em.h,v 1.12 2005/07/02 06:15:44 deraadt Exp $ */ #ifndef _EM_H_DEFINED_ #define _EM_H_DEFINED_ @@ -192,7 +192,6 @@ POSSIBILITY OF SUCH DAMAGE. #define EM_SMARTSPEED_DOWNSHIFT 3 #define EM_SMARTSPEED_MAX 15 - #define MAX_NUM_MULTICAST_ADDRESSES 128 #define PCI_ANY_ID (~0U) @@ -211,7 +210,6 @@ POSSIBILITY OF SUCH DAMAGE. #define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A) #define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B) - /* Supported RX Buffer Sizes */ #define EM_RXBUFFER_2048 2048 #define EM_RXBUFFER_4096 4096 @@ -374,11 +372,6 @@ struct em_softc { boolean_t pcix_82544; boolean_t in_detach; -#ifdef DBG_STATS - unsigned long no_pkts_avail; - unsigned long clean_tx_interrupts; - -#endif struct em_hw_stats stats; }; diff --git a/sys/dev/pci/if_em_hw.c b/sys/dev/pci/if_em_hw.c index a2428a01658..ed06d1060e4 100644 --- a/sys/dev/pci/if_em_hw.c +++ b/sys/dev/pci/if_em_hw.c @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright (c) 2001-2003, Intel Corporation + Copyright (c) 2001-2005, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,19 +31,16 @@ *******************************************************************************/ -/* $OpenBSD: if_em_hw.c,v 1.8 2005/03/27 16:38:13 brad Exp $ */ +/* $OpenBSD: if_em_hw.c,v 1.9 2005/07/02 06:15:44 deraadt Exp $ */ /* if_em_hw.c * Shared functions for accessing and configuring the MAC */ #if 0 #include <sys/cdefs.h> -__FBSDID("$FreeBSD: if_em_hw.c,v 1.15 2004/09/23 22:57:53 cognet Exp $"); +__FBSDID("$FreeBSD: if_em_hw.c,v 1.16 2005/05/26 23:32:02 tackerman Exp $"); #endif -#include "bpfilter.h" -#include "vlan.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/sockio.h> @@ -65,15 +62,6 @@ __FBSDID("$FreeBSD: if_em_hw.c,v 1.15 2004/09/23 22:57:53 cognet Exp $"); #include <netinet/if_ether.h> #endif -#if NVLAN > 0 -#include <net/if_types.h> -#include <net/if_vlan_var.h> -#endif - -#if NBPFILTER > 0 -#include <net/bpf.h> -#endif - #include <uvm/uvm_extern.h> #include <dev/pci/pcireg.h> @@ -113,9 +101,11 @@ static uint16_t em_shift_in_ee_bits(struct em_hw *hw, uint16_t count); static int32_t em_acquire_eeprom(struct em_hw *hw); static void em_release_eeprom(struct em_hw *hw); static void em_standby_eeprom(struct em_hw *hw); -static int32_t em_id_led_init(struct em_hw * hw); static int32_t em_set_vco_speed(struct em_hw *hw); +static int32_t em_polarity_reversal_workaround(struct em_hw *hw); static int32_t em_set_phy_mode(struct em_hw *hw); +static int32_t em_host_if_read_cookie(struct em_hw *hw, uint8_t *buffer); +static uint8_t em_calculate_mng_checksum(char *buffer, uint32_t length); /* IGP cable length table */ static const @@ -129,6 +119,16 @@ uint16_t em_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120}; +static const +uint16_t em_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] = + { 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, + 22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58, + 32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74, + 43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90, + 57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108, + 73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124, + 91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128, + 108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}; /****************************************************************************** * Set the phy type member in the hw struct. @@ -140,10 +140,14 @@ em_set_phy_type(struct em_hw *hw) { DEBUGFUNC("em_set_phy_type"); + if(hw->mac_type == em_undefined) + return -E1000_ERR_PHY_TYPE; + switch(hw->phy_id) { case M88E1000_E_PHY_ID: case M88E1000_I_PHY_ID: case M88E1011_I_PHY_ID: + case M88E1111_I_PHY_ID: hw->phy_type = em_phy_m88; break; case IGP01E1000_I_PHY_ID: @@ -172,16 +176,30 @@ em_set_phy_type(struct em_hw *hw) static void em_phy_init_script(struct em_hw *hw) { + uint32_t ret_val; + uint16_t phy_saved_data; + DEBUGFUNC("em_phy_init_script"); if(hw->phy_init_script) { msec_delay(20); + /* Save off the current value of register 0x2F5B to be restored at + * the end of this routine. */ + ret_val = em_read_phy_reg(hw, 0x2F5B, &phy_saved_data); + + /* Disabled the PHY transmitter */ + em_write_phy_reg(hw, 0x2F5B, 0x0003); + + msec_delay(20); + em_write_phy_reg(hw,0x0000,0x0140); msec_delay(5); - if(hw->mac_type == em_82541 || hw->mac_type == em_82547) { + switch(hw->mac_type) { + case em_82541: + case em_82547: em_write_phy_reg(hw, 0x1F95, 0x0001); em_write_phy_reg(hw, 0x1F71, 0xBD21); @@ -199,12 +217,23 @@ em_phy_init_script(struct em_hw *hw) em_write_phy_reg(hw, 0x1F96, 0x003F); em_write_phy_reg(hw, 0x2010, 0x0008); - } else { + break; + + case em_82541_rev_2: + case em_82547_rev_2: em_write_phy_reg(hw, 0x1F73, 0x0099); + break; + default: + break; } em_write_phy_reg(hw, 0x0000, 0x3300); + msec_delay(20); + + /* Now enable the transmitter */ + em_write_phy_reg(hw, 0x2F5B, phy_saved_data); + if(hw->mac_type == em_82547) { uint16_t fused, fine, coarse; @@ -293,9 +322,12 @@ em_set_mac_type(struct em_hw *hw) case E1000_DEV_ID_82546GB_COPPER: case E1000_DEV_ID_82546GB_FIBER: case E1000_DEV_ID_82546GB_SERDES: + case E1000_DEV_ID_82546GB_PCIE: + case E1000_DEV_ID_82546GB_QUAD_COPPER: hw->mac_type = em_82546_rev_3; break; case E1000_DEV_ID_82541EI: + case E1000_DEV_ID_82541ER_LOM: case E1000_DEV_ID_82541EI_MOBILE: hw->mac_type = em_82541; break; @@ -306,16 +338,35 @@ em_set_mac_type(struct em_hw *hw) hw->mac_type = em_82541_rev_2; break; case E1000_DEV_ID_82547EI: + case E1000_DEV_ID_82547EI_MOBILE: hw->mac_type = em_82547; break; case E1000_DEV_ID_82547GI: hw->mac_type = em_82547_rev_2; break; + case E1000_DEV_ID_82573E: + case E1000_DEV_ID_82573E_IAMT: + hw->mac_type = em_82573; + break; default: /* Should never have loaded on this device */ return -E1000_ERR_MAC_TYPE; } + switch(hw->mac_type) { + case em_82573: + hw->eeprom_semaphore_present = TRUE; + /* fall through */ + case em_82541: + case em_82547: + case em_82541_rev_2: + case em_82547_rev_2: + hw->asf_firmware_present = TRUE; + break; + default: + break; + } + return E1000_SUCCESS; } @@ -371,6 +422,9 @@ em_reset_hw(struct em_hw *hw) uint32_t icr; uint32_t manc; uint32_t led_ctrl; + uint32_t timeout; + uint32_t extcnf_ctrl; + int32_t ret_val; DEBUGFUNC("em_reset_hw"); @@ -380,6 +434,15 @@ em_reset_hw(struct em_hw *hw) em_pci_clear_mwi(hw); } + if(hw->bus_type == em_bus_type_pci_express) { + /* Prevent the PCI-E bus from sticking if there is no TLP connection + * on the last TLP read/write transaction when MAC is reset. + */ + if(em_disable_pciex_master(hw) != E1000_SUCCESS) { + DEBUGOUT("PCI-E Master disable polling has failed.\n"); + } + } + /* Clear interrupt mask to stop board from generating interrupts */ DEBUGOUT("Masking off all interrupts\n"); E1000_WRITE_REG(hw, IMC, 0xffffffff); @@ -404,10 +467,32 @@ em_reset_hw(struct em_hw *hw) /* Must reset the PHY before resetting the MAC */ if((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) { - E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST)); + E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST)); msec_delay(5); } + /* Must acquire the MDIO ownership before MAC reset. + * Ownership defaults to firmware after a reset. */ + if(hw->mac_type == em_82573) { + timeout = 10; + + extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + + do { + E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl); + extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); + + if(extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) + break; + else + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + + msec_delay(2); + timeout--; + } while(timeout); + } + /* Issue a global reset to the MAC. This will reset the chip's * transmit, receive, DMA, and link units. It will not effect * the current PCI configuration. The global reset bit is self- @@ -461,6 +546,18 @@ em_reset_hw(struct em_hw *hw) /* Wait for EEPROM reload */ msec_delay(20); break; + case em_82573: + usec_delay(10); + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); + ctrl_ext |= E1000_CTRL_EXT_EE_RST; + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); + E1000_WRITE_FLUSH(hw); + /* fall through */ + ret_val = em_get_auto_rd_done(hw); + if(ret_val) + /* We don't want to continue accessing MAC registers. */ + return ret_val; + break; default: /* Wait for EEPROM reload (it happens automatically) */ msec_delay(5); @@ -468,7 +565,7 @@ em_reset_hw(struct em_hw *hw) } /* Disable HW ARPs on ASF enabled adapters */ - if(hw->mac_type >= em_82540) { + if(hw->mac_type >= em_82540 && hw->mac_type <= em_82547_rev_2) { manc = E1000_READ_REG(hw, MANC); manc &= ~(E1000_MANC_ARP_EN); E1000_WRITE_REG(hw, MANC, manc); @@ -521,6 +618,8 @@ em_init_hw(struct em_hw *hw) uint16_t pcix_stat_hi_word; uint16_t cmd_mmrbc; uint16_t stat_mmrbc; + uint32_t mta_size; + DEBUGFUNC("em_init_hw"); /* Initialize Identification LED */ @@ -535,8 +634,8 @@ em_init_hw(struct em_hw *hw) /* Disabling VLAN filtering. */ DEBUGOUT("Initializing the IEEE VLAN\n"); - E1000_WRITE_REG(hw, VET, 0); - + if (hw->mac_type < em_82545_rev_3) + E1000_WRITE_REG(hw, VET, 0); em_clear_vfta(hw); /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */ @@ -564,14 +663,16 @@ em_init_hw(struct em_hw *hw) /* Zero out the Multicast HASH table */ DEBUGOUT("Zeroing the MTA\n"); - for(i = 0; i < E1000_MC_TBL_SIZE; i++) + mta_size = E1000_MC_TBL_SIZE; + for(i = 0; i < mta_size; i++) E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); /* Set the PCI priority bit correctly in the CTRL register. This * determines if the adapter gives priority to receives, or if it - * gives equal priority to transmits and receives. + * gives equal priority to transmits and receives. Valid only on + * 82542 and 82543 silicon. */ - if(hw->dma_fairness) { + if(hw->dma_fairness && hw->mac_type <= em_82543) { ctrl = E1000_READ_REG(hw, CTRL); E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR); } @@ -609,9 +710,20 @@ em_init_hw(struct em_hw *hw) if(hw->mac_type > em_82544) { ctrl = E1000_READ_REG(hw, TXDCTL); ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; + switch (hw->mac_type) { + default: + break; + case em_82573: + ctrl |= E1000_TXDCTL_COUNT_DESC; + break; + } E1000_WRITE_REG(hw, TXDCTL, ctrl); } + if (hw->mac_type == em_82573) { + em_enable_tx_pkt_filtering(hw); + } + /* Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there @@ -690,7 +802,7 @@ em_setup_link(struct em_hw *hw) * control setting, then the variable hw->fc will * be initialized based on a value in the EEPROM. */ - if(em_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 0) { + if(em_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) { DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } @@ -747,6 +859,7 @@ em_setup_link(struct em_hw *hw) E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW); E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH); E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE); + E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time); /* Set the flow control receive threshold registers. Normally, @@ -917,20 +1030,18 @@ em_setup_fiber_serdes_link(struct em_hw *hw) } /****************************************************************************** -* Detects which PHY is present and the speed and duplex +* Make sure we have a valid PHY and change PHY mode before link setup. * * hw - Struct containing variables accessed by shared code ******************************************************************************/ static int32_t -em_setup_copper_link(struct em_hw *hw) +em_copper_link_preconfig(struct em_hw *hw) { uint32_t ctrl; - uint32_t led_ctrl; int32_t ret_val; - uint16_t i; uint16_t phy_data; - DEBUGFUNC("em_setup_copper_link"); + DEBUGFUNC("em_copper_link_preconfig"); ctrl = E1000_READ_REG(hw, CTRL); /* With 82543, we need to force speed and duplex on the MAC equal to what @@ -944,7 +1055,9 @@ em_setup_copper_link(struct em_hw *hw) } else { ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU); E1000_WRITE_REG(hw, CTRL, ctrl); - em_phy_hw_reset(hw); + ret_val = em_phy_hw_reset(hw); + if(ret_val) + return ret_val; } /* Make sure we have a valid PHY */ @@ -972,274 +1085,398 @@ em_setup_copper_link(struct em_hw *hw) hw->mac_type == em_82541_rev_2 || hw->mac_type == em_82547_rev_2) hw->phy_reset_disable = FALSE; - if(!hw->phy_reset_disable) { - if (hw->phy_type == em_phy_igp) { + return E1000_SUCCESS; +} - ret_val = em_phy_reset(hw); - if(ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; - } - /* Wait 10ms for MAC to configure PHY from eeprom settings */ - msec_delay(15); +/******************************************************************** +* Copper link setup for em_phy_igp series. +* +* hw - Struct containing variables accessed by shared code +*********************************************************************/ +static int32_t +em_copper_link_igp_setup(struct em_hw *hw) +{ + uint32_t led_ctrl; + int32_t ret_val; + uint16_t phy_data; - /* Configure activity LED after PHY reset */ - led_ctrl = E1000_READ_REG(hw, LEDCTL); - led_ctrl &= IGP_ACTIVITY_LED_MASK; - led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); - E1000_WRITE_REG(hw, LEDCTL, led_ctrl); + DEBUGFUNC("em_copper_link_igp_setup"); - /* disable lplu d3 during driver init */ - ret_val = em_set_d3_lplu_state(hw, FALSE); - if(ret_val) { - DEBUGOUT("Error Disabling LPLU D3\n"); - return ret_val; - } + if (hw->phy_reset_disable) + return E1000_SUCCESS; + + ret_val = em_phy_reset(hw); + if (ret_val) { + DEBUGOUT("Error Resetting the PHY\n"); + return ret_val; + } - /* Configure mdi-mdix settings */ - ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, - &phy_data); - if(ret_val) - return ret_val; + /* Wait 10ms for MAC to configure PHY from eeprom settings */ + msec_delay(15); - if((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) { - hw->dsp_config_state = em_dsp_config_disabled; - /* Force MDI for IGP B-0 PHY */ - phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | - IGP01E1000_PSCR_FORCE_MDI_MDIX); - hw->mdix = 1; + /* Configure activity LED after PHY reset */ + led_ctrl = E1000_READ_REG(hw, LEDCTL); + led_ctrl &= IGP_ACTIVITY_LED_MASK; + led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); + E1000_WRITE_REG(hw, LEDCTL, led_ctrl); - } else { - hw->dsp_config_state = em_dsp_config_enabled; - phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; - - switch (hw->mdix) { - case 1: - phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; - break; - case 2: - phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; - break; - case 0: - default: - phy_data |= IGP01E1000_PSCR_AUTO_MDIX; - break; - } - } - ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, - phy_data); - if(ret_val) - return ret_val; + /* disable lplu d3 during driver init */ + ret_val = em_set_d3_lplu_state(hw, FALSE); + if (ret_val) { + DEBUGOUT("Error Disabling LPLU D3\n"); + return ret_val; + } - /* set auto-master slave resolution settings */ - if(hw->autoneg) { - em_ms_type phy_ms_setting = hw->master_slave; + /* disable lplu d0 during driver init */ + ret_val = em_set_d0_lplu_state(hw, FALSE); + if (ret_val) { + DEBUGOUT("Error Disabling LPLU D0\n"); + return ret_val; + } + /* Configure mdi-mdix settings */ + ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); + if (ret_val) + return ret_val; - if(hw->ffe_config_state == em_ffe_config_active) - hw->ffe_config_state = em_ffe_config_enabled; + if ((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) { + hw->dsp_config_state = em_dsp_config_disabled; + /* Force MDI for earlier revs of the IGP PHY */ + phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | IGP01E1000_PSCR_FORCE_MDI_MDIX); + hw->mdix = 1; - if(hw->dsp_config_state == em_dsp_config_activated) - hw->dsp_config_state = em_dsp_config_enabled; + } else { + hw->dsp_config_state = em_dsp_config_enabled; + phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; - /* when autonegotiation advertisment is only 1000Mbps then we - * should disable SmartSpeed and enable Auto MasterSlave - * resolution as hardware default. */ - if(hw->autoneg_advertised == ADVERTISE_1000_FULL) { - /* Disable SmartSpeed */ - ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - &phy_data); - if(ret_val) - return ret_val; - phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = em_write_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - phy_data); - if(ret_val) - return ret_val; - /* Set auto Master/Slave resolution process */ - ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); - if(ret_val) - return ret_val; - phy_data &= ~CR_1000T_MS_ENABLE; - ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); - if(ret_val) - return ret_val; - } + switch (hw->mdix) { + case 1: + phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; + break; + case 2: + phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; + break; + case 0: + default: + phy_data |= IGP01E1000_PSCR_AUTO_MDIX; + break; + } + } + ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); + if(ret_val) + return ret_val; - ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); - if(ret_val) - return ret_val; + /* set auto-master slave resolution settings */ + if(hw->autoneg) { + em_ms_type phy_ms_setting = hw->master_slave; - /* load defaults for future use */ - hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ? - ((phy_data & CR_1000T_MS_VALUE) ? - em_ms_force_master : - em_ms_force_slave) : - em_ms_auto; - - switch (phy_ms_setting) { - case em_ms_force_master: - phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); - break; - case em_ms_force_slave: - phy_data |= CR_1000T_MS_ENABLE; - phy_data &= ~(CR_1000T_MS_VALUE); - break; - case em_ms_auto: - phy_data &= ~CR_1000T_MS_ENABLE; - default: - break; - } - ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); - if(ret_val) - return ret_val; - } - } else { - /* Enable CRS on TX. This must be set for half-duplex operation. */ - ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, - &phy_data); + if(hw->ffe_config_state == em_ffe_config_active) + hw->ffe_config_state = em_ffe_config_enabled; + + if(hw->dsp_config_state == em_dsp_config_activated) + hw->dsp_config_state = em_dsp_config_enabled; + + /* when autonegotiation advertisment is only 1000Mbps then we + * should disable SmartSpeed and enable Auto MasterSlave + * resolution as hardware default. */ + if(hw->autoneg_advertised == ADVERTISE_1000_FULL) { + /* Disable SmartSpeed */ + ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); + if(ret_val) + return ret_val; + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; + ret_val = em_write_phy_reg(hw, + IGP01E1000_PHY_PORT_CONFIG, + phy_data); + if(ret_val) + return ret_val; + /* Set auto Master/Slave resolution process */ + ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); + if(ret_val) + return ret_val; + phy_data &= ~CR_1000T_MS_ENABLE; + ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); if(ret_val) return ret_val; + } - phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; + ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); + if(ret_val) + return ret_val; - /* Options: - * MDI/MDI-X = 0 (default) - * 0 - Auto for all speeds - * 1 - MDI mode - * 2 - MDI-X mode - * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) - */ - phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; + /* load defaults for future use */ + hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ? + ((phy_data & CR_1000T_MS_VALUE) ? + em_ms_force_master : + em_ms_force_slave) : + em_ms_auto; - switch (hw->mdix) { - case 1: - phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; - break; - case 2: - phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; - break; - case 3: - phy_data |= M88E1000_PSCR_AUTO_X_1000T; - break; - case 0: + switch (phy_ms_setting) { + case em_ms_force_master: + phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); + break; + case em_ms_force_slave: + phy_data |= CR_1000T_MS_ENABLE; + phy_data &= ~(CR_1000T_MS_VALUE); + break; + case em_ms_auto: + phy_data &= ~CR_1000T_MS_ENABLE; default: - phy_data |= M88E1000_PSCR_AUTO_X_MODE; - break; - } + break; + } + ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); + if(ret_val) + return ret_val; + } - /* Options: - * disable_polarity_correction = 0 (default) - * Automatic Correction for Reversed Cable Polarity - * 0 - Disabled - * 1 - Enabled - */ - phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; - if(hw->disable_polarity_correction == 1) - phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; - ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, - phy_data); - if(ret_val) - return ret_val; + return E1000_SUCCESS; +} - /* Force TX_CLK in the Extended PHY Specific Control Register - * to 25MHz clock. - */ - ret_val = em_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - &phy_data); - if(ret_val) - return ret_val; - phy_data |= M88E1000_EPSCR_TX_CLK_25; +/******************************************************************** +* Copper link setup for em_phy_m88 series. +* +* hw - Struct containing variables accessed by shared code +*********************************************************************/ +static int32_t +em_copper_link_mgp_setup(struct em_hw *hw) +{ + int32_t ret_val; + uint16_t phy_data; + + DEBUGFUNC("em_copper_link_mgp_setup"); + + if(hw->phy_reset_disable) + return E1000_SUCCESS; + + /* Enable CRS on TX. This must be set for half-duplex operation. */ + ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + if(ret_val) + return ret_val; + + phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; + + /* Options: + * MDI/MDI-X = 0 (default) + * 0 - Auto for all speeds + * 1 - MDI mode + * 2 - MDI-X mode + * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) + */ + phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; + + switch (hw->mdix) { + case 1: + phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; + break; + case 2: + phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; + break; + case 3: + phy_data |= M88E1000_PSCR_AUTO_X_1000T; + break; + case 0: + default: + phy_data |= M88E1000_PSCR_AUTO_X_MODE; + break; + } + + /* Options: + * disable_polarity_correction = 0 (default) + * Automatic Correction for Reversed Cable Polarity + * 0 - Disabled + * 1 - Enabled + */ + phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; + if(hw->disable_polarity_correction == 1) + phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; + ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); + if(ret_val) + return ret_val; - if (hw->phy_revision < M88E1011_I_REV_4) { - /* Configure Master and Slave downshift values */ - phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | + /* Force TX_CLK in the Extended PHY Specific Control Register + * to 25MHz clock. + */ + ret_val = em_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); + if(ret_val) + return ret_val; + + phy_data |= M88E1000_EPSCR_TX_CLK_25; + + if (hw->phy_revision < M88E1011_I_REV_4) { + /* Configure Master and Slave downshift values */ + phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); - phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | + phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); - ret_val = em_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - phy_data); - if(ret_val) - return ret_val; - } + ret_val = em_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); + if(ret_val) + return ret_val; + } - /* SW Reset the PHY so all changes take effect */ - ret_val = em_phy_reset(hw); - if(ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; - } + /* SW Reset the PHY so all changes take effect */ + ret_val = em_phy_reset(hw); + if(ret_val) { + DEBUGOUT("Error Resetting the PHY\n"); + return ret_val; + } + + return E1000_SUCCESS; +} + +/******************************************************************** +* Setup auto-negotiation and flow control advertisements, +* and then perform auto-negotiation. +* +* hw - Struct containing variables accessed by shared code +*********************************************************************/ +static int32_t +em_copper_link_autoneg(struct em_hw *hw) +{ + int32_t ret_val; + uint16_t phy_data; + + DEBUGFUNC("em_copper_link_autoneg"); + + /* Perform some bounds checking on the hw->autoneg_advertised + * parameter. If this variable is zero, then set it to the default. + */ + hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT; + + /* If autoneg_advertised is zero, we assume it was not defaulted + * by the calling code so we set to advertise full capability. + */ + if(hw->autoneg_advertised == 0) + hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; + + DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); + ret_val = em_phy_setup_autoneg(hw); + if(ret_val) { + DEBUGOUT("Error Setting up Auto-Negotiation\n"); + return ret_val; + } + DEBUGOUT("Restarting Auto-Neg\n"); + + /* Restart auto-negotiation by setting the Auto Neg Enable bit and + * the Auto Neg Restart bit in the PHY control register. + */ + ret_val = em_read_phy_reg(hw, PHY_CTRL, &phy_data); + if(ret_val) + return ret_val; + + phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); + ret_val = em_write_phy_reg(hw, PHY_CTRL, phy_data); + if(ret_val) + return ret_val; + + /* Does the user want to wait for Auto-Neg to complete here, or + * check at a later time (for example, callback routine). + */ + if(hw->wait_autoneg_complete) { + ret_val = em_wait_autoneg(hw); + if(ret_val) { + DEBUGOUT("Error while waiting for autoneg to complete\n"); + return ret_val; } + } - /* Options: - * autoneg = 1 (default) - * PHY will advertise value(s) parsed from - * autoneg_advertised and fc - * autoneg = 0 - * PHY will be set to 10H, 10F, 100H, or 100F - * depending on value parsed from forced_speed_duplex. - */ + hw->get_link_status = TRUE; - /* Is autoneg enabled? This is enabled by default or by software - * override. If so, call em_phy_setup_autoneg routine to parse the - * autoneg_advertised and fc options. If autoneg is NOT enabled, then - * the user should have provided a speed/duplex override. If so, then - * call em_phy_force_speed_duplex to parse and set this up. - */ - if(hw->autoneg) { - /* Perform some bounds checking on the hw->autoneg_advertised - * parameter. If this variable is zero, then set it to the default. - */ - hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT; + return E1000_SUCCESS; +} - /* If autoneg_advertised is zero, we assume it was not defaulted - * by the calling code so we set to advertise full capability. - */ - if(hw->autoneg_advertised == 0) - hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; - DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); - ret_val = em_phy_setup_autoneg(hw); - if(ret_val) { - DEBUGOUT("Error Setting up Auto-Negotiation\n"); - return ret_val; - } - DEBUGOUT("Restarting Auto-Neg\n"); +/****************************************************************************** +* Config the MAC and the PHY after link is up. +* 1) Set up the MAC to the current PHY speed/duplex +* if we are on 82543. If we +* are on newer silicon, we only need to configure +* collision distance in the Transmit Control Register. +* 2) Set up flow control on the MAC to that established with +* the link partner. +* 3) Config DSP to improve Gigabit link quality for some PHY revisions. +* +* hw - Struct containing variables accessed by shared code +******************************************************************************/ +static int32_t +em_copper_link_postconfig(struct em_hw *hw) +{ + int32_t ret_val; + DEBUGFUNC("em_copper_link_postconfig"); + + if(hw->mac_type >= em_82544) { + em_config_collision_dist(hw); + } else { + ret_val = em_config_mac_to_phy(hw); + if(ret_val) { + DEBUGOUT("Error configuring MAC to PHY settings\n"); + return ret_val; + } + } + ret_val = em_config_fc_after_link_up(hw); + if(ret_val) { + DEBUGOUT("Error Configuring Flow Control\n"); + return ret_val; + } - /* Restart auto-negotiation by setting the Auto Neg Enable bit and - * the Auto Neg Restart bit in the PHY control register. - */ - ret_val = em_read_phy_reg(hw, PHY_CTRL, &phy_data); - if(ret_val) - return ret_val; + /* Config DSP to improve Giga link quality */ + if(hw->phy_type == em_phy_igp) { + ret_val = em_config_dsp_after_link_change(hw, TRUE); + if(ret_val) { + DEBUGOUT("Error Configuring DSP after link up\n"); + return ret_val; + } + } + + return E1000_SUCCESS; +} - phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); - ret_val = em_write_phy_reg(hw, PHY_CTRL, phy_data); - if(ret_val) - return ret_val; +/****************************************************************************** +* Detects which PHY is present and setup the speed and duplex +* +* hw - Struct containing variables accessed by shared code +******************************************************************************/ +static int32_t +em_setup_copper_link(struct em_hw *hw) +{ + int32_t ret_val; + uint16_t i; + uint16_t phy_data; - /* Does the user want to wait for Auto-Neg to complete here, or - * check at a later time (for example, callback routine). - */ - if(hw->wait_autoneg_complete) { - ret_val = em_wait_autoneg(hw); - if(ret_val) { - DEBUGOUT("Error while waiting for autoneg to complete\n"); - return ret_val; - } - } - hw->get_link_status = TRUE; - } else { - DEBUGOUT("Forcing speed and duplex\n"); - ret_val = em_phy_force_speed_duplex(hw); - if(ret_val) { - DEBUGOUT("Error Forcing Speed and Duplex\n"); - return ret_val; - } + DEBUGFUNC("em_setup_copper_link"); + + /* Check if it is a valid PHY and set PHY mode if necessary. */ + ret_val = em_copper_link_preconfig(hw); + if(ret_val) + return ret_val; + + if (hw->phy_type == em_phy_igp || + hw->phy_type == em_phy_igp_2) { + ret_val = em_copper_link_igp_setup(hw); + if(ret_val) + return ret_val; + } else if (hw->phy_type == em_phy_m88) { + ret_val = em_copper_link_mgp_setup(hw); + if(ret_val) + return ret_val; + } + + if(hw->autoneg) { + /* Setup autoneg and flow control advertisement + * and perform autonegotiation */ + ret_val = em_copper_link_autoneg(hw); + if(ret_val) + return ret_val; + } else { + /* PHY will be set to 10H, 10F, 100H,or 100F + * depending on value from forced_speed_duplex. */ + DEBUGOUT("Forcing speed and duplex\n"); + ret_val = em_phy_force_speed_duplex(hw); + if(ret_val) { + DEBUGOUT("Error Forcing Speed and Duplex\n"); + return ret_val; } - } /* !hw->phy_reset_disable */ + } /* Check link status. Wait up to 100 microseconds for link to become * valid. @@ -1253,37 +1490,11 @@ em_setup_copper_link(struct em_hw *hw) return ret_val; if(phy_data & MII_SR_LINK_STATUS) { - /* We have link, so we need to finish the config process: - * 1) Set up the MAC to the current PHY speed/duplex - * if we are on 82543. If we - * are on newer silicon, we only need to configure - * collision distance in the Transmit Control Register. - * 2) Set up flow control on the MAC to that established with - * the link partner. - */ - if(hw->mac_type >= em_82544) { - em_config_collision_dist(hw); - } else { - ret_val = em_config_mac_to_phy(hw); - if(ret_val) { - DEBUGOUT("Error configuring MAC to PHY settings\n"); - return ret_val; - } - } - ret_val = em_config_fc_after_link_up(hw); - if(ret_val) { - DEBUGOUT("Error Configuring Flow Control\n"); + /* Config the MAC and PHY after link is up */ + ret_val = em_copper_link_postconfig(hw); + if(ret_val) return ret_val; - } - DEBUGOUT("Valid link established!!!\n"); - - if(hw->phy_type == em_phy_igp) { - ret_val = em_config_dsp_after_link_change(hw, TRUE); - if(ret_val) { - DEBUGOUT("Error Configuring DSP after link up\n"); - return ret_val; - } - } + DEBUGOUT("Valid link established!!!\n"); return E1000_SUCCESS; } @@ -1313,10 +1524,10 @@ em_phy_setup_autoneg(struct em_hw *hw) if(ret_val) return ret_val; - /* Read the MII 1000Base-T Control Register (Address 9). */ - ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg); - if(ret_val) - return ret_val; + /* Read the MII 1000Base-T Control Register (Address 9). */ + ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg); + if(ret_val) + return ret_val; /* Need to parse both autoneg_advertised and fc and set up * the appropriate PHY registers. First we will parse for @@ -1428,7 +1639,7 @@ em_phy_setup_autoneg(struct em_hw *hw) DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); - ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); + ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); if(ret_val) return ret_val; @@ -1516,16 +1727,16 @@ em_phy_force_speed_duplex(struct em_hw *hw) E1000_WRITE_REG(hw, CTRL, ctrl); if (hw->phy_type == em_phy_m88) { - if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, - &phy_data))) + ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + if(ret_val) return ret_val; /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI * forced whenever speed are duplex are forced. */ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; - if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, - phy_data))) + ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); + if(ret_val) return ret_val; DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data); @@ -1536,20 +1747,21 @@ em_phy_force_speed_duplex(struct em_hw *hw) /* Clear Auto-Crossover to force MDI manually. IGP requires MDI * forced whenever speed or duplex are forced. */ - if((ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, - &phy_data))) + ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); + if(ret_val) return ret_val; phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; - if((ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, - phy_data))) + ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); + if(ret_val) return ret_val; } /* Write back the modified PHY MII control register. */ - if((ret_val = em_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg))) + ret_val = em_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg); + if(ret_val) return ret_val; usec_delay(1); @@ -1582,7 +1794,8 @@ em_phy_force_speed_duplex(struct em_hw *hw) if(mii_status_reg & MII_SR_LINK_STATUS) break; msec_delay(100); } - if((i == 0) && (hw->phy_type == em_phy_m88)) { + if((i == 0) && + (hw->phy_type == em_phy_m88)) { /* We didn't get link. Reset the DSP and wait again for link. */ ret_val = em_phy_reset_dsp(hw); if(ret_val) { @@ -1632,6 +1845,15 @@ em_phy_force_speed_duplex(struct em_hw *hw) ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if(ret_val) return ret_val; + + if((hw->mac_type == em_82544 || hw->mac_type == em_82543) && + (!hw->autoneg) && + (hw->forced_speed_duplex == em_10_full || + hw->forced_speed_duplex == em_10_half)) { + ret_val = em_polarity_reversal_workaround(hw); + if(ret_val) + return ret_val; + } } return E1000_SUCCESS; } @@ -1678,6 +1900,11 @@ em_config_mac_to_phy(struct em_hw *hw) DEBUGFUNC("em_config_mac_to_phy"); + /* 82544 or newer MAC, Auto Speed Detection takes care of + * MAC speed/duplex configuration.*/ + if (hw->mac_type >= em_82544) + return E1000_SUCCESS; + /* Read the Device Control Register and set the bits to Force Speed * and Duplex. */ @@ -1688,45 +1915,25 @@ em_config_mac_to_phy(struct em_hw *hw) /* Set up duplex in the Device Control and Transmit Control * registers depending on negotiated values. */ - if (hw->phy_type == em_phy_igp) { - ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, - &phy_data); - if(ret_val) - return ret_val; - - if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD; - else ctrl &= ~E1000_CTRL_FD; - - em_config_collision_dist(hw); + ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); + if(ret_val) + return ret_val; - /* Set up speed in the Device Control register depending on - * negotiated values. - */ - if((phy_data & IGP01E1000_PSSR_SPEED_MASK) == - IGP01E1000_PSSR_SPEED_1000MBPS) - ctrl |= E1000_CTRL_SPD_1000; - else if((phy_data & IGP01E1000_PSSR_SPEED_MASK) == - IGP01E1000_PSSR_SPEED_100MBPS) - ctrl |= E1000_CTRL_SPD_100; - } else { - ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, - &phy_data); - if(ret_val) - return ret_val; + if(phy_data & M88E1000_PSSR_DPLX) + ctrl |= E1000_CTRL_FD; + else + ctrl &= ~E1000_CTRL_FD; - if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD; - else ctrl &= ~E1000_CTRL_FD; + em_config_collision_dist(hw); - em_config_collision_dist(hw); + /* Set up speed in the Device Control register depending on + * negotiated values. + */ + if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) + ctrl |= E1000_CTRL_SPD_1000; + else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS) + ctrl |= E1000_CTRL_SPD_100; - /* Set up speed in the Device Control register depending on - * negotiated values. - */ - if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) - ctrl |= E1000_CTRL_SPD_1000; - else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS) - ctrl |= E1000_CTRL_SPD_100; - } /* Write the configured values back to the Device Control Reg. */ E1000_WRITE_REG(hw, CTRL, ctrl); return E1000_SUCCESS; @@ -2021,6 +2228,7 @@ em_check_for_link(struct em_hw *hw) uint32_t ctrl; uint32_t status; uint32_t rctl; + uint32_t icr; uint32_t signal = 0; int32_t ret_val; uint16_t phy_data; @@ -2070,6 +2278,25 @@ em_check_for_link(struct em_hw *hw) * link-up */ em_check_downshift(hw); + /* If we are on 82544 or 82543 silicon and speed/duplex + * are forced to 10H or 10F, then we will implement the polarity + * reversal workaround. We disable interrupts first, and upon + * returning, place the devices interrupt state to its previous + * value except for the link status change interrupt which will + * happen due to the execution of this workaround. + */ + + if((hw->mac_type == em_82544 || hw->mac_type == em_82543) && + (!hw->autoneg) && + (hw->forced_speed_duplex == em_10_full || + hw->forced_speed_duplex == em_10_half)) { + E1000_WRITE_REG(hw, IMC, 0xffffffff); + ret_val = em_polarity_reversal_workaround(hw); + icr = E1000_READ_REG(hw, ICR); + E1000_WRITE_REG(hw, ICS, (icr & ~E1000_ICS_LSC)); + E1000_WRITE_REG(hw, IMS, IMS_ENABLE_MASK); + } + } else { /* No link detected */ em_config_dsp_after_link_change(hw, FALSE); @@ -2119,7 +2346,7 @@ em_check_for_link(struct em_hw *hw) * at gigabit speed, then TBI compatibility is not needed. If we are * at gigabit speed, we turn on TBI compatibility. */ - if(hw->tbi_compatibility_en) { + if(hw->tbi_compatibility_en) { uint16_t speed, duplex; em_get_speed_and_duplex(hw, &speed, &duplex); if(speed != SPEED_1000) { @@ -2474,15 +2701,17 @@ em_read_phy_reg(struct em_hw *hw, DEBUGFUNC("em_read_phy_reg"); - if(hw->phy_type == em_phy_igp && + if((hw->phy_type == em_phy_igp || + hw->phy_type == em_phy_igp_2) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = em_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, (uint16_t)reg_addr); - if(ret_val) + if(ret_val) { return ret_val; + } } - ret_val = em_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr, + ret_val = em_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, phy_data); return ret_val; @@ -2578,15 +2807,17 @@ em_write_phy_reg(struct em_hw *hw, DEBUGFUNC("em_write_phy_reg"); - if(hw->phy_type == em_phy_igp && + if((hw->phy_type == em_phy_igp || + hw->phy_type == em_phy_igp_2) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = em_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, (uint16_t)reg_addr); - if(ret_val) + if(ret_val) { return ret_val; + } } - ret_val = em_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr, + ret_val = em_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, phy_data); return ret_val; @@ -2655,19 +2886,27 @@ em_write_phy_reg_ex(struct em_hw *hw, return E1000_SUCCESS; } + /****************************************************************************** * Returns the PHY to the power-on reset state * * hw - Struct containing variables accessed by shared code ******************************************************************************/ -void +int32_t em_phy_hw_reset(struct em_hw *hw) { uint32_t ctrl, ctrl_ext; uint32_t led_ctrl; + int32_t ret_val; DEBUGFUNC("em_phy_hw_reset"); + /* In the case of the phy reset being blocked, it's not an error, we + * simply return success without performing the reset. */ + ret_val = em_check_phy_reset_block(hw); + if (ret_val) + return E1000_SUCCESS; + DEBUGOUT("Resetting Phy...\n"); if(hw->mac_type > em_82543) { @@ -2703,6 +2942,11 @@ em_phy_hw_reset(struct em_hw *hw) led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); E1000_WRITE_REG(hw, LEDCTL, led_ctrl); } + + /* Wait for FW to finish PHY configuration. */ + ret_val = em_get_phy_cfg_done(hw); + + return ret_val; } /****************************************************************************** @@ -2720,7 +2964,19 @@ em_phy_reset(struct em_hw *hw) DEBUGFUNC("em_phy_reset"); - if(hw->mac_type != em_82541_rev_2) { + /* In the case of the phy reset being blocked, it's not an error, we + * simply return success without performing the reset. */ + ret_val = em_check_phy_reset_block(hw); + if (ret_val) + return E1000_SUCCESS; + + switch (hw->mac_type) { + case em_82541_rev_2: + ret_val = em_phy_hw_reset(hw); + if(ret_val) + return ret_val; + break; + default: ret_val = em_read_phy_reg(hw, PHY_CTRL, &phy_data); if(ret_val) return ret_val; @@ -2731,9 +2987,10 @@ em_phy_reset(struct em_hw *hw) return ret_val; usec_delay(1); - } else em_phy_hw_reset(hw); + break; + } - if(hw->phy_type == em_phy_igp) + if(hw->phy_type == em_phy_igp || hw->phy_type == em_phy_igp_2) em_phy_init_script(hw); return E1000_SUCCESS; @@ -2787,6 +3044,9 @@ em_detect_gig_phy(struct em_hw *hw) case em_82547_rev_2: if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE; break; + case em_82573: + if(hw->phy_id == M88E1111_I_PHY_ID) match = TRUE; + break; default: DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type); return -E1000_ERR_CONFIG; @@ -2842,7 +3102,7 @@ em_phy_igp_get_info(struct em_hw *hw, /* The downshift status is checked only once, after link is established, * and it stored in the hw->speed_downgraded parameter. */ - phy_info->downshift = hw->speed_downgraded; + phy_info->downshift = (em_downshift)hw->speed_downgraded; /* IGP01E1000 does not need to support it. */ phy_info->extended_10bt_distance = em_10bt_ext_dist_enable_normal; @@ -2881,7 +3141,7 @@ em_phy_igp_get_info(struct em_hw *hw, if(ret_val) return ret_val; - /* transalte to old method */ + /* Translate to old method */ average = (max_length + min_length) / 2; if(average <= em_igp_cable_length_50) @@ -2916,7 +3176,7 @@ em_phy_m88_get_info(struct em_hw *hw, /* The downshift status is checked only once, after link is established, * and it stored in the hw->speed_downgraded parameter. */ - phy_info->downshift = hw->speed_downgraded; + phy_info->downshift = (em_downshift)hw->speed_downgraded; ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if(ret_val) @@ -2932,8 +3192,7 @@ em_phy_m88_get_info(struct em_hw *hw, /* Check polarity status */ ret_val = em_check_polarity(hw, &polarity); if(ret_val) - return ret_val; - + return ret_val; phy_info->cable_polarity = polarity; ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); @@ -2943,9 +3202,9 @@ em_phy_m88_get_info(struct em_hw *hw, phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >> M88E1000_PSSR_MDIX_SHIFT; - if(phy_data & M88E1000_PSSR_1000MBS) { - /* Cable Length Estimation and Local/Remote Receiver Informatoion - * are only valid at 1000 Mbps + if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) { + /* Cable Length Estimation and Local/Remote Receiver Information + * are only valid at 1000 Mbps. */ phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> M88E1000_PSSR_CABLE_LENGTH_SHIFT); @@ -3006,7 +3265,8 @@ em_phy_get_info(struct em_hw *hw, return -E1000_ERR_CONFIG; } - if(hw->phy_type == em_phy_igp) + if(hw->phy_type == em_phy_igp || + hw->phy_type == em_phy_igp_2) return em_phy_igp_get_info(hw, phy_info); else return em_phy_m88_get_info(hw, phy_info); @@ -3032,11 +3292,12 @@ em_validate_mdi_setting(struct em_hw *hw) * * hw - Struct containing variables accessed by shared code *****************************************************************************/ -void +int32_t em_init_eeprom_params(struct em_hw *hw) { struct em_eeprom_info *eeprom = &hw->eeprom; uint32_t eecd = E1000_READ_REG(hw, EECD); + int32_t ret_val = E1000_SUCCESS; uint16_t eeprom_size; DEBUGFUNC("em_init_eeprom_params"); @@ -3051,6 +3312,8 @@ em_init_eeprom_params(struct em_hw *hw) eeprom->opcode_bits = 3; eeprom->address_bits = 6; eeprom->delay_usec = 50; + eeprom->use_eerd = FALSE; + eeprom->use_eewr = FALSE; break; case em_82540: case em_82545: @@ -3067,6 +3330,8 @@ em_init_eeprom_params(struct em_hw *hw) eeprom->word_size = 64; eeprom->address_bits = 6; } + eeprom->use_eerd = FALSE; + eeprom->use_eewr = FALSE; break; case em_82541: case em_82541_rev_2: @@ -3095,8 +3360,10 @@ em_init_eeprom_params(struct em_hw *hw) eeprom->address_bits = 6; } } + eeprom->use_eerd = FALSE; + eeprom->use_eewr = FALSE; break; - default: + case em_82573: eeprom->type = em_eeprom_spi; eeprom->opcode_bits = 8; eeprom->delay_usec = 1; @@ -3107,40 +3374,46 @@ em_init_eeprom_params(struct em_hw *hw) eeprom->page_size = 8; eeprom->address_bits = 8; } + eeprom->use_eerd = TRUE; + eeprom->use_eewr = TRUE; + if(em_is_onboard_nvm_eeprom(hw) == FALSE) { + eeprom->type = em_eeprom_flash; + eeprom->word_size = 2048; + + /* Ensure that the Autonomous FLASH update bit is cleared due to + * Flash update issue on parts which use a FLASH for NVM. */ + eecd &= ~E1000_EECD_AUPDEN; + E1000_WRITE_REG(hw, EECD, eecd); + } + break; + default: break; } if (eeprom->type == em_eeprom_spi) { - eeprom->word_size = 64; - if (em_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) { - eeprom_size &= EEPROM_SIZE_MASK; - - switch (eeprom_size) { - case EEPROM_SIZE_16KB: - eeprom->word_size = 8192; - break; - case EEPROM_SIZE_8KB: - eeprom->word_size = 4096; - break; - case EEPROM_SIZE_4KB: - eeprom->word_size = 2048; - break; - case EEPROM_SIZE_2KB: - eeprom->word_size = 1024; - break; - case EEPROM_SIZE_1KB: - eeprom->word_size = 512; - break; - case EEPROM_SIZE_512B: - eeprom->word_size = 256; - break; - case EEPROM_SIZE_128B: - default: - eeprom->word_size = 64; - break; - } + /* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to + * 32KB (incremented by powers of 2). + */ + if(hw->mac_type <= em_82547_rev_2) { + /* Set to default value for initial eeprom read. */ + eeprom->word_size = 64; + ret_val = em_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size); + if(ret_val) + return ret_val; + eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT; + /* 256B eeprom size was not supported in earlier hardware, so we + * bump eeprom_size up one to ensure that "1" (which maps to 256B) + * is never the result used in the shifting logic below. */ + if(eeprom_size) + eeprom_size++; + } else { + eeprom_size = (uint16_t)((eecd & E1000_EECD_SIZE_EX_MASK) >> + E1000_EECD_SIZE_EX_SHIFT); } + + eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT); } + return ret_val; } /****************************************************************************** @@ -3293,8 +3566,12 @@ em_acquire_eeprom(struct em_hw *hw) DEBUGFUNC("em_acquire_eeprom"); + if(em_get_hw_eeprom_semaphore(hw)) + return -E1000_ERR_EEPROM; + eecd = E1000_READ_REG(hw, EECD); + if (hw->mac_type != em_82573) { /* Request EEPROM Access */ if(hw->mac_type > em_82544) { eecd |= E1000_EECD_REQ; @@ -3313,6 +3590,7 @@ em_acquire_eeprom(struct em_hw *hw) return -E1000_ERR_EEPROM; } } + } /* Setup EEPROM for Read/Write */ @@ -3430,6 +3708,8 @@ em_release_eeprom(struct em_hw *hw) eecd &= ~E1000_EECD_REQ; E1000_WRITE_REG(hw, EECD, eecd); } + + em_put_hw_eeprom_semaphore(hw); } /****************************************************************************** @@ -3491,21 +3771,36 @@ em_read_eeprom(struct em_hw *hw, { struct em_eeprom_info *eeprom = &hw->eeprom; uint32_t i = 0; + int32_t ret_val; DEBUGFUNC("em_read_eeprom"); /* A check for invalid values: offset too large, too many words, and not * enough words. */ - if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) || + if((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) || (words == 0)) { DEBUGOUT("\"words\" parameter out of bounds\n"); return -E1000_ERR_EEPROM; } - /* Prepare the EEPROM for reading */ - if(em_acquire_eeprom(hw) != E1000_SUCCESS) - return -E1000_ERR_EEPROM; + /* FLASH reads without acquiring the semaphore are safe in 82573-based + * controllers. + */ + if ((em_is_onboard_nvm_eeprom(hw) == TRUE) || + (hw->mac_type != em_82573)) { + /* Prepare the EEPROM for reading */ + if(em_acquire_eeprom(hw) != E1000_SUCCESS) + return -E1000_ERR_EEPROM; + } + + if(eeprom->use_eerd == TRUE) { + ret_val = em_read_eeprom_eerd(hw, offset, words, data); + if ((em_is_onboard_nvm_eeprom(hw) == TRUE) || + (hw->mac_type != em_82573)) + em_release_eeprom(hw); + return ret_val; + } if(eeprom->type == em_eeprom_spi) { uint16_t word_in; @@ -3557,6 +3852,132 @@ em_read_eeprom(struct em_hw *hw, } /****************************************************************************** + * Reads a 16 bit word from the EEPROM using the EERD register. + * + * hw - Struct containing variables accessed by shared code + * offset - offset of word in the EEPROM to read + * data - word read from the EEPROM + * words - number of words to read + *****************************************************************************/ +int32_t +em_read_eeprom_eerd(struct em_hw *hw, + uint16_t offset, + uint16_t words, + uint16_t *data) +{ + uint32_t i, eerd = 0; + int32_t error = 0; + + for (i = 0; i < words; i++) { + eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) + + E1000_EEPROM_RW_REG_START; + + E1000_WRITE_REG(hw, EERD, eerd); + error = em_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ); + + if(error) { + break; + } + data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA); + + } + + return error; +} + +/****************************************************************************** + * Writes a 16 bit word from the EEPROM using the EEWR register. + * + * hw - Struct containing variables accessed by shared code + * offset - offset of word in the EEPROM to read + * data - word read from the EEPROM + * words - number of words to read + *****************************************************************************/ +int32_t +em_write_eeprom_eewr(struct em_hw *hw, + uint16_t offset, + uint16_t words, + uint16_t *data) +{ + uint32_t register_value = 0; + uint32_t i = 0; + int32_t error = 0; + + for (i = 0; i < words; i++) { + register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) | + ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) | + E1000_EEPROM_RW_REG_START; + + error = em_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE); + if(error) { + break; + } + + E1000_WRITE_REG(hw, EEWR, register_value); + + error = em_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE); + + if(error) { + break; + } + } + + return error; +} + +/****************************************************************************** + * Polls the status bit (bit 1) of the EERD to determine when the read is done. + * + * hw - Struct containing variables accessed by shared code + *****************************************************************************/ +int32_t +em_poll_eerd_eewr_done(struct em_hw *hw, int eerd) +{ + uint32_t attempts = 100000; + uint32_t i, reg = 0; + int32_t done = E1000_ERR_EEPROM; + + for(i = 0; i < attempts; i++) { + if(eerd == E1000_EEPROM_POLL_READ) + reg = E1000_READ_REG(hw, EERD); + else + reg = E1000_READ_REG(hw, EEWR); + + if(reg & E1000_EEPROM_RW_REG_DONE) { + done = E1000_SUCCESS; + break; + } + usec_delay(5); + } + + return done; +} + +/*************************************************************************** +* Description: Determines if the onboard NVM is FLASH or EEPROM. +* +* hw - Struct containing variables accessed by shared code +****************************************************************************/ +boolean_t +em_is_onboard_nvm_eeprom(struct em_hw *hw) +{ + uint32_t eecd = 0; + + if(hw->mac_type == em_82573) { + eecd = E1000_READ_REG(hw, EECD); + + /* Isolate bits 15 & 16 */ + eecd = ((eecd >> 15) & 0x03); + + /* If both bits are set, device is Flash type */ + if(eecd == 0x03) { + return FALSE; + } + } + return TRUE; +} + +/****************************************************************************** * Verifies that the EEPROM has a valid checksum * * hw - Struct containing variables accessed by shared code @@ -3573,6 +3994,25 @@ em_validate_eeprom_checksum(struct em_hw *hw) DEBUGFUNC("em_validate_eeprom_checksum"); + if ((hw->mac_type == em_82573) && + (em_is_onboard_nvm_eeprom(hw) == FALSE)) { + /* Check bit 4 of word 10h. If it is 0, firmware is done updating + * 10h-12h. Checksum may need to be fixed. */ + em_read_eeprom(hw, 0x10, 1, &eeprom_data); + if ((eeprom_data & 0x10) == 0) { + /* Read 0x23 and check bit 15. This bit is a 1 when the checksum + * has already been fixed. If the checksum is still wrong and this + * bit is a 1, we need to return bad checksum. Otherwise, we need + * to set this bit to a 1 and update the checksum. */ + em_read_eeprom(hw, 0x23, 1, &eeprom_data); + if ((eeprom_data & 0x8000) == 0) { + eeprom_data |= 0x8000; + em_write_eeprom(hw, 0x23, 1, &eeprom_data); + em_update_eeprom_checksum(hw); + } + } + } + for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { if(em_read_eeprom(hw, i, 1, &eeprom_data) < 0) { DEBUGOUT("EEPROM Read Error\n"); @@ -3616,6 +4056,8 @@ em_update_eeprom_checksum(struct em_hw *hw) if(em_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) { DEBUGOUT("EEPROM Write Error\n"); return -E1000_ERR_EEPROM; + } else if (hw->eeprom.type == em_eeprom_flash) { + em_commit_shadow_ram(hw); } return E1000_SUCCESS; } @@ -3645,12 +4087,16 @@ em_write_eeprom(struct em_hw *hw, /* A check for invalid values: offset too large, too many words, and not * enough words. */ - if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) || + if((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) || (words == 0)) { DEBUGOUT("\"words\" parameter out of bounds\n"); return -E1000_ERR_EEPROM; } + /* 82573 reads only through eerd */ + if(eeprom->use_eewr == TRUE) + return em_write_eeprom_eewr(hw, offset, words, data); + /* Prepare the EEPROM for writing */ if (em_acquire_eeprom(hw) != E1000_SUCCESS) return -E1000_ERR_EEPROM; @@ -3821,6 +4267,65 @@ em_write_eeprom_microwire(struct em_hw *hw, } /****************************************************************************** + * Flushes the cached eeprom to NVM. This is done by saving the modified values + * in the eeprom cache and the non modified values in the currently active bank + * to the new bank. + * + * hw - Struct containing variables accessed by shared code + * offset - offset of word in the EEPROM to read + * data - word read from the EEPROM + * words - number of words to read + *****************************************************************************/ +int32_t +em_commit_shadow_ram(struct em_hw *hw) +{ + uint32_t attempts = 100000; + uint32_t eecd = 0; + uint32_t flop = 0; + uint32_t i = 0; + int32_t error = E1000_SUCCESS; + + /* The flop register will be used to determine if flash type is STM */ + flop = E1000_READ_REG(hw, FLOP); + + if (hw->mac_type == em_82573) { + for (i=0; i < attempts; i++) { + eecd = E1000_READ_REG(hw, EECD); + if ((eecd & E1000_EECD_FLUPD) == 0) { + break; + } + usec_delay(5); + } + + if (i == attempts) { + return -E1000_ERR_EEPROM; + } + + /* If STM opcode located in bits 15:8 of flop, reset firmware */ + if ((flop & 0xFF00) == E1000_STM_OPCODE) { + E1000_WRITE_REG(hw, HICR, E1000_HICR_FW_RESET); + } + + /* Perform the flash update */ + E1000_WRITE_REG(hw, EECD, eecd | E1000_EECD_FLUPD); + + for (i=0; i < attempts; i++) { + eecd = E1000_READ_REG(hw, EECD); + if ((eecd & E1000_EECD_FLUPD) == 0) { + break; + } + usec_delay(5); + } + + if (i == attempts) { + return -E1000_ERR_EEPROM; + } + } + + return error; +} + +/****************************************************************************** * Reads the adapter's part number from the EEPROM * * hw - Struct containing variables accessed by shared code @@ -3899,6 +4404,7 @@ void em_init_rx_addrs(struct em_hw *hw) { uint32_t i; + uint32_t rar_num; DEBUGFUNC("em_init_rx_addrs"); @@ -3907,9 +4413,10 @@ em_init_rx_addrs(struct em_hw *hw) em_rar_set(hw, hw->mac_addr, 0); + rar_num = E1000_RAR_ENTRIES; /* Zero out the other 15 receive addresses. */ DEBUGOUT("Clearing RAR[1-15]\n"); - for(i = 1; i < E1000_RAR_ENTRIES; i++) { + for(i = 1; i < rar_num; i++) { E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); } @@ -3938,7 +4445,9 @@ em_mc_addr_list_update(struct em_hw *hw, { uint32_t hash_value; uint32_t i; - + uint32_t num_rar_entry; + uint32_t num_mta_entry; + DEBUGFUNC("em_mc_addr_list_update"); /* Set the new number of MC addresses that we are being requested to use. */ @@ -3946,14 +4455,16 @@ em_mc_addr_list_update(struct em_hw *hw, /* Clear RAR[1-15] */ DEBUGOUT(" Clearing RAR[1-15]\n"); - for(i = rar_used_count; i < E1000_RAR_ENTRIES; i++) { + num_rar_entry = E1000_RAR_ENTRIES; + for(i = rar_used_count; i < num_rar_entry; i++) { E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); } /* Clear the MTA */ DEBUGOUT(" Clearing MTA\n"); - for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++) { + num_mta_entry = E1000_NUM_MTA_REGISTERS; + for(i = 0; i < num_mta_entry; i++) { E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); } @@ -3977,7 +4488,7 @@ em_mc_addr_list_update(struct em_hw *hw, /* Place this multicast address in the RAR if there is room, * * else put it in the MTA */ - if(rar_used_count < E1000_RAR_ENTRIES) { + if (rar_used_count < num_rar_entry) { em_rar_set(hw, mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)), rar_used_count); @@ -4028,6 +4539,7 @@ em_hash_mc_addr(struct em_hw *hw, } hash_value &= 0xFFF; + return hash_value; } @@ -4132,12 +4644,33 @@ void em_clear_vfta(struct em_hw *hw) { uint32_t offset; - - for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) - E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0); + uint32_t vfta_value = 0; + uint32_t vfta_offset = 0; + uint32_t vfta_bit_in_reg = 0; + + if (hw->mac_type == em_82573) { + if (hw->mng_cookie.vlan_id != 0) { + /* The VFTA is a 4096b bit-field, each identifying a single VLAN + * ID. The following operations determine which 32b entry + * (i.e. offset) into the array we want to set the VLAN ID + * (i.e. bit) of the manageability unit. */ + vfta_offset = (hw->mng_cookie.vlan_id >> + E1000_VFTA_ENTRY_SHIFT) & + E1000_VFTA_ENTRY_MASK; + vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id & + E1000_VFTA_ENTRY_BIT_SHIFT_MASK); + } + } + for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { + /* If the offset we want to clear is the same offset of the + * manageability VLAN ID, then clear all bits except that of the + * manageability unit */ + vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0; + E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value); + } } -static int32_t +int32_t em_id_led_init(struct em_hw * hw) { uint32_t ledctl; @@ -4468,6 +5001,19 @@ em_clear_hw_cntrs(struct em_hw *hw) temp = E1000_READ_REG(hw, MGTPRC); temp = E1000_READ_REG(hw, MGTPDC); temp = E1000_READ_REG(hw, MGTPTC); + + if(hw->mac_type <= em_82547_rev_2) return; + + temp = E1000_READ_REG(hw, IAC); + temp = E1000_READ_REG(hw, ICRXOC); + temp = E1000_READ_REG(hw, ICRXPTC); + temp = E1000_READ_REG(hw, ICRXATC); + temp = E1000_READ_REG(hw, ICTXPTC); + temp = E1000_READ_REG(hw, ICTXATC); + temp = E1000_READ_REG(hw, ICTXQEC); + temp = E1000_READ_REG(hw, ICTXQMTC); + temp = E1000_READ_REG(hw, ICRXDMTC); + } /****************************************************************************** @@ -4627,41 +5173,49 @@ em_get_bus_info(struct em_hw *hw) { uint32_t status; - if(hw->mac_type < em_82543) { + switch (hw->mac_type) { + case em_82542_rev2_0: + case em_82542_rev2_1: hw->bus_type = em_bus_type_unknown; hw->bus_speed = em_bus_speed_unknown; hw->bus_width = em_bus_width_unknown; - return; - } - - status = E1000_READ_REG(hw, STATUS); - hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? - em_bus_type_pcix : em_bus_type_pci; - - if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) { - hw->bus_speed = (hw->bus_type == em_bus_type_pci) ? - em_bus_speed_66 : em_bus_speed_120; - } else if(hw->bus_type == em_bus_type_pci) { - hw->bus_speed = (status & E1000_STATUS_PCI66) ? - em_bus_speed_66 : em_bus_speed_33; - } else { - switch (status & E1000_STATUS_PCIX_SPEED) { - case E1000_STATUS_PCIX_SPEED_66: - hw->bus_speed = em_bus_speed_66; - break; - case E1000_STATUS_PCIX_SPEED_100: - hw->bus_speed = em_bus_speed_100; - break; - case E1000_STATUS_PCIX_SPEED_133: - hw->bus_speed = em_bus_speed_133; - break; - default: - hw->bus_speed = em_bus_speed_reserved; - break; + break; + case em_82573: + hw->bus_type = em_bus_type_pci_express; + hw->bus_speed = em_bus_speed_2500; + hw->bus_width = em_bus_width_pciex_4; + break; + default: + status = E1000_READ_REG(hw, STATUS); + hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? + em_bus_type_pcix : em_bus_type_pci; + + if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) { + hw->bus_speed = (hw->bus_type == em_bus_type_pci) ? + em_bus_speed_66 : em_bus_speed_120; + } else if(hw->bus_type == em_bus_type_pci) { + hw->bus_speed = (status & E1000_STATUS_PCI66) ? + em_bus_speed_66 : em_bus_speed_33; + } else { + switch (status & E1000_STATUS_PCIX_SPEED) { + case E1000_STATUS_PCIX_SPEED_66: + hw->bus_speed = em_bus_speed_66; + break; + case E1000_STATUS_PCIX_SPEED_100: + hw->bus_speed = em_bus_speed_100; + break; + case E1000_STATUS_PCIX_SPEED_133: + hw->bus_speed = em_bus_speed_133; + break; + default: + hw->bus_speed = em_bus_speed_reserved; + break; + } } + hw->bus_width = (status & E1000_STATUS_BUS64) ? + em_bus_width_64 : em_bus_width_32; + break; } - hw->bus_width = (status & E1000_STATUS_BUS64) ? - em_bus_width_64 : em_bus_width_32; } /****************************************************************************** * Reads a value from one of the devices registers using port I/O (as opposed @@ -4726,6 +5280,7 @@ em_get_cable_length(struct em_hw *hw, uint16_t agc_value = 0; uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE; uint16_t i, phy_data; + uint16_t cable_length; DEBUGFUNC("em_get_cable_length"); @@ -4733,14 +5288,16 @@ em_get_cable_length(struct em_hw *hw, /* Use old method for Phy older than IGP */ if(hw->phy_type == em_phy_m88) { + ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if(ret_val) return ret_val; + cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> + M88E1000_PSSR_CABLE_LENGTH_SHIFT; /* Convert the enum value to ranged values */ - switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> - M88E1000_PSSR_CABLE_LENGTH_SHIFT) { + switch (cable_length) { case em_cable_length_50: *min_length = 0; *max_length = em_igp_cable_length_50; @@ -4848,7 +5405,8 @@ em_check_polarity(struct em_hw *hw, return ret_val; *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >> M88E1000_PSSR_REV_POLARITY_SHIFT; - } else if(hw->phy_type == em_phy_igp) { + } else if(hw->phy_type == em_phy_igp || + hw->phy_type == em_phy_igp_2) { /* Read the Status register to check the speed */ ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data); @@ -4900,15 +5458,15 @@ em_check_downshift(struct em_hw *hw) DEBUGFUNC("em_check_downshift"); - if(hw->phy_type == em_phy_igp) { + if(hw->phy_type == em_phy_igp || + hw->phy_type == em_phy_igp_2) { ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data); if(ret_val) return ret_val; hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0; - } - else if(hw->phy_type == em_phy_m88) { + } else if(hw->phy_type == em_phy_m88) { ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if(ret_val) @@ -4917,6 +5475,7 @@ em_check_downshift(struct em_hw *hw) hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >> M88E1000_PSSR_DOWNSHIFT_SHIFT; } + return E1000_SUCCESS; } @@ -4937,7 +5496,7 @@ em_config_dsp_after_link_change(struct em_hw *hw, boolean_t link_up) { int32_t ret_val; - uint16_t phy_data, speed, duplex, i; + uint16_t phy_data, phy_saved_data, speed, duplex, i; uint16_t dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {IGP01E1000_PHY_AGC_PARAM_A, IGP01E1000_PHY_AGC_PARAM_B, @@ -5018,6 +5577,21 @@ em_config_dsp_after_link_change(struct em_hw *hw, } } else { if(hw->dsp_config_state == em_dsp_config_activated) { + /* Save off the current value of register 0x2F5B to be restored at + * the end of the routines. */ + ret_val = em_read_phy_reg(hw, 0x2F5B, &phy_saved_data); + + if(ret_val) + return ret_val; + + /* Disable the PHY transmitter */ + ret_val = em_write_phy_reg(hw, 0x2F5B, 0x0003); + + if(ret_val) + return ret_val; + + msec_delay_irq(20); + ret_val = em_write_phy_reg(hw, 0x0000, IGP01E1000_IEEE_FORCE_GIGA); if(ret_val) @@ -5040,10 +5614,33 @@ em_config_dsp_after_link_change(struct em_hw *hw, if(ret_val) return ret_val; + msec_delay_irq(20); + + /* Now enable the transmitter */ + ret_val = em_write_phy_reg(hw, 0x2F5B, phy_saved_data); + + if(ret_val) + return ret_val; + hw->dsp_config_state = em_dsp_config_enabled; } if(hw->ffe_config_state == em_ffe_config_active) { + /* Save off the current value of register 0x2F5B to be restored at + * the end of the routines. */ + ret_val = em_read_phy_reg(hw, 0x2F5B, &phy_saved_data); + + if(ret_val) + return ret_val; + + /* Disable the PHY transmitter */ + ret_val = em_write_phy_reg(hw, 0x2F5B, 0x0003); + + if(ret_val) + return ret_val; + + msec_delay_irq(20); + ret_val = em_write_phy_reg(hw, 0x0000, IGP01E1000_IEEE_FORCE_GIGA); if(ret_val) @@ -5057,6 +5654,15 @@ em_config_dsp_after_link_change(struct em_hw *hw, IGP01E1000_IEEE_RESTART_AUTONEG); if(ret_val) return ret_val; + + msec_delay_irq(20); + + /* Now enable the transmitter */ + ret_val = em_write_phy_reg(hw, 0x2F5B, phy_saved_data); + + if(ret_val) + return ret_val; + hw->ffe_config_state = em_ffe_config_enabled; } } @@ -5124,45 +5730,168 @@ em_set_d3_lplu_state(struct em_hw *hw, uint16_t phy_data; DEBUGFUNC("em_set_d3_lplu_state"); - if(!((hw->mac_type == em_82541_rev_2) || - (hw->mac_type == em_82547_rev_2))) + if(hw->phy_type != em_phy_igp && hw->phy_type != em_phy_igp_2) return E1000_SUCCESS; /* During driver activity LPLU should not be used or it will attain link * from the lowest speeds starting from 10Mbps. The capability is used for * Dx transitions and states */ - ret_val = em_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data); - if(ret_val) - return ret_val; - - if(!active) { - phy_data &= ~IGP01E1000_GMII_FLEX_SPD; - ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); + if(hw->mac_type == em_82541_rev_2 || hw->mac_type == em_82547_rev_2) { + ret_val = em_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data); if(ret_val) return ret_val; + } else { + ret_val = em_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); + if(ret_val) + return ret_val; + } + + if(!active) { + if(hw->mac_type == em_82541_rev_2 || + hw->mac_type == em_82547_rev_2) { + phy_data &= ~IGP01E1000_GMII_FLEX_SPD; + ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); + if(ret_val) + return ret_val; + } else { + phy_data &= ~IGP02E1000_PM_D3_LPLU; + ret_val = em_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, + phy_data); + if (ret_val) + return ret_val; + } /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during * Dx states where the power conservation is most important. During * driver activity we should enable SmartSpeed, so performance is * maintained. */ + if (hw->smart_speed == em_smart_speed_on) { + ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + &phy_data); + if(ret_val) + return ret_val; + + phy_data |= IGP01E1000_PSCFR_SMART_SPEED; + ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + phy_data); + if(ret_val) + return ret_val; + } else if (hw->smart_speed == em_smart_speed_off) { + ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + &phy_data); + if (ret_val) + return ret_val; + + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; + ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + phy_data); + if(ret_val) + return ret_val; + } + + } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) || + (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) || + (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) { + + if(hw->mac_type == em_82541_rev_2 || + hw->mac_type == em_82547_rev_2) { + phy_data |= IGP01E1000_GMII_FLEX_SPD; + ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); + if(ret_val) + return ret_val; + } else { + phy_data |= IGP02E1000_PM_D3_LPLU; + ret_val = em_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, + phy_data); + if (ret_val) + return ret_val; + } + + /* When LPLU is enabled we should disable SmartSpeed */ ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); if(ret_val) return ret_val; - phy_data |= IGP01E1000_PSCFR_SMART_SPEED; + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data); if(ret_val) return ret_val; - } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) || - (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) || - (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) { + } + return E1000_SUCCESS; +} + +/***************************************************************************** + * + * This function sets the lplu d0 state according to the active flag. When + * activating lplu this function also disables smart speed and vise versa. + * lplu will not be activated unless the device autonegotiation advertisment + * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes. + * hw: Struct containing variables accessed by shared code + * active - true to enable lplu false to disable lplu. + * + * returns: - E1000_ERR_PHY if fail to read/write the PHY + * E1000_SUCCESS at any other case. + * + ****************************************************************************/ + +int32_t +em_set_d0_lplu_state(struct em_hw *hw, + boolean_t active) +{ + int32_t ret_val; + uint16_t phy_data; + DEBUGFUNC("em_set_d0_lplu_state"); + + if(hw->mac_type <= em_82547_rev_2) + return E1000_SUCCESS; - phy_data |= IGP01E1000_GMII_FLEX_SPD; - ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); + ret_val = em_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); if(ret_val) return ret_val; + if (!active) { + phy_data &= ~IGP02E1000_PM_D0_LPLU; + ret_val = em_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); + if (ret_val) + return ret_val; + + /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during + * Dx states where the power conservation is most important. During + * driver activity we should enable SmartSpeed, so performance is + * maintained. */ + if (hw->smart_speed == em_smart_speed_on) { + ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + &phy_data); + if(ret_val) + return ret_val; + + phy_data |= IGP01E1000_PSCFR_SMART_SPEED; + ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + phy_data); + if(ret_val) + return ret_val; + } else if (hw->smart_speed == em_smart_speed_off) { + ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + &phy_data); + if (ret_val) + return ret_val; + + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; + ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + phy_data); + if(ret_val) + return ret_val; + } + + + } else { + + phy_data |= IGP02E1000_PM_D0_LPLU; + ret_val = em_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); + if (ret_val) + return ret_val; + /* When LPLU is enabled we should disable SmartSpeed */ ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); if(ret_val) @@ -5240,3 +5969,679 @@ em_set_vco_speed(struct em_hw *hw) return E1000_SUCCESS; } + +/***************************************************************************** + * This function reads the cookie from ARC ram. + * + * returns: - E1000_SUCCESS . + ****************************************************************************/ +int32_t +em_host_if_read_cookie(struct em_hw * hw, uint8_t *buffer) +{ + uint8_t i; + uint32_t offset = E1000_MNG_DHCP_COOKIE_OFFSET; + uint8_t length = E1000_MNG_DHCP_COOKIE_LENGTH; + + length = (length >> 2); + offset = (offset >> 2); + + for (i = 0; i < length; i++) { + *((uint32_t *) buffer + i) = + E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i); + } + return E1000_SUCCESS; +} + + +/***************************************************************************** + * This function checks whether the HOST IF is enabled for command operaton + * and also checks whether the previous command is completed. + * It busy waits in case of previous command is not completed. + * + * returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or + * timeout + * - E1000_SUCCESS for success. + ****************************************************************************/ +int32_t +em_mng_enable_host_if(struct em_hw * hw) +{ + uint32_t hicr; + uint8_t i; + + /* Check that the host interface is enabled. */ + hicr = E1000_READ_REG(hw, HICR); + if ((hicr & E1000_HICR_EN) == 0) { + DEBUGOUT("E1000_HOST_EN bit disabled.\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + /* check the previous command is completed */ + for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { + hicr = E1000_READ_REG(hw, HICR); + if (!(hicr & E1000_HICR_C)) + break; + msec_delay_irq(1); + } + + if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { + DEBUGOUT("Previous command timeout failed .\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + return E1000_SUCCESS; +} + +/***************************************************************************** + * This function writes the buffer content at the offset given on the host if. + * It also does alignment considerations to do the writes in most efficient way. + * Also fills up the sum of the buffer in *buffer parameter. + * + * returns - E1000_SUCCESS for success. + ****************************************************************************/ +int32_t +em_mng_host_if_write(struct em_hw * hw, uint8_t *buffer, + uint16_t length, uint16_t offset, uint8_t *sum) +{ + uint8_t *tmp; + uint8_t *bufptr = buffer; + uint32_t data; + uint16_t remaining, i, j, prev_bytes; + + /* sum = only sum of the data and it is not checksum */ + + if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) { + return -E1000_ERR_PARAM; + } + + tmp = (uint8_t *)&data; + prev_bytes = offset & 0x3; + offset &= 0xFFFC; + offset >>= 2; + + if (prev_bytes) { + data = E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset); + for (j = prev_bytes; j < sizeof(uint32_t); j++) { + *(tmp + j) = *bufptr++; + *sum += *(tmp + j); + } + E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset, data); + length -= j - prev_bytes; + offset++; + } + + remaining = length & 0x3; + length -= remaining; + + /* Calculate length in DWORDs */ + length >>= 2; + + /* The device driver writes the relevant command block into the + * ram area. */ + for (i = 0; i < length; i++) { + for (j = 0; j < sizeof(uint32_t); j++) { + *(tmp + j) = *bufptr++; + *sum += *(tmp + j); + } + + E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data); + } + if (remaining) { + for (j = 0; j < sizeof(uint32_t); j++) { + if (j < remaining) + *(tmp + j) = *bufptr++; + else + *(tmp + j) = 0; + + *sum += *(tmp + j); + } + E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data); + } + + return E1000_SUCCESS; +} + + +/***************************************************************************** + * This function writes the command header after does the checksum calculation. + * + * returns - E1000_SUCCESS for success. + ****************************************************************************/ +int32_t +em_mng_write_cmd_header(struct em_hw * hw, + struct em_host_mng_command_header * hdr) +{ + uint16_t i; + uint8_t sum; + uint8_t *buffer; + + /* Write the whole command header structure which includes sum of + * the buffer */ + + uint16_t length = sizeof(struct em_host_mng_command_header); + + sum = hdr->checksum; + hdr->checksum = 0; + + buffer = (uint8_t *) hdr; + i = length; + while(i--) + sum += buffer[i]; + + hdr->checksum = 0 - sum; + + length >>= 2; + /* The device driver writes the relevant command block into the ram area. */ + for (i = 0; i < length; i++) + E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((uint32_t *) hdr + i)); + + return E1000_SUCCESS; +} + + +/***************************************************************************** + * This function indicates to ARC that a new command is pending which completes + * one write operation by the driver. + * + * returns - E1000_SUCCESS for success. + ****************************************************************************/ +int32_t +em_mng_write_commit( + struct em_hw * hw) +{ + uint32_t hicr; + + hicr = E1000_READ_REG(hw, HICR); + /* Setting this bit tells the ARC that a new command is pending. */ + E1000_WRITE_REG(hw, HICR, hicr | E1000_HICR_C); + + return E1000_SUCCESS; +} + + +/***************************************************************************** + * This function checks the mode of the firmware. + * + * returns - TRUE when the mode is IAMT or FALSE. + ****************************************************************************/ +boolean_t +em_check_mng_mode( + struct em_hw *hw) +{ + uint32_t fwsm; + + fwsm = E1000_READ_REG(hw, FWSM); + + if((fwsm & E1000_FWSM_MODE_MASK) == + (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)) + return TRUE; + + return FALSE; +} + + +/***************************************************************************** + * This function writes the dhcp info . + ****************************************************************************/ +int32_t +em_mng_write_dhcp_info(struct em_hw * hw, uint8_t *buffer, + uint16_t length) +{ + int32_t ret_val; + struct em_host_mng_command_header hdr; + + hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; + hdr.command_length = length; + hdr.reserved1 = 0; + hdr.reserved2 = 0; + hdr.checksum = 0; + + ret_val = em_mng_enable_host_if(hw); + if (ret_val == E1000_SUCCESS) { + ret_val = em_mng_host_if_write(hw, buffer, length, sizeof(hdr), + &(hdr.checksum)); + if (ret_val == E1000_SUCCESS) { + ret_val = em_mng_write_cmd_header(hw, &hdr); + if (ret_val == E1000_SUCCESS) + ret_val = em_mng_write_commit(hw); + } + } + return ret_val; +} + + +/***************************************************************************** + * This function calculates the checksum. + * + * returns - checksum of buffer contents. + ****************************************************************************/ +uint8_t +em_calculate_mng_checksum(char *buffer, uint32_t length) +{ + uint8_t sum = 0; + uint32_t i; + + if (!buffer) + return 0; + + for (i=0; i < length; i++) + sum += buffer[i]; + + return (uint8_t) (0 - sum); +} + +/***************************************************************************** + * This function checks whether tx pkt filtering needs to be enabled or not. + * + * returns - TRUE for packet filtering or FALSE. + ****************************************************************************/ +boolean_t +em_enable_tx_pkt_filtering(struct em_hw *hw) +{ + /* called in init as well as watchdog timer functions */ + + int32_t ret_val, checksum; + boolean_t tx_filter = FALSE; + struct em_host_mng_dhcp_cookie *hdr = &(hw->mng_cookie); + uint8_t *buffer = (uint8_t *) &(hw->mng_cookie); + + if (em_check_mng_mode(hw)) { + ret_val = em_mng_enable_host_if(hw); + if (ret_val == E1000_SUCCESS) { + ret_val = em_host_if_read_cookie(hw, buffer); + if (ret_val == E1000_SUCCESS) { + checksum = hdr->checksum; + hdr->checksum = 0; + if ((hdr->signature == E1000_IAMT_SIGNATURE) && + checksum == em_calculate_mng_checksum((char *)buffer, + E1000_MNG_DHCP_COOKIE_LENGTH)) { + if (hdr->status & + E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT) + tx_filter = TRUE; + } else + tx_filter = TRUE; + } else + tx_filter = TRUE; + } + } + + hw->tx_pkt_filtering = tx_filter; + return tx_filter; +} + +/****************************************************************************** + * Verifies the hardware needs to allow ARPs to be processed by the host + * + * hw - Struct containing variables accessed by shared code + * + * returns: - TRUE/FALSE + * + *****************************************************************************/ +uint32_t +em_enable_mng_pass_thru(struct em_hw *hw) +{ + uint32_t manc; + uint32_t fwsm, factps; + + if (hw->asf_firmware_present) { + manc = E1000_READ_REG(hw, MANC); + + if (!(manc & E1000_MANC_RCV_TCO_EN) || + !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) + return FALSE; + if (em_arc_subsystem_valid(hw) == TRUE) { + fwsm = E1000_READ_REG(hw, FWSM); + factps = E1000_READ_REG(hw, FACTPS); + + if (((fwsm & E1000_FWSM_MODE_MASK) == + (em_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) && + (factps & E1000_FACTPS_MNGCG)) + return TRUE; + } else + if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) + return TRUE; + } + return FALSE; +} + +static int32_t +em_polarity_reversal_workaround(struct em_hw *hw) +{ + int32_t ret_val; + uint16_t mii_status_reg; + uint16_t i; + + /* Polarity reversal workaround for forced 10F/10H links. */ + + /* Disable the transmitter on the PHY */ + + ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); + if(ret_val) + return ret_val; + ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF); + if(ret_val) + return ret_val; + + ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000); + if(ret_val) + return ret_val; + + /* This loop will early-out if the NO link condition has been met. */ + for(i = PHY_FORCE_TIME; i > 0; i--) { + /* Read the MII Status Register and wait for Link Status bit + * to be clear. + */ + + ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); + if(ret_val) + return ret_val; + + ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); + if(ret_val) + return ret_val; + + if((mii_status_reg & ~MII_SR_LINK_STATUS) == 0) break; + msec_delay_irq(100); + } + + /* Recommended delay time after link has been lost */ + msec_delay_irq(1000); + + /* Now we will re-enable th transmitter on the PHY */ + + ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); + if(ret_val) + return ret_val; + msec_delay_irq(50); + ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0); + if(ret_val) + return ret_val; + msec_delay_irq(50); + ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00); + if(ret_val) + return ret_val; + msec_delay_irq(50); + ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000); + if(ret_val) + return ret_val; + + ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000); + if(ret_val) + return ret_val; + + /* This loop will early-out if the link condition has been met. */ + for(i = PHY_FORCE_TIME; i > 0; i--) { + /* Read the MII Status Register and wait for Link Status bit + * to be set. + */ + + ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); + if(ret_val) + return ret_val; + + ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); + if(ret_val) + return ret_val; + + if(mii_status_reg & MII_SR_LINK_STATUS) break; + msec_delay_irq(100); + } + return E1000_SUCCESS; +} + +/*************************************************************************** + * + * Disables PCI-Express master access. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - none. + * + ***************************************************************************/ +void +em_set_pci_express_master_disable(struct em_hw *hw) +{ + uint32_t ctrl; + + DEBUGFUNC("em_set_pci_express_master_disable"); + + if (hw->bus_type != em_bus_type_pci_express) + return; + + ctrl = E1000_READ_REG(hw, CTRL); + ctrl |= E1000_CTRL_GIO_MASTER_DISABLE; + E1000_WRITE_REG(hw, CTRL, ctrl); +} + +/*************************************************************************** + * + * Enables PCI-Express master access. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - none. + * + ***************************************************************************/ +void +em_enable_pciex_master(struct em_hw *hw) +{ + uint32_t ctrl; + + DEBUGFUNC("em_enable_pciex_master"); + + if (hw->bus_type != em_bus_type_pci_express) + return; + + ctrl = E1000_READ_REG(hw, CTRL); + ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE; + E1000_WRITE_REG(hw, CTRL, ctrl); +} + +/******************************************************************************* + * + * Disables PCI-Express master access and verifies there are no pending requests + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_MASTER_REQUESTS_PENDING if master disable bit hasn't + * caused the master requests to be disabled. + * E1000_SUCCESS master requests disabled. + * + ******************************************************************************/ +int32_t +em_disable_pciex_master(struct em_hw *hw) +{ + int32_t timeout = MASTER_DISABLE_TIMEOUT; /* 80ms */ + + DEBUGFUNC("em_disable_pciex_master"); + + if (hw->bus_type != em_bus_type_pci_express) + return E1000_SUCCESS; + + em_set_pci_express_master_disable(hw); + + while(timeout) { + if(!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE)) + break; + else + usec_delay(100); + timeout--; + } + + if(!timeout) { + DEBUGOUT("Master requests are pending.\n"); + return -E1000_ERR_MASTER_REQUESTS_PENDING; + } + + return E1000_SUCCESS; +} + +/******************************************************************************* + * + * Check for EEPROM Auto Read bit done. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_RESET if fail to reset MAC + * E1000_SUCCESS at any other case. + * + ******************************************************************************/ +int32_t +em_get_auto_rd_done(struct em_hw *hw) +{ + int32_t timeout = AUTO_READ_DONE_TIMEOUT; + + DEBUGFUNC("em_get_auto_rd_done"); + + switch (hw->mac_type) { + default: + msec_delay(5); + break; + case em_82573: + while(timeout) { + if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break; + else msec_delay(1); + timeout--; + } + + if(!timeout) { + DEBUGOUT("Auto read by HW from EEPROM has not completed.\n"); + return -E1000_ERR_RESET; + } + break; + } + + return E1000_SUCCESS; +} + +/*************************************************************************** + * Checks if the PHY configuration is done + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_RESET if fail to reset MAC + * E1000_SUCCESS at any other case. + * + ***************************************************************************/ +int32_t +em_get_phy_cfg_done(struct em_hw *hw) +{ + DEBUGFUNC("em_get_phy_cfg_done"); + + /* Simply wait for 10ms */ + msec_delay(10); + + return E1000_SUCCESS; +} + +/*************************************************************************** + * + * Using the combination of SMBI and SWESMBI semaphore bits when resetting + * adapter or Eeprom access. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_EEPROM if fail to access EEPROM. + * E1000_SUCCESS at any other case. + * + ***************************************************************************/ +int32_t +em_get_hw_eeprom_semaphore(struct em_hw *hw) +{ + int32_t timeout; + uint32_t swsm; + + DEBUGFUNC("em_get_hw_eeprom_semaphore"); + + if(!hw->eeprom_semaphore_present) + return E1000_SUCCESS; + + + /* Get the FW semaphore. */ + timeout = hw->eeprom.word_size + 1; + while(timeout) { + swsm = E1000_READ_REG(hw, SWSM); + swsm |= E1000_SWSM_SWESMBI; + E1000_WRITE_REG(hw, SWSM, swsm); + /* if we managed to set the bit we got the semaphore. */ + swsm = E1000_READ_REG(hw, SWSM); + if(swsm & E1000_SWSM_SWESMBI) + break; + + usec_delay(50); + timeout--; + } + + if(!timeout) { + /* Release semaphores */ + em_put_hw_eeprom_semaphore(hw); + DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n"); + return -E1000_ERR_EEPROM; + } + + return E1000_SUCCESS; +} + +/*************************************************************************** + * This function clears HW semaphore bits. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - None. + * + ***************************************************************************/ +void +em_put_hw_eeprom_semaphore(struct em_hw *hw) +{ + uint32_t swsm; + + DEBUGFUNC("em_put_hw_eeprom_semaphore"); + + if(!hw->eeprom_semaphore_present) + return; + + swsm = E1000_READ_REG(hw, SWSM); + /* Release both semaphores. */ + swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); + E1000_WRITE_REG(hw, SWSM, swsm); +} + +/****************************************************************************** + * Checks if PHY reset is blocked due to SOL/IDER session, for example. + * Returning E1000_BLK_PHY_RESET isn't necessarily an error. But it's up to + * the caller to figure out how to deal with it. + * + * hw - Struct containing variables accessed by shared code + * + * returns: - E1000_BLK_PHY_RESET + * E1000_SUCCESS + * + *****************************************************************************/ +int32_t +em_check_phy_reset_block(struct em_hw *hw) +{ + uint32_t manc = 0; + if(hw->mac_type > em_82547_rev_2) + manc = E1000_READ_REG(hw, MANC); + return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? + E1000_BLK_PHY_RESET : E1000_SUCCESS; +} + +uint8_t +em_arc_subsystem_valid(struct em_hw *hw) +{ + uint32_t fwsm; + + /* On 8257x silicon, registers in the range of 0x8800 - 0x8FFC + * may not be provided a DMA clock when no manageability features are + * enabled. We do not want to perform any reads/writes to these registers + * if this is the case. We read FWSM to determine the manageability mode. + */ + switch (hw->mac_type) { + case em_82573: + fwsm = E1000_READ_REG(hw, FWSM); + if((fwsm & E1000_FWSM_MODE_MASK) != 0) + return TRUE; + break; + default: + break; + } + return FALSE; +} diff --git a/sys/dev/pci/if_em_hw.h b/sys/dev/pci/if_em_hw.h index 3d9885e2f8c..8c19bf04f66 100644 --- a/sys/dev/pci/if_em_hw.h +++ b/sys/dev/pci/if_em_hw.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright (c) 2001-2003, Intel Corporation + Copyright (c) 2001-2005, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,8 +31,8 @@ *******************************************************************************/ -/* $FreeBSD: if_em_hw.h,v 1.14 2004/09/01 23:22:41 pdeuskar Exp $ */ -/* $OpenBSD: if_em_hw.h,v 1.7 2005/03/27 16:38:13 brad Exp $ */ +/* $OpenBSD: if_em_hw.h,v 1.8 2005/07/02 06:15:44 deraadt Exp $ */ +/* $FreeBSD: if_em_hw.h,v 1.15 2005/05/26 23:32:02 tackerman Exp $ */ /* if_em_hw.h * Structures, enums, and macros for the MAC */ @@ -40,14 +40,8 @@ #ifndef _EM_HW_H_ #define _EM_HW_H_ -#define NO_VERSION_CONTROL - #include <dev/pci/if_em_osdep.h> -#ifndef NO_VERSION_CONTROL -#ident "@(#)$RCSfile: if_em_hw.h,v $$Revision: 1.7 $$Date: 2005/03/27 16:38:13 $" -#endif - /* Forward declarations of structures used by the shared code */ struct em_hw; struct em_hw_stats; @@ -69,6 +63,7 @@ typedef enum { em_82541_rev_2, em_82547, em_82547_rev_2, + em_82573, em_num_macs } em_mac_type; @@ -76,6 +71,7 @@ typedef enum { em_eeprom_uninitialized = 0, em_eeprom_spi, em_eeprom_microwire, + em_eeprom_flash, em_num_eeprom_types } em_eeprom_type; @@ -108,6 +104,7 @@ typedef enum { em_bus_type_unknown = 0, em_bus_type_pci, em_bus_type_pcix, + em_bus_type_pci_express, em_bus_type_reserved } em_bus_type; @@ -119,6 +116,7 @@ typedef enum { em_bus_speed_100, em_bus_speed_120, em_bus_speed_133, + em_bus_speed_2500, em_bus_speed_reserved } em_bus_speed; @@ -127,6 +125,8 @@ typedef enum { em_bus_width_unknown = 0, em_bus_width_32, em_bus_width_64, + em_bus_width_pciex_1, + em_bus_width_pciex_4, em_bus_width_reserved } em_bus_width; @@ -180,6 +180,12 @@ typedef enum { } em_downshift; typedef enum { + em_smart_speed_default = 0, + em_smart_speed_on, + em_smart_speed_off +} em_smart_speed; + +typedef enum { em_polarity_reversal_enabled = 0, em_polarity_reversal_disabled, em_polarity_reversal_undefined = 0xFF @@ -202,6 +208,7 @@ typedef enum { typedef enum { em_phy_m88 = 0, em_phy_igp, + em_phy_igp_2, em_phy_undefined = 0xFF } em_phy_type; @@ -248,9 +255,18 @@ struct em_eeprom_info { uint16_t address_bits; uint16_t delay_usec; uint16_t page_size; + boolean_t use_eerd; + boolean_t use_eewr; }; +/* Flex ASF Information */ +#define E1000_HOST_IF_MAX_SIZE 2048 +typedef enum { + em_byte_align = 0, + em_word_align = 1, + em_dword_align = 2 +} em_align_type; /* Error Codes */ #define E1000_SUCCESS 0 @@ -260,11 +276,16 @@ struct em_eeprom_info { #define E1000_ERR_PARAM 4 #define E1000_ERR_MAC_TYPE 5 #define E1000_ERR_PHY_TYPE 6 +#define E1000_ERR_RESET 9 +#define E1000_ERR_MASTER_REQUESTS_PENDING 10 +#define E1000_ERR_HOST_INTERFACE_COMMAND 11 +#define E1000_BLK_PHY_RESET 12 /* Function prototypes */ /* Initialization */ int32_t em_reset_hw(struct em_hw *hw); int32_t em_init_hw(struct em_hw *hw); +int32_t em_id_led_init(struct em_hw *hw); int32_t em_set_mac_type(struct em_hw *hw); void em_set_media_type(struct em_hw *hw); @@ -281,7 +302,7 @@ int32_t em_force_mac_fc(struct em_hw *hw); /* PHY */ int32_t em_read_phy_reg(struct em_hw *hw, uint32_t reg_addr, uint16_t *phy_data); int32_t em_write_phy_reg(struct em_hw *hw, uint32_t reg_addr, uint16_t data); -void em_phy_hw_reset(struct em_hw *hw); +int32_t em_phy_hw_reset(struct em_hw *hw); int32_t em_phy_reset(struct em_hw *hw); int32_t em_detect_gig_phy(struct em_hw *hw); int32_t em_phy_get_info(struct em_hw *hw, struct em_phy_info *phy_info); @@ -293,13 +314,86 @@ int32_t em_check_downshift(struct em_hw *hw); int32_t em_validate_mdi_setting(struct em_hw *hw); /* EEPROM Functions */ -void em_init_eeprom_params(struct em_hw *hw); +int32_t em_init_eeprom_params(struct em_hw *hw); +boolean_t em_is_onboard_nvm_eeprom(struct em_hw *hw); +int32_t em_read_eeprom_eerd(struct em_hw *hw, uint16_t offset, uint16_t words, uint16_t *data); +int32_t em_write_eeprom_eewr(struct em_hw *hw, uint16_t offset, uint16_t words, uint16_t *data); +int32_t em_poll_eerd_eewr_done(struct em_hw *hw, int eerd); + +/* MNG HOST IF functions */ +uint32_t em_enable_mng_pass_thru(struct em_hw *hw); + +#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64 +#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 /* Host Interface data length */ + +#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 /* Time in ms to process MNG command */ +#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 /* Cookie offset */ +#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 /* Cookie length */ +#define E1000_MNG_IAMT_MODE 0x3 +#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management Technology signature */ + +#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT 0x1 /* DHCP parsing enabled */ +#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT 0x2 /* DHCP parsing enabled */ +#define E1000_VFTA_ENTRY_SHIFT 0x5 +#define E1000_VFTA_ENTRY_MASK 0x7F +#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F + +struct em_host_mng_command_header { + uint8_t command_id; + uint8_t checksum; + uint16_t reserved1; + uint16_t reserved2; + uint16_t command_length; +}; + +struct em_host_mng_command_info { + struct em_host_mng_command_header command_header; /* Command Head/Command Result Head has 4 bytes */ + uint8_t command_data[E1000_HI_MAX_MNG_DATA_LENGTH]; /* Command data can length 0..0x658*/ +}; +#if BYTE_ORDER == BIG_ENDIAN +struct em_host_mng_dhcp_cookie{ + uint32_t signature; + uint16_t vlan_id; + uint8_t reserved0; + uint8_t status; + uint32_t reserved1; + uint8_t checksum; + uint8_t reserved3; + uint16_t reserved2; +}; +#else +struct em_host_mng_dhcp_cookie{ + uint32_t signature; + uint8_t status; + uint8_t reserved0; + uint16_t vlan_id; + uint32_t reserved1; + uint16_t reserved2; + uint8_t reserved3; + uint8_t checksum; +}; +#endif + +int32_t em_mng_write_dhcp_info(struct em_hw *hw, uint8_t *buffer, + uint16_t length); +boolean_t em_check_mng_mode(struct em_hw *hw); +boolean_t em_enable_tx_pkt_filtering(struct em_hw *hw); +int32_t em_mng_enable_host_if(struct em_hw *hw); +int32_t em_mng_host_if_write(struct em_hw *hw, uint8_t *buffer, + uint16_t length, uint16_t offset, uint8_t *sum); +int32_t em_mng_write_cmd_header(struct em_hw* hw, + struct em_host_mng_command_header* hdr); + +int32_t em_mng_write_commit(struct em_hw *hw); + int32_t em_read_eeprom(struct em_hw *hw, uint16_t reg, uint16_t words, uint16_t *data); int32_t em_validate_eeprom_checksum(struct em_hw *hw); int32_t em_update_eeprom_checksum(struct em_hw *hw); int32_t em_write_eeprom(struct em_hw *hw, uint16_t reg, uint16_t words, uint16_t *data); int32_t em_read_part_num(struct em_hw *hw, uint32_t * part_num); int32_t em_read_mac_addr(struct em_hw * hw); +int32_t em_swfw_sync_acquire(struct em_hw *hw, uint16_t mask); +void em_swfw_sync_release(struct em_hw *hw, uint16_t mask); /* Filters (multicast, vlan, receive) */ void em_init_rx_addrs(struct em_hw *hw); @@ -333,6 +427,19 @@ uint32_t em_read_reg_io(struct em_hw *hw, uint32_t offset); void em_write_reg_io(struct em_hw *hw, uint32_t offset, uint32_t value); int32_t em_config_dsp_after_link_change(struct em_hw *hw, boolean_t link_up); int32_t em_set_d3_lplu_state(struct em_hw *hw, boolean_t active); +int32_t em_set_d0_lplu_state(struct em_hw *hw, boolean_t active); +void em_set_pci_express_master_disable(struct em_hw *hw); +void em_enable_pciex_master(struct em_hw *hw); +int32_t em_disable_pciex_master(struct em_hw *hw); +int32_t em_get_auto_rd_done(struct em_hw *hw); +int32_t em_get_phy_cfg_done(struct em_hw *hw); +int32_t em_get_software_semaphore(struct em_hw *hw); +void em_release_software_semaphore(struct em_hw *hw); +int32_t em_check_phy_reset_block(struct em_hw *hw); +int32_t em_get_hw_eeprom_semaphore(struct em_hw *hw); +void em_put_hw_eeprom_semaphore(struct em_hw *hw); +int32_t em_commit_shadow_ram(struct em_hw *hw); +uint8_t em_arc_subsystem_valid(struct em_hw *hw); #define E1000_READ_REG_IO(a, reg) \ em_read_reg_io((a), E1000_##reg) @@ -348,6 +455,7 @@ int32_t em_set_d3_lplu_state(struct em_hw *hw, boolean_t active); #define E1000_DEV_ID_82544GC_COPPER 0x100C #define E1000_DEV_ID_82544GC_LOM 0x100D #define E1000_DEV_ID_82540EM 0x100E +#define E1000_DEV_ID_82541ER_LOM 0x1014 #define E1000_DEV_ID_82540EM_LOM 0x1015 #define E1000_DEV_ID_82540EP_LOM 0x1016 #define E1000_DEV_ID_82540EP 0x1017 @@ -370,7 +478,13 @@ int32_t em_set_d3_lplu_state(struct em_hw *hw, boolean_t active); #define E1000_DEV_ID_82546GB_COPPER 0x1079 #define E1000_DEV_ID_82546GB_FIBER 0x107A #define E1000_DEV_ID_82546GB_SERDES 0x107B +#define E1000_DEV_ID_82546GB_PCIE 0x108A #define E1000_DEV_ID_82547EI 0x1019 +#define E1000_DEV_ID_82547EI_MOBILE 0x101A +#define E1000_DEV_ID_82573E 0x108B +#define E1000_DEV_ID_82573E_IAMT 0x108C + +#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 #define NODE_ADDRESS_SIZE 6 #define ETH_LENGTH_OF_ADDRESS 6 @@ -383,6 +497,7 @@ int32_t em_set_d3_lplu_state(struct em_hw *hw, boolean_t active); #define E1000_REVISION_0 0 #define E1000_REVISION_1 1 #define E1000_REVISION_2 2 +#define E1000_REVISION_3 3 #define SPEED_10 10 #define SPEED_100 100 @@ -390,7 +505,7 @@ int32_t em_set_d3_lplu_state(struct em_hw *hw, boolean_t active); #define HALF_DUPLEX 1 #define FULL_DUPLEX 2 -/* The sizes (in bytes) of an ethernet packet */ +/* The sizes (in bytes) of a ethernet packet */ #define ENET_HEADER_SIZE 14 #define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* With FCS */ #define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */ @@ -402,7 +517,6 @@ int32_t em_set_d3_lplu_state(struct em_hw *hw, boolean_t active); #define CRC_LENGTH ETHERNET_FCS_SIZE #define MAX_JUMBO_FRAME_SIZE 0x3F00 - /* 802.1q VLAN Packet Sizes */ #define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */ @@ -459,14 +573,74 @@ struct em_rx_desc { uint16_t special; }; +/* Receive Descriptor - Extended */ +union em_rx_desc_extended { + struct { + uint64_t buffer_addr; + uint64_t reserved; + } read; + struct { + struct { + uint32_t mrq; /* Multiple Rx Queues */ + union { + uint32_t rss; /* RSS Hash */ + struct { + uint16_t ip_id; /* IP id */ + uint16_t csum; /* Packet Checksum */ + } csum_ip; + } hi_dword; + } lower; + struct { + uint32_t status_error; /* ext status/error */ + uint16_t length; + uint16_t vlan; /* VLAN tag */ + } upper; + } wb; /* writeback */ +}; + +#define MAX_PS_BUFFERS 4 +/* Receive Descriptor - Packet Split */ +union em_rx_desc_packet_split { + struct { + /* one buffer for protocol header(s), three data buffers */ + uint64_t buffer_addr[MAX_PS_BUFFERS]; + } read; + struct { + struct { + uint32_t mrq; /* Multiple Rx Queues */ + union { + uint32_t rss; /* RSS Hash */ + struct { + uint16_t ip_id; /* IP id */ + uint16_t csum; /* Packet Checksum */ + } csum_ip; + } hi_dword; + } lower; + struct { + uint32_t status_error; /* ext status/error */ + uint16_t length0; /* length of buffer 0 */ + uint16_t vlan; /* VLAN tag */ + } middle; + struct { + uint16_t header_status; + uint16_t length[3]; /* length of buffers 1-3 */ + } upper; + uint64_t reserved; + } wb; /* writeback */ +}; + /* Receive Decriptor bit definitions */ #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ #define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ #define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ #define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ +#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */ #define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ #define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ #define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */ +#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */ +#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ +#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */ #define E1000_RXD_ERR_CE 0x01 /* CRC Error */ #define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ #define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ @@ -476,9 +650,20 @@ struct em_rx_desc { #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ #define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ -#define E1000_RXD_SPC_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */ +#define E1000_RXD_SPC_PRI_SHIFT 13 #define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ -#define E1000_RXD_SPC_CFI_SHIFT 0x000C /* CFI is bit 12 */ +#define E1000_RXD_SPC_CFI_SHIFT 12 + +#define E1000_RXDEXT_STATERR_CE 0x01000000 +#define E1000_RXDEXT_STATERR_SE 0x02000000 +#define E1000_RXDEXT_STATERR_SEQ 0x04000000 +#define E1000_RXDEXT_STATERR_CXE 0x10000000 +#define E1000_RXDEXT_STATERR_TCPE 0x20000000 +#define E1000_RXDEXT_STATERR_IPE 0x40000000 +#define E1000_RXDEXT_STATERR_RXE 0x80000000 + +#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 +#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF /* mask to determine if packets should be dropped due to frame errors */ #define E1000_RXD_ERR_FRAME_ERR_MASK ( \ @@ -488,6 +673,14 @@ struct em_rx_desc { E1000_RXD_ERR_CXE | \ E1000_RXD_ERR_RXE) +/* Same mask, but for extended and packet split descriptors */ +#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \ + E1000_RXDEXT_STATERR_CE | \ + E1000_RXDEXT_STATERR_SE | \ + E1000_RXDEXT_STATERR_SEQ | \ + E1000_RXDEXT_STATERR_CXE | \ + E1000_RXDEXT_STATERR_RXE) + /* Transmit Descriptor */ struct em_tx_desc { uint64_t buffer_addr; /* Address of the descriptor's data buffer */ @@ -669,6 +862,7 @@ struct em_ffvt_entry { #define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ #define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ #define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ +#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */ #define E1000_RCTL 0x00100 /* RX Control - RW */ #define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ #define E1000_TXCW 0x00178 /* TX Configuration Word - RW */ @@ -678,9 +872,23 @@ struct em_ffvt_entry { #define E1000_TBT 0x00448 /* TX Burst Timer - RW */ #define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ #define E1000_LEDCTL 0x00E00 /* LED Control - RW */ +#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ +#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */ #define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ +#define E1000_PBS 0x01008 /* Packet Buffer Size */ +#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ +#define E1000_FLASH_UPDATES 1000 +#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ +#define E1000_FLASHT 0x01028 /* FLASH Timer Register */ +#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ +#define E1000_FLSWCTL 0x01030 /* FLASH control register */ +#define E1000_FLSWDATA 0x01034 /* FLASH data register */ +#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */ +#define E1000_FLOP 0x0103C /* FLASH Opcode Register */ +#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */ #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ +#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ #define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ #define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ #define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ @@ -690,6 +898,7 @@ struct em_ffvt_entry { #define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */ #define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */ #define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */ +#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */ #define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */ #define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */ #define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */ @@ -705,6 +914,14 @@ struct em_ffvt_entry { #define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */ #define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */ #define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */ +#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */ +#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */ +#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */ +#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */ +#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */ +#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */ +#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */ +#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */ #define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ #define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ #define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ @@ -763,7 +980,17 @@ struct em_ffvt_entry { #define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */ #define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */ #define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */ +#define E1000_IAC 0x4100 /* Interrupt Assertion Count */ +#define E1000_ICRXPTC 0x4104 /* Interrupt Cause Rx Packet Timer Expire Count */ +#define E1000_ICRXATC 0x4108 /* Interrupt Cause Rx Absolute Timer Expire Count */ +#define E1000_ICTXPTC 0x410C /* Interrupt Cause Tx Packet Timer Expire Count */ +#define E1000_ICTXATC 0x4110 /* Interrupt Cause Tx Absolute Timer Expire Count */ +#define E1000_ICTXQEC 0x4118 /* Interrupt Cause Tx Queue Empty Count */ +#define E1000_ICTXQMTC 0x411C /* Interrupt Cause Tx Queue Minimum Threshold Count */ +#define E1000_ICRXDMTC 0x4120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */ +#define E1000_ICRXOC 0x4124 /* Interrupt Cause Receiver Overrun Count */ #define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */ +#define E1000_RFCTL 0x05008 /* Receive Filter Control*/ #define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */ #define E1000_RA 0x05400 /* Receive Address - RW Array */ #define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */ @@ -781,6 +1008,16 @@ struct em_ffvt_entry { #define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ #define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */ +#define E1000_GCR 0x05B00 /* PCI-Ex Control */ +#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ +#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ +#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */ +#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */ +#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */ +#define E1000_SWSM 0x05B50 /* SW Semaphore */ +#define E1000_FWSM 0x05B54 /* FW Semaphore */ +#define E1000_FFLT_DBG 0x05F04 /* Debug Register */ +#define E1000_HICR 0x08F00 /* Host Inteface Control */ /* Register Set (82542) * * Some of the 82542 registers are located at different offsets than they are @@ -831,6 +1068,18 @@ struct em_ffvt_entry { #define E1000_82542_VFTA 0x00600 #define E1000_82542_LEDCTL E1000_LEDCTL #define E1000_82542_PBA E1000_PBA +#define E1000_82542_PBS E1000_PBS +#define E1000_82542_EEMNGCTL E1000_EEMNGCTL +#define E1000_82542_EEARBC E1000_EEARBC +#define E1000_82542_FLASHT E1000_FLASHT +#define E1000_82542_EEWR E1000_EEWR +#define E1000_82542_FLSWCTL E1000_FLSWCTL +#define E1000_82542_FLSWDATA E1000_FLSWDATA +#define E1000_82542_FLSWCNT E1000_FLSWCNT +#define E1000_82542_FLOP E1000_FLOP +#define E1000_82542_EXTCNF_CTRL E1000_EXTCNF_CTRL +#define E1000_82542_EXTCNF_SIZE E1000_EXTCNF_SIZE +#define E1000_82542_ERT E1000_ERT #define E1000_82542_RXDCTL E1000_RXDCTL #define E1000_82542_RADV E1000_RADV #define E1000_82542_RSRPD E1000_RSRPD @@ -915,6 +1164,38 @@ struct em_ffvt_entry { #define E1000_82542_FFMT E1000_FFMT #define E1000_82542_FFVT E1000_FFVT #define E1000_82542_HOST_IF E1000_HOST_IF +#define E1000_82542_IAM E1000_IAM +#define E1000_82542_EEMNGCTL E1000_EEMNGCTL +#define E1000_82542_PSRCTL E1000_PSRCTL +#define E1000_82542_RAID E1000_RAID +#define E1000_82542_TARC0 E1000_TARC0 +#define E1000_82542_TDBAL1 E1000_TDBAL1 +#define E1000_82542_TDBAH1 E1000_TDBAH1 +#define E1000_82542_TDLEN1 E1000_TDLEN1 +#define E1000_82542_TDH1 E1000_TDH1 +#define E1000_82542_TDT1 E1000_TDT1 +#define E1000_82542_TXDCTL1 E1000_TXDCTL1 +#define E1000_82542_TARC1 E1000_TARC1 +#define E1000_82542_RFCTL E1000_RFCTL +#define E1000_82542_GCR E1000_GCR +#define E1000_82542_GSCL_1 E1000_GSCL_1 +#define E1000_82542_GSCL_2 E1000_GSCL_2 +#define E1000_82542_GSCL_3 E1000_GSCL_3 +#define E1000_82542_GSCL_4 E1000_GSCL_4 +#define E1000_82542_FACTPS E1000_FACTPS +#define E1000_82542_SWSM E1000_SWSM +#define E1000_82542_FWSM E1000_FWSM +#define E1000_82542_FFLT_DBG E1000_FFLT_DBG +#define E1000_82542_IAC E1000_IAC +#define E1000_82542_ICRXPTC E1000_ICRXPTC +#define E1000_82542_ICRXATC E1000_ICRXATC +#define E1000_82542_ICTXPTC E1000_ICTXPTC +#define E1000_82542_ICTXATC E1000_ICTXATC +#define E1000_82542_ICTXQEC E1000_ICTXQEC +#define E1000_82542_ICTXQMTC E1000_ICTXQMTC +#define E1000_82542_ICRXDMTC E1000_ICRXDMTC +#define E1000_82542_ICRXOC E1000_ICRXOC +#define E1000_82542_HICR E1000_HICR /* Statistics counters collected by the MAC */ struct em_hw_stats { @@ -976,11 +1257,21 @@ struct em_hw_stats { uint64_t bptc; uint64_t tsctc; uint64_t tsctfc; + uint64_t iac; + uint64_t icrxptc; + uint64_t icrxatc; + uint64_t ictxptc; + uint64_t ictxatc; + uint64_t ictxqec; + uint64_t ictxqmtc; + uint64_t icrxdmtc; + uint64_t icrxoc; }; /* Structure containing variables used by the shared code (em_hw.c) */ struct em_hw { uint8_t *hw_addr; + uint8_t *flash_address; em_mac_type mac_type; em_phy_type phy_type; uint32_t phy_init_script; @@ -994,6 +1285,8 @@ struct em_hw { em_ms_type master_slave; em_ms_type original_master_slave; em_ffe_config ffe_config_state; + uint32_t asf_firmware_present; + uint32_t eeprom_semaphore_present; unsigned long io_base; uint32_t phy_id; uint32_t phy_revision; @@ -1010,6 +1303,8 @@ struct em_hw { uint32_t ledctl_default; uint32_t ledctl_mode1; uint32_t ledctl_mode2; + boolean_t tx_pkt_filtering; + struct em_host_mng_dhcp_cookie mng_cookie; uint16_t phy_spd_default; uint16_t autoneg_advertised; uint16_t pci_cmd_word; @@ -1035,6 +1330,7 @@ struct em_hw { uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; boolean_t disable_polarity_correction; boolean_t speed_downgraded; + em_smart_speed smart_speed; em_dsp_config dsp_config_state; boolean_t get_link_status; boolean_t serdes_link_down; @@ -1047,17 +1343,23 @@ struct em_hw { boolean_t adaptive_ifs; boolean_t ifs_params_forced; boolean_t in_ifs_mode; + boolean_t mng_reg_access_disabled; }; - #define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */ #define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */ - +#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */ +#define E1000_EEPROM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ +#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */ +#define E1000_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ +#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */ +#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */ /* Register Bit Masks */ /* Device Control */ #define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ #define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */ #define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */ +#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */ #define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */ #define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */ #define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */ @@ -1071,6 +1373,7 @@ struct em_hw { #define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ #define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ +#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */ #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ #define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ @@ -1090,6 +1393,7 @@ struct em_hw { #define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */ #define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ #define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */ +#define E1000_STATUS_FUNC_SHIFT 2 #define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ #define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */ #define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ @@ -1099,6 +1403,8 @@ struct em_hw { #define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ #define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ #define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ +#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */ +#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ #define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */ #define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */ #define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ @@ -1129,6 +1435,18 @@ struct em_hw { #ifndef E1000_EEPROM_GRANT_ATTEMPTS #define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */ #endif +#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */ +#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */ +#define E1000_EECD_SIZE_EX_SHIFT 11 +#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */ +#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */ +#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */ +#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */ +#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ +#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ +#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ +#define E1000_STM_OPCODE 0xDB00 +#define E1000_HICR_FW_RESET 0xC0 /* EEPROM Read */ #define E1000_EERD_START 0x00000001 /* Start Read */ @@ -1172,6 +1490,8 @@ struct em_hw { #define E1000_CTRL_EXT_WR_WMARK_320 0x01000000 #define E1000_CTRL_EXT_WR_WMARK_384 0x02000000 #define E1000_CTRL_EXT_WR_WMARK_448 0x03000000 +#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ +#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */ /* MDI Control */ #define E1000_MDIC_DATA_MASK 0x0000FFFF @@ -1188,14 +1508,17 @@ struct em_hw { /* LED Control */ #define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F #define E1000_LEDCTL_LED0_MODE_SHIFT 0 +#define E1000_LEDCTL_LED0_BLINK_RATE 0x0000020 #define E1000_LEDCTL_LED0_IVRT 0x00000040 #define E1000_LEDCTL_LED0_BLINK 0x00000080 #define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00 #define E1000_LEDCTL_LED1_MODE_SHIFT 8 +#define E1000_LEDCTL_LED1_BLINK_RATE 0x0002000 #define E1000_LEDCTL_LED1_IVRT 0x00004000 #define E1000_LEDCTL_LED1_BLINK 0x00008000 #define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000 #define E1000_LEDCTL_LED2_MODE_SHIFT 16 +#define E1000_LEDCTL_LED2_BLINK_RATE 0x00200000 #define E1000_LEDCTL_LED2_IVRT 0x00400000 #define E1000_LEDCTL_LED2_BLINK 0x00800000 #define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000 @@ -1239,6 +1562,10 @@ struct em_hw { #define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ #define E1000_ICR_TXD_LOW 0x00008000 #define E1000_ICR_SRPD 0x00010000 +#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */ +#define E1000_ICR_MNG 0x00040000 /* Manageability event */ +#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */ +#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ /* Interrupt Cause Set */ #define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ @@ -1256,6 +1583,9 @@ struct em_hw { #define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ #define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW #define E1000_ICS_SRPD E1000_ICR_SRPD +#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */ /* Interrupt Mask Set */ #define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ @@ -1273,6 +1603,9 @@ struct em_hw { #define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ #define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW #define E1000_IMS_SRPD E1000_ICR_SRPD +#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */ /* Interrupt Mask Clear */ #define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */ @@ -1290,6 +1623,9 @@ struct em_hw { #define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ #define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW #define E1000_IMC_SRPD E1000_ICR_SRPD +#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */ /* Receive Control */ #define E1000_RCTL_RST 0x00000001 /* Software reset */ @@ -1302,6 +1638,8 @@ struct em_hw { #define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ #define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ #define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ +#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */ +#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */ #define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ #define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */ #define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */ @@ -1328,6 +1666,34 @@ struct em_hw { #define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ #define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ #define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ +#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */ +#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */ + +/* Use byte values for the following shift parameters + * Usage: + * psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) & + * E1000_PSRCTL_BSIZE0_MASK) | + * ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) & + * E1000_PSRCTL_BSIZE1_MASK) | + * ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) & + * E1000_PSRCTL_BSIZE2_MASK) | + * ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |; + * E1000_PSRCTL_BSIZE3_MASK)) + * where value0 = [128..16256], default=256 + * value1 = [1024..64512], default=4096 + * value2 = [0..64512], default=4096 + * value3 = [0..64512], default=0 + */ + +#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F +#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00 +#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000 +#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000 + +#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */ +#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */ +#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */ +#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */ /* Receive Descriptor */ #define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */ @@ -1342,6 +1708,23 @@ struct em_hw { #define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */ #define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ +/* Header split receive */ +#define E1000_RFCTL_ISCSI_DIS 0x00000001 +#define E1000_RFCTL_ISCSI_DWC_MASK 0x0000003E +#define E1000_RFCTL_ISCSI_DWC_SHIFT 1 +#define E1000_RFCTL_NFSW_DIS 0x00000040 +#define E1000_RFCTL_NFSR_DIS 0x00000080 +#define E1000_RFCTL_NFS_VER_MASK 0x00000300 +#define E1000_RFCTL_NFS_VER_SHIFT 8 +#define E1000_RFCTL_IPV6_DIS 0x00000400 +#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800 +#define E1000_RFCTL_ACK_DIS 0x00001000 +#define E1000_RFCTL_ACKD_DIS 0x00002000 +#define E1000_RFCTL_IPFRSP_DIS 0x00004000 +#define E1000_RFCTL_EXTEN 0x00008000 +#define E1000_RFCTL_IPV6_EX_DIS 0x00010000 +#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000 + /* Receive Descriptor Control */ #define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */ #define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */ @@ -1355,6 +1738,8 @@ struct em_hw { #define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ +#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc. + still to be processed. */ /* Transmit Configuration Word */ #define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */ @@ -1388,12 +1773,15 @@ struct em_hw { #define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ #define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ #define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ +#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ /* Receive Checksum Control */ #define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */ #define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ #define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */ +#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ +#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ /* Definitions for power management and wakeup registers */ /* Wake Up Control */ @@ -1412,6 +1800,7 @@ struct em_hw { #define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ #define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */ #define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */ +#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */ #define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */ #define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */ #define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */ @@ -1447,13 +1836,19 @@ struct em_hw { #define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ #define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery * Filtering */ +#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */ #define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ #define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ +#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ #define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address * filtering */ #define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host * memory */ +#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address + * filtering */ +#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */ +#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */ #define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */ #define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */ #define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */ @@ -1464,11 +1859,97 @@ struct em_hw { #define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ #define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ +/* SW Semaphore Register */ +#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ +#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ +#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */ +#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ + +/* FW Semaphore Register */ +#define E1000_FWSM_MODE_MASK 0x0000000E /* FW mode */ +#define E1000_FWSM_MODE_SHIFT 1 +#define E1000_FWSM_FW_VALID 0x00008000 /* FW established a valid mode */ + +/* FFLT Debug Register */ +#define E1000_FFLT_DBG_INVC 0x00100000 /* Invalid /C/ code handling */ + +typedef enum { + em_mng_mode_none = 0, + em_mng_mode_asf, + em_mng_mode_pt, + em_mng_mode_ipmi, + em_mng_mode_host_interface_only +} em_mng_mode; + +/* Host Inteface Control Register */ +#define E1000_HICR_EN 0x00000001 /* Enable Bit - RO */ +#define E1000_HICR_C 0x00000002 /* Driver sets this bit when done + * to put command in RAM */ +#define E1000_HICR_SV 0x00000004 /* Status Validity */ +#define E1000_HICR_FWR 0x00000080 /* FW reset. Set by the Host */ + +/* Host Interface Command Interface - Address range 0x8800-0x8EFF */ +#define E1000_HI_MAX_DATA_LENGTH 252 /* Host Interface data length */ +#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Number of bytes in range */ +#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Number of dwords in range */ +#define E1000_HI_COMMAND_TIMEOUT 500 /* Time in ms to process HI command */ + +struct em_host_command_header { + uint8_t command_id; + uint8_t command_length; + uint8_t command_options; /* I/F bits for command, status for return */ + uint8_t checksum; +}; +struct em_host_command_info { + struct em_host_command_header command_header; /* Command Head/Command Result Head has 4 bytes */ + uint8_t command_data[E1000_HI_MAX_DATA_LENGTH]; /* Command data can length 0..252 */ +}; + +/* Host SMB register #0 */ +#define E1000_HSMC0R_CLKIN 0x00000001 /* SMB Clock in */ +#define E1000_HSMC0R_DATAIN 0x00000002 /* SMB Data in */ +#define E1000_HSMC0R_DATAOUT 0x00000004 /* SMB Data out */ +#define E1000_HSMC0R_CLKOUT 0x00000008 /* SMB Clock out */ + +/* Host SMB register #1 */ +#define E1000_HSMC1R_CLKIN E1000_HSMC0R_CLKIN +#define E1000_HSMC1R_DATAIN E1000_HSMC0R_DATAIN +#define E1000_HSMC1R_DATAOUT E1000_HSMC0R_DATAOUT +#define E1000_HSMC1R_CLKOUT E1000_HSMC0R_CLKOUT + +/* FW Status Register */ +#define E1000_FWSTS_FWS_MASK 0x000000FF /* FW Status */ + /* Wake Up Packet Length */ #define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */ #define E1000_MDALIGN 4096 +#define E1000_GCR_BEM32 0x00400000 +/* Function Active and Power State to MNG */ +#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003 +#define E1000_FACTPS_LAN0_VALID 0x00000004 +#define E1000_FACTPS_FUNC0_AUX_EN 0x00000008 +#define E1000_FACTPS_FUNC1_POWER_STATE_MASK 0x000000C0 +#define E1000_FACTPS_FUNC1_POWER_STATE_SHIFT 6 +#define E1000_FACTPS_LAN1_VALID 0x00000100 +#define E1000_FACTPS_FUNC1_AUX_EN 0x00000200 +#define E1000_FACTPS_FUNC2_POWER_STATE_MASK 0x00003000 +#define E1000_FACTPS_FUNC2_POWER_STATE_SHIFT 12 +#define E1000_FACTPS_IDE_ENABLE 0x00004000 +#define E1000_FACTPS_FUNC2_AUX_EN 0x00008000 +#define E1000_FACTPS_FUNC3_POWER_STATE_MASK 0x000C0000 +#define E1000_FACTPS_FUNC3_POWER_STATE_SHIFT 18 +#define E1000_FACTPS_SP_ENABLE 0x00100000 +#define E1000_FACTPS_FUNC3_AUX_EN 0x00200000 +#define E1000_FACTPS_FUNC4_POWER_STATE_MASK 0x03000000 +#define E1000_FACTPS_FUNC4_POWER_STATE_SHIFT 24 +#define E1000_FACTPS_IPMI_ENABLE 0x04000000 +#define E1000_FACTPS_FUNC4_AUX_EN 0x08000000 +#define E1000_FACTPS_MNGCG 0x20000000 +#define E1000_FACTPS_LAN_FUNC_SEL 0x40000000 +#define E1000_FACTPS_PM_STATE_CHANGED 0x80000000 + /* EEPROM Commands - Microwire */ #define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */ #define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */ @@ -1478,22 +1959,20 @@ struct em_hw { /* EEPROM Commands - SPI */ #define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ -#define EEPROM_READ_OPCODE_SPI 0x3 /* EEPROM read opcode */ -#define EEPROM_WRITE_OPCODE_SPI 0x2 /* EEPROM write opcode */ -#define EEPROM_A8_OPCODE_SPI 0x8 /* opcode bit-3 = address bit-8 */ -#define EEPROM_WREN_OPCODE_SPI 0x6 /* EEPROM set Write Enable latch */ -#define EEPROM_WRDI_OPCODE_SPI 0x4 /* EEPROM reset Write Enable latch */ -#define EEPROM_RDSR_OPCODE_SPI 0x5 /* EEPROM read Status register */ -#define EEPROM_WRSR_OPCODE_SPI 0x1 /* EEPROM write Status register */ +#define EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */ +#define EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */ +#define EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ +#define EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Enable latch */ +#define EEPROM_WRDI_OPCODE_SPI 0x04 /* EEPROM reset Write Enable latch */ +#define EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status register */ +#define EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status register */ +#define EEPROM_ERASE4K_OPCODE_SPI 0x20 /* EEPROM ERASE 4KB */ +#define EEPROM_ERASE64K_OPCODE_SPI 0xD8 /* EEPROM ERASE 64KB */ +#define EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */ /* EEPROM Size definitions */ -#define EEPROM_SIZE_16KB 0x1800 -#define EEPROM_SIZE_8KB 0x1400 -#define EEPROM_SIZE_4KB 0x1000 -#define EEPROM_SIZE_2KB 0x0C00 -#define EEPROM_SIZE_1KB 0x0800 -#define EEPROM_SIZE_512B 0x0400 -#define EEPROM_SIZE_128B 0x0000 +#define EEPROM_WORD_SIZE_SHIFT 6 +#define EEPROM_SIZE_SHIFT 10 #define EEPROM_SIZE_MASK 0x1C00 /* EEPROM Word Offsets */ @@ -1530,7 +2009,6 @@ struct em_hw { #define IGP_ACTIVITY_LED_ENABLE 0x0300 #define IGP_LED3_MODE 0x07000000 - /* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */ #define EEPROM_SERDES_AMPLITUDE_MASK 0x000F @@ -1607,7 +2085,22 @@ struct em_hw { #define IFS_MIN 40 #define IFS_RATIO 4 +/* Extended Configuration Control and Size */ +#define E1000_EXTCNF_CTRL_PCIE_WRITE_ENABLE 0x00000001 +#define E1000_EXTCNF_CTRL_PHY_WRITE_ENABLE 0x00000002 +#define E1000_EXTCNF_CTRL_D_UD_ENABLE 0x00000004 +#define E1000_EXTCNF_CTRL_D_UD_LATENCY 0x00000008 +#define E1000_EXTCNF_CTRL_D_UD_OWNER 0x00000010 +#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 +#define E1000_EXTCNF_CTRL_MDIO_HW_OWNERSHIP 0x00000040 +#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER 0x1FFF0000 + +#define E1000_EXTCNF_SIZE_EXT_PHY_LENGTH 0x000000FF +#define E1000_EXTCNF_SIZE_EXT_DOCK_LENGTH 0x0000FF00 +#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH 0x00FF0000 + /* PBA constants */ +#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */ #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ #define E1000_PBA_22K 0x0016 #define E1000_PBA_24K 0x0018 @@ -1637,7 +2130,6 @@ struct em_hw { #define PCIX_STATUS_HI_MMRBC_4K 0x3 #define PCIX_STATUS_HI_MMRBC_2K 0x2 - /* Number of bits required to shift right the "pause" bits from the * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register. */ @@ -1658,12 +2150,18 @@ struct em_hw { */ #define ILOS_SHIFT 3 - #define RECEIVE_BUFFER_ALIGN_SIZE (256) /* Number of milliseconds we wait for auto-negotiation to complete */ #define LINK_UP_TIMEOUT 500 +/* Number of 100 microseconds we wait for PCI Express master disable */ +#define MASTER_DISABLE_TIMEOUT 800 +/* Number of milliseconds we wait for Eeprom auto read bit done after MAC reset */ +#define AUTO_READ_DONE_TIMEOUT 10 +/* Number of milliseconds we wait for PHY configuration done after MAC reset */ +#define PHY_CFG_TIMEOUT 40 + #define E1000_TX_BUFFER_SIZE ((uint32_t)1514) /* The carrier extension symbol, as received by the NIC. */ @@ -1706,7 +2204,6 @@ struct em_hw { (((length) > (sc)->min_frame_size) && \ ((length) <= ((sc)->max_frame_size + VLAN_TAG_SIZE + 1))))) - /* Structures, enums, and macros for the PHY */ /* Bit definitions for the Management Data IO (MDIO) and Management Data @@ -1761,6 +2258,7 @@ struct em_hw { #define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */ #define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */ #define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */ +#define IGP02E1000_PHY_POWER_MGMT 0x19 #define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */ /* IGP01E1000 AGC Registers - stores the cable length values*/ @@ -1769,12 +2267,20 @@ struct em_hw { #define IGP01E1000_PHY_AGC_C 0x1472 #define IGP01E1000_PHY_AGC_D 0x1872 +/* IGP02E1000 AGC Registers for cable length values */ +#define IGP02E1000_PHY_AGC_A 0x11B1 +#define IGP02E1000_PHY_AGC_B 0x12B1 +#define IGP02E1000_PHY_AGC_C 0x14B1 +#define IGP02E1000_PHY_AGC_D 0x18B1 + /* IGP01E1000 DSP Reset Register */ #define IGP01E1000_PHY_DSP_RESET 0x1F33 #define IGP01E1000_PHY_DSP_SET 0x1F71 #define IGP01E1000_PHY_DSP_FFE 0x1F35 #define IGP01E1000_PHY_CHANNEL_NUM 4 +#define IGP02E1000_PHY_CHANNEL_NUM 4 + #define IGP01E1000_PHY_AGC_PARAM_A 0x1171 #define IGP01E1000_PHY_AGC_PARAM_B 0x1271 #define IGP01E1000_PHY_AGC_PARAM_C 0x1471 @@ -2059,20 +2565,30 @@ struct em_hw { #define IGP01E1000_MSE_CHANNEL_B 0x0F00 #define IGP01E1000_MSE_CHANNEL_A 0xF000 +#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */ +#define IGP02E1000_PM_D3_LPLU 0x0004 /* Enable LPLU in non-D0a modes */ +#define IGP02E1000_PM_D0_LPLU 0x0002 /* Enable LPLU in D0a mode */ + /* IGP01E1000 DSP reset macros */ #define DSP_RESET_ENABLE 0x0 #define DSP_RESET_DISABLE 0x2 #define E1000_MAX_DSP_RESETS 10 -/* IGP01E1000 AGC Registers */ +/* IGP01E1000 & IGP02E1000 AGC Registers */ #define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */ +#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Coarse - 15:13, Fine - 12:9 */ + +/* IGP02E1000 AGC Register Length 9-bit mask */ +#define IGP02E1000_AGC_LENGTH_MASK 0x7F /* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */ #define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128 +#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128 -/* The precision of the length is +/- 10 meters */ +/* The precision error of the cable length is +/- 10 meters */ #define IGP01E1000_AGC_RANGE 10 +#define IGP02E1000_AGC_RANGE 10 /* IGP01E1000 PCS Initialization register */ /* bits 3:6 in the PCS registers stores the channels polarity */ @@ -2101,6 +2617,9 @@ struct em_hw { #define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500 /* Bit definitions for valid PHY IDs. */ +/* I = Integrated + * E = External + */ #define M88E1000_E_PHY_ID 0x01410C50 #define M88E1000_I_PHY_ID 0x01410C30 #define M88E1011_I_PHY_ID 0x01410C20 @@ -2108,6 +2627,8 @@ struct em_hw { #define M88E1000_12_PHY_ID M88E1000_E_PHY_ID #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID #define M88E1011_I_REV_4 0x04 +#define M88E1111_I_PHY_ID 0x01410CC0 +#define L1LXT971A_PHY_ID 0x001378E0 /* Miscellaneous PHY bit definitions. */ #define PHY_PREAMBLE 0xFFFFFFFF diff --git a/sys/dev/pci/if_em_osdep.h b/sys/dev/pci/if_em_osdep.h index 0037a78e019..581fc1888e3 100644 --- a/sys/dev/pci/if_em_osdep.h +++ b/sys/dev/pci/if_em_osdep.h @@ -31,8 +31,8 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ -/*$FreeBSD: if_em_osdep.h,v 1.11 2003/05/02 21:17:08 pdeuskar Exp $*/ -/* $OpenBSD: if_em_osdep.h,v 1.3 2004/04/18 04:15:01 henric Exp $ */ +/* $OpenBSD: if_em_osdep.h,v 1.4 2005/07/02 06:15:44 deraadt Exp $ */ +/* $FreeBSD: if_em_osdep.h,v 1.11 2003/05/02 21:17:08 pdeuskar Exp $ */ #ifndef _EM_OPENBSD_OS_H_ #define _EM_OPENBSD_OS_H_ @@ -42,6 +42,8 @@ POSSIBILITY OF SUCH DAMAGE. /* The happy-fun DELAY macro is defined in /usr/src/sys/i386/include/clock.h */ #define usec_delay(x) DELAY(x) #define msec_delay(x) DELAY(1000*(x)) +/* TODO: Should we be paranoid about delaying in interrupt context? */ +#define msec_delay_irq(x) DELAY(1000*(x)) #define MSGOUT(S, A, B) printf(S "\n", A, B) #define DEBUGFUNC(F) DEBUGOUT(F); @@ -81,33 +83,53 @@ struct em_osdep bus_addr_t em_iobase; }; -#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS) - -#define E1000_READ_REG(a, reg) \ - bus_space_read_4( ((struct em_osdep *)(a)->back)->mem_bus_space_tag, \ - ((struct em_osdep *)(a)->back)->mem_bus_space_handle, \ - ((a)->mac_type >= em_82543) ? E1000_##reg : E1000_82542_##reg) - -#define E1000_WRITE_REG(a, reg, value) \ - bus_space_write_4( ((struct em_osdep *)(a)->back)->mem_bus_space_tag, \ - ((struct em_osdep *)(a)->back)->mem_bus_space_handle, \ - ((a)->mac_type >= em_82543) ? E1000_##reg : E1000_82542_##reg, \ - value) - -#define E1000_READ_REG_ARRAY(a, reg, offset) \ - bus_space_read_4( ((struct em_osdep *)(a)->back)->mem_bus_space_tag, \ - ((struct em_osdep *)(a)->back)->mem_bus_space_handle, \ - ((a)->mac_type >= em_82543) ? \ - (E1000_##reg + ((offset) << 2)) : \ - (E1000_82542_##reg + ((offset) << 2)) ) - -#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \ - bus_space_write_4( ((struct em_osdep *)(a)->back)->mem_bus_space_tag, \ - ((struct em_osdep *)(a)->back)->mem_bus_space_handle, \ - ((a)->mac_type >= em_82543) ? \ - (E1000_##reg + ((offset) << 2)) : \ - (E1000_82542_##reg + ((offset) << 2)), \ - value) +#define E1000_WRITE_FLUSH(hw) E1000_READ_REG(hw, STATUS) + +/* Read from an absolute offset in the adapter's memory space */ +#define E1000_READ_OFFSET(hw, offset) \ + bus_space_read_4( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \ + ((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \ + offset) + +/* Write to an absolute offset in the adapter's memory space */ +#define E1000_WRITE_OFFSET(hw, offset, value) \ + bus_space_write_4( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \ + ((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \ + offset, \ + value) + +/* Convert a register name to its offset in the adapter's memory space */ +#define E1000_REG_OFFSET(hw, reg) \ + ((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg) + +#define E1000_READ_REG(hw, reg) \ + E1000_READ_OFFSET(hw, E1000_REG_OFFSET(hw, reg)) + +#define E1000_WRITE_REG(hw, reg, value) \ + E1000_WRITE_OFFSET(hw, E1000_REG_OFFSET(hw, reg), value) + +#define E1000_READ_REG_ARRAY(hw, reg, index) \ + E1000_READ_OFFSET(hw, E1000_REG_OFFSET(hw, reg) + ((index) << 2)) + +#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY + +#define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \ + E1000_WRITE_OFFSET(hw, E1000_REG_OFFSET(hw, reg) + ((index) << 2), value) + +#define E1000_WRITE_REG_ARRAY_BYTE(hw, reg, index, value) \ + bus_space_write_1( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \ + ((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \ + E1000_REG_OFFSET(hw, reg) + (index), \ + value) + +#define E1000_WRITE_REG_ARRAY_WORD(hw, reg, index, value) \ + bus_space_write_2( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \ + ((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \ + E1000_REG_OFFSET(hw, reg) + (index), \ + value) + +#define E1000_WRITE_REG_ARRAY_DWORD(hw, reg, index, value) \ + E1000_WRITE_OFFSET(hw, E1000_REG_OFFSET(hw, reg) + ((index) << 2), value) #define em_io_read(hw, port) \ bus_space_read_4(((struct em_osdep *)(hw)->back)->em_iobtag, \ diff --git a/sys/dev/pci/pcidevs.h b/sys/dev/pci/pcidevs.h index 91a9535690a..c336b687964 100644 --- a/sys/dev/pci/pcidevs.h +++ b/sys/dev/pci/pcidevs.h @@ -2,7 +2,7 @@ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * OpenBSD: pcidevs,v 1.883 2005/06/30 03:15:31 deraadt Exp + * OpenBSD: pcidevs,v 1.884 2005/07/02 06:15:39 deraadt Exp */ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ @@ -52,7 +52,7 @@ */ #define PCI_VENDOR_MARTINMARIETTA 0x003d /* Martin-Marietta */ -#define PCI_VENDOR_HAUPPAUGE 0x0070 /* Hauppauge Computer Works */ +#define PCI_VENDOR_HAUPPAUGE 0x0070 /* Hauppauge */ #define PCI_VENDOR_DYNALINK 0x0675 /* Dynalink */ #define PCI_VENDOR_COMPAQ 0x0e11 /* Compaq */ #define PCI_VENDOR_SYMBIOS 0x1000 /* Symbios Logic */ @@ -139,7 +139,7 @@ #define PCI_VENDOR_AMCIRCUITS 0x10e8 /* Applied Micro Circuits */ #define PCI_VENDOR_REALTEK 0x10ec /* Realtek */ #define PCI_VENDOR_NKK 0x10f5 /* NKK */ -#define PCI_VENDOR_IODATA 0x10fc /* IO Data Device Inc */ +#define PCI_VENDOR_IODATA 0x10fc /* IO Data Device */ #define PCI_VENDOR_INITIO 0x1101 /* Initio */ #define PCI_VENDOR_CREATIVELABS 0x1102 /* Creative Labs */ #define PCI_VENDOR_TRIONES 0x1103 /* HighPoint */ @@ -210,7 +210,7 @@ #define PCI_VENDOR_DTCTECH 0x134a /* DTC Tech */ #define PCI_VENDOR_PCTEL 0x134d /* PCTEL */ #define PCI_VENDOR_CNET 0x1371 /* CNet */ -#define PCI_VENDOR_LMC 0x1376 /* LAN Media Corp */ +#define PCI_VENDOR_LMC 0x1376 /* LAN Media */ #define PCI_VENDOR_NETGEAR 0x1385 /* Netgear */ #define PCI_VENDOR_MOXA 0x1393 /* Moxa */ #define PCI_VENDOR_LEVEL1 0x1394 /* Level 1 */ @@ -243,7 +243,7 @@ #define PCI_VENDOR_SYBA 0x1592 /* Syba */ #define PCI_VENDOR_BLUESTEEL 0x15ab /* Bluesteel Networks */ #define PCI_VENDOR_VMWARE 0x15ad /* VMware */ -#define PCI_VENDOR_NDC 0x15e8 /* National Datacomm Corp */ +#define PCI_VENDOR_NDC 0x15e8 /* National Datacomm */ #define PCI_VENDOR_ZOLTRIX 0x15b0 /* Zoltrix */ #define PCI_VENDOR_EUMITCOM 0x1638 /* Eumitcom */ #define PCI_VENDOR_NETSEC 0x1660 /* NetSec */ @@ -450,7 +450,7 @@ #define PCI_PRODUCT_ALI_M5243 0x5243 /* M5243 AGP/PCI-PCI */ #define PCI_PRODUCT_ALI_M5451 0x5451 /* M5451 Audio */ #define PCI_PRODUCT_ALI_M5457 0x5457 /* M5457 Modem */ -#define PCI_PRODUCT_ALI_M7101 0x7101 /* M7101 Power Mgmt */ +#define PCI_PRODUCT_ALI_M7101 0x7101 /* M7101 Power */ /* ADMtek products */ #define PCI_PRODUCT_ADMTEK_AL981 0x0981 /* AL981 */ @@ -569,21 +569,21 @@ #define PCI_PRODUCT_AMD_761_PPB 0x700f /* 761 PCI-PCI */ #define PCI_PRODUCT_AMD_755_ISA 0x7400 /* 755 ISA */ #define PCI_PRODUCT_AMD_755_IDE 0x7401 /* 755 IDE */ -#define PCI_PRODUCT_AMD_755_PMC 0x7403 /* 755 Power Mgmt */ +#define PCI_PRODUCT_AMD_755_PMC 0x7403 /* 755 Power */ #define PCI_PRODUCT_AMD_755_USB 0x7404 /* 755 USB */ /* http://www.amd.com/products/cpg/athlon/techdocs/pdf/22548.pdf */ #define PCI_PRODUCT_AMD_PBC756_ISA 0x7408 /* 756 ISA */ #define PCI_PRODUCT_AMD_PBC756_IDE 0x7409 /* 756 IDE */ -#define PCI_PRODUCT_AMD_PBC756_PMC 0x740b /* 756 Power Mgmt */ +#define PCI_PRODUCT_AMD_PBC756_PMC 0x740b /* 756 Power */ #define PCI_PRODUCT_AMD_PBC756_USB 0x740c /* 756 USB Host */ #define PCI_PRODUCT_AMD_766_ISA 0x7410 /* 766 ISA */ #define PCI_PRODUCT_AMD_766_IDE 0x7411 /* 766 IDE */ #define PCI_PRODUCT_AMD_766_USB 0x7412 /* 766 USB */ -#define PCI_PRODUCT_AMD_766_PMC 0x7413 /* 766 Power Mgmt */ +#define PCI_PRODUCT_AMD_766_PMC 0x7413 /* 766 Power */ #define PCI_PRODUCT_AMD_766_USB_HCI 0x7414 /* 766 USB OpenHCI */ #define PCI_PRODUCT_AMD_PBC768_ISA 0x7440 /* 768 ISA */ #define PCI_PRODUCT_AMD_PBC768_IDE 0x7441 /* 768 IDE */ -#define PCI_PRODUCT_AMD_PBC768_PMC 0x7443 /* 768 Power Mgmt */ +#define PCI_PRODUCT_AMD_PBC768_PMC 0x7443 /* 768 Power */ #define PCI_PRODUCT_AMD_PBC768_ACA 0x7445 /* 768 AC97 */ #define PCI_PRODUCT_AMD_PBC768_MD 0x7446 /* 768 Modem */ #define PCI_PRODUCT_AMD_PBC768_PPB 0x7448 /* 768 PCI-PCI */ @@ -1603,7 +1603,7 @@ #define PCI_PRODUCT_INTEL_82371AB_ISA 0x7110 /* 82371AB PIIX4 ISA */ #define PCI_PRODUCT_INTEL_82371AB_IDE 0x7111 /* 82371AB IDE */ #define PCI_PRODUCT_INTEL_82371AB_USB 0x7112 /* 82371AB USB */ -#define PCI_PRODUCT_INTEL_82371AB_PMC 0x7113 /* 82371AB Power Mgmt */ +#define PCI_PRODUCT_INTEL_82371AB_PMC 0x7113 /* 82371AB Power */ #define PCI_PRODUCT_INTEL_82810_MCH 0x7120 /* 82810 */ #define PCI_PRODUCT_INTEL_82810_GC 0x7121 /* 82810 Graphics */ #define PCI_PRODUCT_INTEL_82810_DC100_MCH 0x7122 /* 82810-DC100 */ @@ -1621,7 +1621,7 @@ #define PCI_PRODUCT_INTEL_82440MX_ISA 0x7198 /* 82440MX ISA */ #define PCI_PRODUCT_INTEL_82440MX_IDE 0x7199 /* 82440MX IDE */ #define PCI_PRODUCT_INTEL_82440MX_USB 0x719a /* 82440MX USB */ -#define PCI_PRODUCT_INTEL_82440MX_PM 0x719b /* 82440MX Power Mgmt */ +#define PCI_PRODUCT_INTEL_82440MX_PM 0x719b /* 82440MX Power */ #define PCI_PRODUCT_INTEL_82440BX 0x71a0 /* 82440BX AGP */ #define PCI_PRODUCT_INTEL_82440BX_AGP 0x71a1 /* 82440BX AGP */ #define PCI_PRODUCT_INTEL_82443GX 0x71a2 /* 82443GX */ @@ -2763,10 +2763,10 @@ #define PCI_PRODUCT_VIATECH_VT82C1595 0x1595 /* VT82C1595 PCI */ #define PCI_PRODUCT_VIATECH_K8HTB_2 0x2282 /* K8HTB Host */ #define PCI_PRODUCT_VIATECH_VT83C572 0x3038 /* VT83C572 USB */ -#define PCI_PRODUCT_VIATECH_VT82C586_PWR 0x3040 /* VT82C586 Power Mgmt */ +#define PCI_PRODUCT_VIATECH_VT82C586_PWR 0x3040 /* VT82C586 Power */ #define PCI_PRODUCT_VIATECH_RHINE 0x3043 /* Rhine/RhineII */ #define PCI_PRODUCT_VIATECH_VT6306 0x3044 /* VT6306 FireWire */ -#define PCI_PRODUCT_VIATECH_VT82C596 0x3050 /* VT82C596 Power Mgmt */ +#define PCI_PRODUCT_VIATECH_VT82C596 0x3050 /* VT82C596 Power */ #define PCI_PRODUCT_VIATECH_VT82C596B_PM 0x3051 /* VT82C596B PM */ #define PCI_PRODUCT_VIATECH_VT6105M 0x3053 /* VT6105M RhineIII */ #define PCI_PRODUCT_VIATECH_VT82C686A_SMB 0x3057 /* VT82C686 SMBus */ diff --git a/sys/dev/pci/pcidevs_data.h b/sys/dev/pci/pcidevs_data.h index 3d60276a553..e78d5afec4b 100644 --- a/sys/dev/pci/pcidevs_data.h +++ b/sys/dev/pci/pcidevs_data.h @@ -2,7 +2,7 @@ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * OpenBSD: pcidevs,v 1.883 2005/06/30 03:15:31 deraadt Exp + * OpenBSD: pcidevs,v 1.884 2005/07/02 06:15:39 deraadt Exp */ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ @@ -576,7 +576,7 @@ static const struct pci_known_product pci_known_products[] = { }, { PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M7101, - "M7101 Power Mgmt", + "M7101 Power", }, { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AL981, @@ -972,7 +972,7 @@ static const struct pci_known_product pci_known_products[] = { }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_755_PMC, - "755 Power Mgmt", + "755 Power", }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_755_USB, @@ -988,7 +988,7 @@ static const struct pci_known_product pci_known_products[] = { }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC756_PMC, - "756 Power Mgmt", + "756 Power", }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC756_USB, @@ -1008,7 +1008,7 @@ static const struct pci_known_product pci_known_products[] = { }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_766_PMC, - "766 Power Mgmt", + "766 Power", }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_766_USB_HCI, @@ -1024,7 +1024,7 @@ static const struct pci_known_product pci_known_products[] = { }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC768_PMC, - "768 Power Mgmt", + "768 Power", }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC768_ACA, @@ -4472,7 +4472,7 @@ static const struct pci_known_product pci_known_products[] = { }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371AB_PMC, - "82371AB Power Mgmt", + "82371AB Power", }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82810_MCH, @@ -4544,7 +4544,7 @@ static const struct pci_known_product pci_known_products[] = { }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82440MX_PM, - "82440MX Power Mgmt", + "82440MX Power", }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82440BX, @@ -8216,7 +8216,7 @@ static const struct pci_known_product pci_known_products[] = { }, { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C586_PWR, - "VT82C586 Power Mgmt", + "VT82C586 Power", }, { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_RHINE, @@ -8228,7 +8228,7 @@ static const struct pci_known_product pci_known_products[] = { }, { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C596, - "VT82C596 Power Mgmt", + "VT82C596 Power", }, { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C596B_PM, @@ -8944,7 +8944,7 @@ static const struct pci_known_vendor pci_known_vendors[] = { }, { PCI_VENDOR_HAUPPAUGE, - "Hauppauge Computer Works", + "Hauppauge", }, { PCI_VENDOR_DYNALINK, @@ -9292,7 +9292,7 @@ static const struct pci_known_vendor pci_known_vendors[] = { }, { PCI_VENDOR_IODATA, - "IO Data Device Inc", + "IO Data Device", }, { PCI_VENDOR_INITIO, @@ -9576,7 +9576,7 @@ static const struct pci_known_vendor pci_known_vendors[] = { }, { PCI_VENDOR_LMC, - "LAN Media Corp", + "LAN Media", }, { PCI_VENDOR_NETGEAR, @@ -9708,7 +9708,7 @@ static const struct pci_known_vendor pci_known_vendors[] = { }, { PCI_VENDOR_NDC, - "National Datacomm Corp", + "National Datacomm", }, { PCI_VENDOR_ZOLTRIX, |