* and the corresponding inplace checks inserted instead.
* Pieces such as LED handling that we definitely don't need are deleted.
*
+ * Please keep the function ordering so that it is easy to produce diffs
+ * against the linux driver.
+ *
* The following defines should not be needed normally,
* but may be helpful for debugging purposes. */
static void e1000_phy_hw_reset(struct e1000_hw *hw);
static int e1000_phy_reset(struct e1000_hw *hw);
static int e1000_detect_gig_phy(struct e1000_hw *hw);
-static void e1000_irq(struct nic *nic, irq_action_t action);
+static int e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static void e1000_init_rx_addrs(struct e1000_hw *hw);
+static void e1000_clear_vfta(struct e1000_hw *hw);
/* Printing macros... */
#define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);}
+
+/******************************************************************************
+ * Inline functions from e1000_main.c of the linux driver
+ ******************************************************************************/
+
+#if 0
static inline uint32_t
e1000_io_read(struct e1000_hw *hw __unused, uint32_t port)
{
return inl(port);
}
+#endif
static inline void
e1000_io_write(struct e1000_hw *hw __unused, uint32_t port, uint32_t value)
hw->pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
}
+
/******************************************************************************
- * Raises the EEPROM's clock input.
- *
- * hw - Struct containing variables accessed by shared code
- * eecd - EECD's current value
- *****************************************************************************/
-static void
-e1000_raise_ee_clk(struct e1000_hw *hw,
- uint32_t *eecd)
-{
- /* Raise the clock input to the EEPROM (by setting the SK bit), and then
- * wait <delay> microseconds.
- */
- *eecd = *eecd | E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, *eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(hw->eeprom.delay_usec);
-}
+ * Inline functions from e1000_hw.c of the linux driver
+ ******************************************************************************/
/******************************************************************************
- * Lowers the EEPROM's clock input.
- *
- * hw - Struct containing variables accessed by shared code
- * eecd - EECD's current value
- *****************************************************************************/
-static void
-e1000_lower_ee_clk(struct e1000_hw *hw,
- uint32_t *eecd)
-{
- /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
- * wait 50 microseconds.
- */
- *eecd = *eecd & ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, *eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(hw->eeprom.delay_usec);
+* Writes a value to one of the devices registers using port I/O (as opposed to
+* memory mapped I/O). Only 82544 and newer devices support port I/O. *
+* hw - Struct containing variables accessed by shared code
+* offset - offset to write to * value - value to write
+*****************************************************************************/
+static inline void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset,
+ uint32_t value){
+ e1000_io_write(hw, hw->io_base, offset);
+ e1000_io_write(hw, hw->io_base + 4, value);
}
-/******************************************************************************
- * Shift data bits out to the EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * data - data to send to the EEPROM
- * count - number of bits to shift out
- *****************************************************************************/
-static void
-e1000_shift_out_ee_bits(struct e1000_hw *hw,
- uint16_t data,
- uint16_t count)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd;
- uint32_t mask;
-
- /* We need to shift "count" bits out to the EEPROM. So, value in the
- * "data" parameter will be shifted out to the EEPROM one bit at a time.
- * In order to do this, "data" must be broken down into bits.
- */
- mask = 0x01 << (count - 1);
- eecd = E1000_READ_REG(hw, EECD);
- if (eeprom->type == e1000_eeprom_microwire) {
- eecd &= ~E1000_EECD_DO;
- } else if (eeprom->type == e1000_eeprom_spi) {
- eecd |= E1000_EECD_DO;
- }
- do {
- /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
- * and then raising and then lowering the clock (the SK bit controls
- * the clock input to the EEPROM). A "0" is shifted out to the EEPROM
- * by setting "DI" to "0" and then raising and then lowering the clock.
- */
- eecd &= ~E1000_EECD_DI;
-
- if(data & mask)
- eecd |= E1000_EECD_DI;
-
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-
- udelay(eeprom->delay_usec);
-
- e1000_raise_ee_clk(hw, &eecd);
- e1000_lower_ee_clk(hw, &eecd);
-
- mask = mask >> 1;
-
- } while(mask);
- /* We leave the "DI" bit set to "0" when we leave this routine. */
- eecd &= ~E1000_EECD_DI;
- E1000_WRITE_REG(hw, EECD, eecd);
-}
+/******************************************************************************
+ * Functions from e1000_hw.c of the linux driver
+ ******************************************************************************/
/******************************************************************************
- * Shift data bits in from the EEPROM
+ * Set the phy type member in the hw struct.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-static uint16_t
-e1000_shift_in_ee_bits(struct e1000_hw *hw,
- uint16_t count)
+static int32_t
+e1000_set_phy_type(struct e1000_hw *hw)
{
- uint32_t eecd;
- uint32_t i;
- uint16_t data;
-
- /* In order to read a register from the EEPROM, we need to shift 'count'
- * bits in from the EEPROM. Bits are "shifted in" by raising the clock
- * input to the EEPROM (setting the SK bit), and then reading the value of
- * the "DO" bit. During this "shifting in" process the "DI" bit should
- * always be clear.
- */
-
- eecd = E1000_READ_REG(hw, EECD);
-
- eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
- data = 0;
-
- for(i = 0; i < count; i++) {
- data = data << 1;
- e1000_raise_ee_clk(hw, &eecd);
-
- eecd = E1000_READ_REG(hw, EECD);
-
- eecd &= ~(E1000_EECD_DI);
- if(eecd & E1000_EECD_DO)
- data |= 1;
-
- e1000_lower_ee_clk(hw, &eecd);
+ DEBUGFUNC("e1000_set_phy_type");
+
+ switch(hw->phy_id) {
+ case M88E1000_E_PHY_ID:
+ case M88E1000_I_PHY_ID:
+ case M88E1011_I_PHY_ID:
+ hw->phy_type = e1000_phy_m88;
+ break;
+ case IGP01E1000_I_PHY_ID:
+ hw->phy_type = e1000_phy_igp;
+ break;
+ default:
+ /* Should never have loaded on this device */
+ hw->phy_type = e1000_phy_undefined;
+ return -E1000_ERR_PHY_TYPE;
}
-
- return data;
+
+ return E1000_SUCCESS;
}
/******************************************************************************
- * Prepares EEPROM for access
+ * IGP phy init script - initializes the GbE PHY
*
* hw - Struct containing variables accessed by shared code
- *
- * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
- * function should be called before issuing a command to the EEPROM.
*****************************************************************************/
-static int32_t
-e1000_acquire_eeprom(struct e1000_hw *hw)
+static void
+e1000_phy_init_script(struct e1000_hw *hw)
{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd, i=0;
+ DEBUGFUNC("e1000_phy_init_script");
- eecd = E1000_READ_REG(hw, EECD);
+#if 0
+ /* See e1000_sw_init() of the Linux driver */
+ if(hw->phy_init_script) {
+#else
+ if((hw->mac_type == e1000_82541) ||
+ (hw->mac_type == e1000_82547) ||
+ (hw->mac_type == e1000_82541_rev_2) ||
+ (hw->mac_type == e1000_82547_rev_2)) {
+#endif
+ mdelay(20);
- /* Request EEPROM Access */
- if(hw->mac_type > e1000_82544) {
- eecd |= E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
- eecd = E1000_READ_REG(hw, EECD);
- while((!(eecd & E1000_EECD_GNT)) &&
- (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
- i++;
- udelay(5);
- eecd = E1000_READ_REG(hw, EECD);
- }
- if(!(eecd & E1000_EECD_GNT)) {
- eecd &= ~E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
- DEBUGOUT("Could not acquire EEPROM grant\n");
- return -E1000_ERR_EEPROM;
- }
- }
+ e1000_write_phy_reg(hw,0x0000,0x0140);
- /* Setup EEPROM for Read/Write */
+ mdelay(5);
- if (eeprom->type == e1000_eeprom_microwire) {
- /* Clear SK and DI */
- eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
- E1000_WRITE_REG(hw, EECD, eecd);
+ if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
+ e1000_write_phy_reg(hw, 0x1F95, 0x0001);
- /* Set CS */
- eecd |= E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- } else if (eeprom->type == e1000_eeprom_spi) {
- /* Clear SK and CS */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- E1000_WRITE_REG(hw, EECD, eecd);
- udelay(1);
- }
+ e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
- return E1000_SUCCESS;
-}
+ e1000_write_phy_reg(hw, 0x1F79, 0x0018);
-/******************************************************************************
- * Returns EEPROM to a "standby" state
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void
-e1000_standby_eeprom(struct e1000_hw *hw)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd;
-
- eecd = E1000_READ_REG(hw, EECD);
+ e1000_write_phy_reg(hw, 0x1F30, 0x1600);
- if(eeprom->type == e1000_eeprom_microwire) {
+ e1000_write_phy_reg(hw, 0x1F31, 0x0014);
- /* Deselect EEPROM */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(eeprom->delay_usec);
-
- /* Clock high */
- eecd |= E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(eeprom->delay_usec);
-
- /* Select EEPROM */
- eecd |= E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(eeprom->delay_usec);
+ e1000_write_phy_reg(hw, 0x1F32, 0x161C);
- /* Clock low */
- eecd &= ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(eeprom->delay_usec);
- } else if(eeprom->type == e1000_eeprom_spi) {
- /* Toggle CS to flush commands */
- eecd |= E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(eeprom->delay_usec);
- eecd &= ~E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(eeprom->delay_usec);
- }
-}
+ e1000_write_phy_reg(hw, 0x1F94, 0x0003);
-/******************************************************************************
- * Terminates a command by inverting the EEPROM's chip select pin
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void
-e1000_release_eeprom(struct e1000_hw *hw)
-{
- uint32_t eecd;
+ e1000_write_phy_reg(hw, 0x1F96, 0x003F);
- eecd = E1000_READ_REG(hw, EECD);
+ e1000_write_phy_reg(hw, 0x2010, 0x0008);
+ } else {
+ e1000_write_phy_reg(hw, 0x1F73, 0x0099);
+ }
- if (hw->eeprom.type == e1000_eeprom_spi) {
- eecd |= E1000_EECD_CS; /* Pull CS high */
- eecd &= ~E1000_EECD_SK; /* Lower SCK */
+ e1000_write_phy_reg(hw, 0x0000, 0x3300);
- E1000_WRITE_REG(hw, EECD, eecd);
- udelay(hw->eeprom.delay_usec);
- } else if(hw->eeprom.type == e1000_eeprom_microwire) {
- /* cleanup eeprom */
+ if(hw->mac_type == e1000_82547) {
+ uint16_t fused, fine, coarse;
- /* CS on Microwire is active-high */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+ /* Move to analog registers page */
+ e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
- E1000_WRITE_REG(hw, EECD, eecd);
+ if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
+ e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused);
- /* Rising edge of clock */
- eecd |= E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(hw->eeprom.delay_usec);
+ fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
+ coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
- /* Falling edge of clock */
- eecd &= ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- udelay(hw->eeprom.delay_usec);
- }
+ if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
+ coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10;
+ fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
+ } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
+ fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
- /* Stop requesting EEPROM access */
- if(hw->mac_type > e1000_82544) {
- eecd &= ~E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
+ fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
+ (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
+ (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);
+
+ e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
+ e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
+ IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
+ }
+ }
}
}
/******************************************************************************
- * Reads a 16 bit word from the EEPROM.
- *
+ * Set the mac type member in the hw struct.
+ *
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-static int32_t
-e1000_spi_eeprom_ready(struct e1000_hw *hw)
+static int
+e1000_set_mac_type(struct e1000_hw *hw)
{
- uint16_t retry_count = 0;
- uint8_t spi_stat_reg;
+ DEBUGFUNC("e1000_set_mac_type");
- /* Read "Status Register" repeatedly until the LSB is cleared. The
- * EEPROM will signal that the command has been completed by clearing
- * bit 0 of the internal status register. If it's not cleared within
- * 5 milliseconds, then error out.
- */
- retry_count = 0;
- do {
- e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
- hw->eeprom.opcode_bits);
- spi_stat_reg = (uint8_t)e1000_shift_in_ee_bits(hw, 8);
- if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
+ switch (hw->device_id) {
+ case E1000_DEV_ID_82542:
+ switch (hw->revision_id) {
+ case E1000_82542_2_0_REV_ID:
+ hw->mac_type = e1000_82542_rev2_0;
break;
+ case E1000_82542_2_1_REV_ID:
+ hw->mac_type = e1000_82542_rev2_1;
+ break;
+ default:
+ /* Invalid 82542 revision ID */
+ return -E1000_ERR_MAC_TYPE;
+ }
+ break;
+ case E1000_DEV_ID_82543GC_FIBER:
+ case E1000_DEV_ID_82543GC_COPPER:
+ hw->mac_type = e1000_82543;
+ break;
+ case E1000_DEV_ID_82544EI_COPPER:
+ case E1000_DEV_ID_82544EI_FIBER:
+ case E1000_DEV_ID_82544GC_COPPER:
+ case E1000_DEV_ID_82544GC_LOM:
+ hw->mac_type = e1000_82544;
+ break;
+ case E1000_DEV_ID_82540EM:
+ case E1000_DEV_ID_82540EM_LOM:
+ case E1000_DEV_ID_82540EP:
+ case E1000_DEV_ID_82540EP_LOM:
+ case E1000_DEV_ID_82540EP_LP:
+ hw->mac_type = e1000_82540;
+ break;
+ case E1000_DEV_ID_82545EM_COPPER:
+ case E1000_DEV_ID_82545EM_FIBER:
+ hw->mac_type = e1000_82545;
+ break;
+ case E1000_DEV_ID_82545GM_COPPER:
+ case E1000_DEV_ID_82545GM_FIBER:
+ case E1000_DEV_ID_82545GM_SERDES:
+ hw->mac_type = e1000_82545_rev_3;
+ break;
+ case E1000_DEV_ID_82546EB_COPPER:
+ case E1000_DEV_ID_82546EB_FIBER:
+ case E1000_DEV_ID_82546EB_QUAD_COPPER:
+ hw->mac_type = e1000_82546;
+ break;
+ case E1000_DEV_ID_82546GB_COPPER:
+ case E1000_DEV_ID_82546GB_FIBER:
+ case E1000_DEV_ID_82546GB_SERDES:
+ hw->mac_type = e1000_82546_rev_3;
+ break;
+ case E1000_DEV_ID_82541EI:
+ case E1000_DEV_ID_82541EI_MOBILE:
+ hw->mac_type = e1000_82541;
+ break;
+ case E1000_DEV_ID_82541ER:
+ case E1000_DEV_ID_82541GI:
+ case E1000_DEV_ID_82541GI_MOBILE:
+ hw->mac_type = e1000_82541_rev_2;
+ break;
+ case E1000_DEV_ID_82547EI:
+ hw->mac_type = e1000_82547;
+ break;
+ case E1000_DEV_ID_82547GI:
+ hw->mac_type = e1000_82547_rev_2;
+ break;
+ default:
+ /* Should never have loaded on this device */
+ return -E1000_ERR_MAC_TYPE;
+ }
- udelay(5);
- retry_count += 5;
+ return E1000_SUCCESS;
+}
- } while(retry_count < EEPROM_MAX_RETRY_SPI);
+/*****************************************************************************
+ * Set media type and TBI compatibility.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * **************************************************************************/
+static void
+e1000_set_media_type(struct e1000_hw *hw)
+{
+ uint32_t status;
- /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
- * only 0-5mSec on 5V devices)
- */
- if(retry_count >= EEPROM_MAX_RETRY_SPI) {
- DEBUGOUT("SPI EEPROM Status error\n");
- return -E1000_ERR_EEPROM;
+ DEBUGFUNC("e1000_set_media_type");
+
+ if(hw->mac_type != e1000_82543) {
+ /* tbi_compatibility is only valid on 82543 */
+ hw->tbi_compatibility_en = FALSE;
}
- return E1000_SUCCESS;
+ switch (hw->device_id) {
+ case E1000_DEV_ID_82545GM_SERDES:
+ case E1000_DEV_ID_82546GB_SERDES:
+ hw->media_type = e1000_media_type_internal_serdes;
+ break;
+ default:
+ if(hw->mac_type >= e1000_82543) {
+ status = E1000_READ_REG(hw, STATUS);
+ if(status & E1000_STATUS_TBIMODE) {
+ hw->media_type = e1000_media_type_fiber;
+ /* tbi_compatibility not valid on fiber */
+ hw->tbi_compatibility_en = FALSE;
+ } else {
+ hw->media_type = e1000_media_type_copper;
+ }
+ } else {
+ /* This is an 82542 (fiber only) */
+ hw->media_type = e1000_media_type_fiber;
+ }
+ }
}
/******************************************************************************
- * Reads a 16 bit word from the EEPROM.
+ * Reset the transmit and receive units; mask and clear all interrupts.
*
* 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
*****************************************************************************/
-static int
-e1000_read_eeprom(struct e1000_hw *hw,
- uint16_t offset,
- uint16_t words,
- uint16_t *data)
+static void
+e1000_reset_hw(struct e1000_hw *hw)
{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- uint32_t i = 0;
+ uint32_t ctrl;
+ uint32_t ctrl_ext;
+ uint32_t icr;
+ uint32_t manc;
- DEBUGFUNC("e1000_read_eeprom");
+ DEBUGFUNC("e1000_reset_hw");
+
+ /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
+ if(hw->mac_type == e1000_82542_rev2_0) {
+ DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+ e1000_pci_clear_mwi(hw);
+ }
- /* A check for invalid values: offset too large, too many words, and not
- * enough words.
+ /* Clear interrupt mask to stop board from generating interrupts */
+ DEBUGOUT("Masking off all interrupts\n");
+ E1000_WRITE_REG(hw, IMC, 0xffffffff);
+
+ /* Disable the Transmit and Receive units. Then delay to allow
+ * any pending transactions to complete before we hit the MAC with
+ * the global reset.
*/
- if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
- (words == 0)) {
- DEBUGOUT("\"words\" parameter out of bounds\n");
- return -E1000_ERR_EEPROM;
- }
+ E1000_WRITE_REG(hw, RCTL, 0);
+ E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
+ E1000_WRITE_FLUSH(hw);
- /* Prepare the EEPROM for reading */
- if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
- return -E1000_ERR_EEPROM;
-
- if(eeprom->type == e1000_eeprom_spi) {
- uint16_t word_in;
- uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
-
- if(e1000_spi_eeprom_ready(hw)) {
- e1000_release_eeprom(hw);
- return -E1000_ERR_EEPROM;
- }
-
- e1000_standby_eeprom(hw);
-
- /* Some SPI eeproms use the 8th address bit embedded in the opcode */
- if((eeprom->address_bits == 8) && (offset >= 128))
- read_opcode |= EEPROM_A8_OPCODE_SPI;
+ /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
+ hw->tbi_compatibility_on = FALSE;
- /* Send the READ command (opcode + addr) */
- e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
- e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits);
+ /* Delay to allow any outstanding PCI transactions to complete before
+ * resetting the device
+ */
+ mdelay(10);
- /* Read the data. The address of the eeprom internally increments with
- * each byte (spi) being read, saving on the overhead of eeprom setup
- * and tear-down. The address counter will roll over if reading beyond
- * the size of the eeprom, thus allowing the entire memory to be read
- * starting from any offset. */
- for (i = 0; i < words; i++) {
- word_in = e1000_shift_in_ee_bits(hw, 16);
- data[i] = (word_in >> 8) | (word_in << 8);
- }
- } else if(eeprom->type == e1000_eeprom_microwire) {
- for (i = 0; i < words; i++) {
- /* Send the READ command (opcode + addr) */
- e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
- eeprom->opcode_bits);
- e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i),
- eeprom->address_bits);
+ ctrl = E1000_READ_REG(hw, CTRL);
- /* Read the data. For microwire, each word requires the overhead
- * of eeprom setup and tear-down. */
- data[i] = e1000_shift_in_ee_bits(hw, 16);
- e1000_standby_eeprom(hw);
- }
+ /* Must reset the PHY before resetting the MAC */
+ if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+ E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
+ mdelay(5);
}
- /* End this read operation */
- e1000_release_eeprom(hw);
+ /* Issue a global reset to the MAC. This will reset the chip's
+ * transmit, receive, DMA, and link units. It will not effect
+ * the current PCI configuration. The global reset bit is self-
+ * clearing, and should clear within a microsecond.
+ */
+ DEBUGOUT("Issuing a global reset to MAC\n");
- return E1000_SUCCESS;
-}
+ switch(hw->mac_type) {
+ case e1000_82544:
+ case e1000_82540:
+ case e1000_82545:
+ case e1000_82546:
+ case e1000_82541:
+ case e1000_82541_rev_2:
+ /* These controllers can't ack the 64-bit write when issuing the
+ * reset, so use IO-mapping as a workaround to issue the reset */
+ E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
+ break;
+ case e1000_82545_rev_3:
+ case e1000_82546_rev_3:
+ /* Reset is performed on a shadow of the control register */
+ E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
+ break;
+ default:
+ E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+ break;
+ }
-/******************************************************************************
- * Verifies that the EEPROM has a valid checksum
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Reads the first 64 16 bit words of the EEPROM and sums the values read.
- * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
- * valid.
- *****************************************************************************/
-static int
-e1000_validate_eeprom_checksum(struct e1000_hw *hw)
-{
- uint16_t checksum = 0;
- uint16_t i, eeprom_data;
+ /* After MAC reset, force reload of EEPROM to restore power-on settings to
+ * device. Later controllers reload the EEPROM automatically, so just wait
+ * for reload to complete.
+ */
+ switch(hw->mac_type) {
+ case e1000_82542_rev2_0:
+ case e1000_82542_rev2_1:
+ case e1000_82543:
+ case e1000_82544:
+ /* Wait for reset to complete */
+ udelay(10);
+ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+ ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+ E1000_WRITE_FLUSH(hw);
+ /* Wait for EEPROM reload */
+ mdelay(2);
+ break;
+ case e1000_82541:
+ case e1000_82541_rev_2:
+ case e1000_82547:
+ case e1000_82547_rev_2:
+ /* Wait for EEPROM reload */
+ mdelay(20);
+ break;
+ default:
+ /* Wait for EEPROM reload (it happens automatically) */
+ mdelay(5);
+ break;
+ }
- DEBUGFUNC("e1000_validate_eeprom_checksum");
+ /* Disable HW ARPs on ASF enabled adapters */
+ if(hw->mac_type >= e1000_82540) {
+ manc = E1000_READ_REG(hw, MANC);
+ manc &= ~(E1000_MANC_ARP_EN);
+ E1000_WRITE_REG(hw, MANC, manc);
+ }
- for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
- if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- checksum += eeprom_data;
+ if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+ e1000_phy_init_script(hw);
}
+
+ /* Clear interrupt mask to stop board from generating interrupts */
+ DEBUGOUT("Masking off all interrupts\n");
+ E1000_WRITE_REG(hw, IMC, 0xffffffff);
- if(checksum == (uint16_t) EEPROM_SUM)
- return E1000_SUCCESS;
- else {
- DEBUGOUT("EEPROM Checksum Invalid\n");
- return -E1000_ERR_EEPROM;
+ /* Clear any pending interrupt events. */
+ icr = E1000_READ_REG(hw, ICR);
+
+ /* If MWI was previously enabled, reenable it. */
+ if(hw->mac_type == e1000_82542_rev2_0) {
+#ifdef LINUX_DRIVER
+ if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
+#endif
+ e1000_pci_set_mwi(hw);
}
}
/******************************************************************************
- * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
- * second function of dual function devices
+ * Performs basic configuration of the adapter.
*
* hw - Struct containing variables accessed by shared code
+ *
+ * Assumes that the controller has previously been reset and is in a
+ * post-reset uninitialized state. Initializes the receive address registers,
+ * multicast table, and VLAN filter table. Calls routines to setup link
+ * configuration and flow control settings. Clears all on-chip counters. Leaves
+ * the transmit and receive units disabled and uninitialized.
*****************************************************************************/
-static int
-e1000_read_mac_addr(struct e1000_hw *hw)
+static int
+e1000_init_hw(struct e1000_hw *hw)
{
- uint16_t offset;
- uint16_t eeprom_data;
- int i;
+ uint32_t ctrl, status;
+ uint32_t i;
+ int32_t ret_val;
+ uint16_t pcix_cmd_word;
+ uint16_t pcix_stat_hi_word;
+ uint16_t cmd_mmrbc;
+ uint16_t stat_mmrbc;
+ e1000_bus_type bus_type = e1000_bus_type_unknown;
- DEBUGFUNC("e1000_read_mac_addr");
+ DEBUGFUNC("e1000_init_hw");
- for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
- offset = i >> 1;
- if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- hw->mac_addr[i] = eeprom_data & 0xff;
- hw->mac_addr[i+1] = (eeprom_data >> 8) & 0xff;
- }
- if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
- (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
- /* Invert the last bit if this is the second device */
- hw->mac_addr[5] ^= 1;
- return E1000_SUCCESS;
-}
+ /* Set the media type and TBI compatibility */
+ e1000_set_media_type(hw);
-/******************************************************************************
- * Initializes receive address filters.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Places the MAC address in receive address register 0 and clears the rest
- * of the receive addresss registers. Clears the multicast table. Assumes
- * the receiver is in reset when the routine is called.
- *****************************************************************************/
-static void
-e1000_init_rx_addrs(struct e1000_hw *hw)
-{
- uint32_t i;
- uint32_t addr_low;
- uint32_t addr_high;
+ /* Disabling VLAN filtering. */
+ DEBUGOUT("Initializing the IEEE VLAN\n");
+ E1000_WRITE_REG(hw, VET, 0);
- DEBUGFUNC("e1000_init_rx_addrs");
+ e1000_clear_vfta(hw);
- /* Setup the receive address. */
- DEBUGOUT("Programming MAC Address into RAR[0]\n");
- addr_low = (hw->mac_addr[0] |
- (hw->mac_addr[1] << 8) |
- (hw->mac_addr[2] << 16) | (hw->mac_addr[3] << 24));
+ /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
+ if(hw->mac_type == e1000_82542_rev2_0) {
+ DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+ e1000_pci_clear_mwi(hw);
+ E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
+ E1000_WRITE_FLUSH(hw);
+ mdelay(5);
+ }
- addr_high = (hw->mac_addr[4] |
- (hw->mac_addr[5] << 8) | E1000_RAH_AV);
+ /* Setup the receive address. This involves initializing all of the Receive
+ * Address Registers (RARs 0 - 15).
+ */
+ e1000_init_rx_addrs(hw);
- E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
- E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
+ /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
+ if(hw->mac_type == e1000_82542_rev2_0) {
+ E1000_WRITE_REG(hw, RCTL, 0);
+ E1000_WRITE_FLUSH(hw);
+ mdelay(1);
+#ifdef LINUX_DRIVER
+ if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
+#endif
+ e1000_pci_set_mwi(hw);
+ }
- /* Zero out the other 15 receive addresses. */
- DEBUGOUT("Clearing RAR[1-15]\n");
- for(i = 1; i < E1000_RAR_ENTRIES; i++) {
- E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
- E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
+ /* Zero out the Multicast HASH table */
+ DEBUGOUT("Zeroing the MTA\n");
+ for(i = 0; i < E1000_MC_TBL_SIZE; i++)
+ E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
+
+#if 0
+ /* Set the PCI priority bit correctly in the CTRL register. This
+ * determines if the adapter gives priority to receives, or if it
+ * gives equal priority to transmits and receives.
+ */
+ if(hw->dma_fairness) {
+ ctrl = E1000_READ_REG(hw, CTRL);
+ E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
}
-}
-
-/******************************************************************************
- * Clears the VLAN filer table
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void
-e1000_clear_vfta(struct e1000_hw *hw)
-{
- uint32_t offset;
-
- for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
-}
+#endif
-/******************************************************************************
-* Writes a value to one of the devices registers using port I/O (as opposed to
-* memory mapped I/O). Only 82544 and newer devices support port I/O. *
-* hw - Struct containing variables accessed by shared code
-* offset - offset to write to * value - value to write
-*****************************************************************************/
-static inline void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset,
- uint32_t value){
- e1000_io_write(hw, hw->io_base, offset);
- e1000_io_write(hw, hw->io_base + 4, value);
-}
+ switch(hw->mac_type) {
+ case e1000_82545_rev_3:
+ case e1000_82546_rev_3:
+ break;
+ default:
+ if (hw->mac_type >= e1000_82543) {
+ /* See e1000_get_bus_info() of the Linux driver */
+ status = E1000_READ_REG(hw, STATUS);
+ bus_type = (status & E1000_STATUS_PCIX_MODE) ?
+ e1000_bus_type_pcix : e1000_bus_type_pci;
+ }
-/******************************************************************************
- * Set the phy type member in the hw struct.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static int32_t
-e1000_set_phy_type(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_set_phy_type");
+ /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
+ if(bus_type == e1000_bus_type_pcix) {
+ pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
+ pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word);
+ cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
+ PCIX_COMMAND_MMRBC_SHIFT;
+ stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
+ PCIX_STATUS_HI_MMRBC_SHIFT;
+ if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
+ stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
+ if(cmd_mmrbc > stat_mmrbc) {
+ pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
+ pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
+ pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER, pcix_cmd_word);
+ }
+ }
+ break;
+ }
- switch(hw->phy_id) {
- case M88E1000_E_PHY_ID:
- case M88E1000_I_PHY_ID:
- case M88E1011_I_PHY_ID:
- hw->phy_type = e1000_phy_m88;
- break;
- case IGP01E1000_I_PHY_ID:
- hw->phy_type = e1000_phy_igp;
- break;
- default:
- /* Should never have loaded on this device */
- hw->phy_type = e1000_phy_undefined;
- return -E1000_ERR_PHY_TYPE;
+ /* Call a subroutine to configure the link and setup flow control. */
+ ret_val = e1000_setup_link(hw);
+
+ /* Set the transmit descriptor write-back policy */
+ if(hw->mac_type > e1000_82544) {
+ ctrl = E1000_READ_REG(hw, TXDCTL);
+ ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
+ E1000_WRITE_REG(hw, TXDCTL, ctrl);
}
- return E1000_SUCCESS;
+#if 0
+ /* Clear all of the statistics registers (clear on read). It is
+ * important that we do this after we have tried to establish link
+ * because the symbol error count will increment wildly if there
+ * is no link.
+ */
+ e1000_clear_hw_cntrs(hw);
+#endif
+
+ return ret_val;
}
/******************************************************************************
- * IGP phy init script - initializes the GbE PHY
+ * Adjust SERDES output amplitude based on EEPROM setting.
*
- * hw - Struct containing variables accessed by shared code
+ * hw - Struct containing variables accessed by shared code.
*****************************************************************************/
-static void
-e1000_phy_init_script(struct e1000_hw *hw)
+static int32_t
+e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
{
- DEBUGFUNC("e1000_phy_init_script");
-
-#if 0
- /* See e1000_sw_init() of the Linux driver */
- if(hw->phy_init_script) {
-#else
- if((hw->mac_type == e1000_82541) ||
- (hw->mac_type == e1000_82547) ||
- (hw->mac_type == e1000_82541_rev_2) ||
- (hw->mac_type == e1000_82547_rev_2)) {
-#endif
- mdelay(20);
-
- e1000_write_phy_reg(hw,0x0000,0x0140);
-
- mdelay(5);
-
- if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
- e1000_write_phy_reg(hw, 0x1F95, 0x0001);
-
- e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
-
- e1000_write_phy_reg(hw, 0x1F79, 0x0018);
-
- e1000_write_phy_reg(hw, 0x1F30, 0x1600);
-
- e1000_write_phy_reg(hw, 0x1F31, 0x0014);
-
- e1000_write_phy_reg(hw, 0x1F32, 0x161C);
-
- e1000_write_phy_reg(hw, 0x1F94, 0x0003);
-
- e1000_write_phy_reg(hw, 0x1F96, 0x003F);
-
- e1000_write_phy_reg(hw, 0x2010, 0x0008);
- } else {
- e1000_write_phy_reg(hw, 0x1F73, 0x0099);
- }
-
- e1000_write_phy_reg(hw, 0x0000, 0x3300);
-
-
- if(hw->mac_type == e1000_82547) {
- uint16_t fused, fine, coarse;
-
- /* Move to analog registers page */
- e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
+ uint16_t eeprom_data;
+ int32_t ret_val;
- if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
- e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused);
+ DEBUGFUNC("e1000_adjust_serdes_amplitude");
- fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
- coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
+ if(hw->media_type != e1000_media_type_internal_serdes)
+ return E1000_SUCCESS;
- if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
- coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10;
- fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
- } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
- fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
+ switch(hw->mac_type) {
+ case e1000_82545_rev_3:
+ case e1000_82546_rev_3:
+ break;
+ default:
+ return E1000_SUCCESS;
+ }
- fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
- (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
- (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);
+ if ((ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
+ &eeprom_data))) {
+ return ret_val;
+ }
- e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
- e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
- IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
- }
- }
+ if(eeprom_data != EEPROM_RESERVED_WORD) {
+ /* Adjust SERDES output amplitude only. */
+ eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
+ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL,
+ eeprom_data)))
+ return ret_val;
}
-}
+ return E1000_SUCCESS;
+}
+
/******************************************************************************
- * Set the mac type member in the hw struct.
+ * Configures flow control and link settings.
*
* hw - Struct containing variables accessed by shared code
+ *
+ * Determines which flow control settings to use. Calls the apropriate media-
+ * specific link configuration function. Configures the flow control settings.
+ * Assuming the adapter has a valid link partner, a valid link should be
+ * established. Assumes the hardware has previously been reset and the
+ * transmitter and receiver are not enabled.
*****************************************************************************/
static int
-e1000_set_mac_type(struct e1000_hw *hw)
+e1000_setup_link(struct e1000_hw *hw)
{
- DEBUGFUNC("e1000_set_mac_type");
-
- switch (hw->device_id) {
- case E1000_DEV_ID_82542:
- switch (hw->revision_id) {
- case E1000_82542_2_0_REV_ID:
- hw->mac_type = e1000_82542_rev2_0;
- break;
- case E1000_82542_2_1_REV_ID:
- hw->mac_type = e1000_82542_rev2_1;
- break;
- default:
- /* Invalid 82542 revision ID */
- return -E1000_ERR_MAC_TYPE;
- }
- break;
- case E1000_DEV_ID_82543GC_FIBER:
- case E1000_DEV_ID_82543GC_COPPER:
- hw->mac_type = e1000_82543;
- break;
- case E1000_DEV_ID_82544EI_COPPER:
- case E1000_DEV_ID_82544EI_FIBER:
- case E1000_DEV_ID_82544GC_COPPER:
- case E1000_DEV_ID_82544GC_LOM:
- hw->mac_type = e1000_82544;
- break;
- case E1000_DEV_ID_82540EM:
- case E1000_DEV_ID_82540EM_LOM:
- case E1000_DEV_ID_82540EP:
- case E1000_DEV_ID_82540EP_LOM:
- case E1000_DEV_ID_82540EP_LP:
- hw->mac_type = e1000_82540;
- break;
- case E1000_DEV_ID_82545EM_COPPER:
- case E1000_DEV_ID_82545EM_FIBER:
- hw->mac_type = e1000_82545;
- break;
- case E1000_DEV_ID_82545GM_COPPER:
- case E1000_DEV_ID_82545GM_FIBER:
- case E1000_DEV_ID_82545GM_SERDES:
- hw->mac_type = e1000_82545_rev_3;
- break;
- case E1000_DEV_ID_82546EB_COPPER:
- case E1000_DEV_ID_82546EB_FIBER:
- case E1000_DEV_ID_82546EB_QUAD_COPPER:
- hw->mac_type = e1000_82546;
- break;
- case E1000_DEV_ID_82546GB_COPPER:
- case E1000_DEV_ID_82546GB_FIBER:
- case E1000_DEV_ID_82546GB_SERDES:
- hw->mac_type = e1000_82546_rev_3;
- break;
- case E1000_DEV_ID_82541EI:
- case E1000_DEV_ID_82541EI_MOBILE:
- hw->mac_type = e1000_82541;
- break;
- case E1000_DEV_ID_82541ER:
- case E1000_DEV_ID_82541GI:
- case E1000_DEV_ID_82541GI_MOBILE:
- hw->mac_type = e1000_82541_rev_2;
- break;
- case E1000_DEV_ID_82547EI:
- hw->mac_type = e1000_82547;
- break;
- case E1000_DEV_ID_82547GI:
- hw->mac_type = e1000_82547_rev_2;
- break;
- default:
- /* Should never have loaded on this device */
- return -E1000_ERR_MAC_TYPE;
- }
-
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- * Set media type and TBI compatibility.
- *
- * hw - Struct containing variables accessed by shared code
- * **************************************************************************/
-static void
-e1000_set_media_type(struct e1000_hw *hw)
-{
- uint32_t status;
-
- DEBUGFUNC("e1000_set_media_type");
-
- if(hw->mac_type != e1000_82543) {
- /* tbi_compatibility is only valid on 82543 */
- hw->tbi_compatibility_en = FALSE;
- }
-
- switch (hw->device_id) {
- case E1000_DEV_ID_82545GM_SERDES:
- case E1000_DEV_ID_82546GB_SERDES:
- hw->media_type = e1000_media_type_internal_serdes;
- break;
- default:
- if(hw->mac_type >= e1000_82543) {
- status = E1000_READ_REG(hw, STATUS);
- if(status & E1000_STATUS_TBIMODE) {
- hw->media_type = e1000_media_type_fiber;
- /* tbi_compatibility not valid on fiber */
- hw->tbi_compatibility_en = FALSE;
- } else {
- hw->media_type = e1000_media_type_copper;
- }
- } else {
- /* This is an 82542 (fiber only) */
- hw->media_type = e1000_media_type_fiber;
- }
- }
-}
-
-/******************************************************************************
- * Reset the transmit and receive units; mask and clear all interrupts.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void
-e1000_reset_hw(struct e1000_hw *hw)
-{
- uint32_t ctrl;
- uint32_t ctrl_ext;
- uint32_t icr;
- uint32_t manc;
-
- DEBUGFUNC("e1000_reset_hw");
-
- /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
- if(hw->mac_type == e1000_82542_rev2_0) {
- DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
- e1000_pci_clear_mwi(hw);
- }
-
- /* Clear interrupt mask to stop board from generating interrupts */
- DEBUGOUT("Masking off all interrupts\n");
- E1000_WRITE_REG(hw, IMC, 0xffffffff);
-
- /* Disable the Transmit and Receive units. Then delay to allow
- * any pending transactions to complete before we hit the MAC with
- * the global reset.
- */
- E1000_WRITE_REG(hw, RCTL, 0);
- E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
- E1000_WRITE_FLUSH(hw);
-
- /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
- hw->tbi_compatibility_on = FALSE;
-
- /* Delay to allow any outstanding PCI transactions to complete before
- * resetting the device
- */
- mdelay(10);
-
- ctrl = E1000_READ_REG(hw, CTRL);
-
- /* Must reset the PHY before resetting the MAC */
- if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
- E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
- mdelay(5);
- }
-
- /* Issue a global reset to the MAC. This will reset the chip's
- * transmit, receive, DMA, and link units. It will not effect
- * the current PCI configuration. The global reset bit is self-
- * clearing, and should clear within a microsecond.
- */
- DEBUGOUT("Issuing a global reset to MAC\n");
-
- switch(hw->mac_type) {
- case e1000_82544:
- case e1000_82540:
- case e1000_82545:
- case e1000_82546:
- case e1000_82541:
- case e1000_82541_rev_2:
- /* These controllers can't ack the 64-bit write when issuing the
- * reset, so use IO-mapping as a workaround to issue the reset */
- E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
- break;
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- /* Reset is performed on a shadow of the control register */
- E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
- break;
- default:
- E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
- break;
- }
-
- /* After MAC reset, force reload of EEPROM to restore power-on settings to
- * device. Later controllers reload the EEPROM automatically, so just wait
- * for reload to complete.
- */
- switch(hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- case e1000_82544:
- /* Wait for reset to complete */
- udelay(10);
- ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH(hw);
- /* Wait for EEPROM reload */
- mdelay(2);
- break;
- case e1000_82541:
- case e1000_82541_rev_2:
- case e1000_82547:
- case e1000_82547_rev_2:
- /* Wait for EEPROM reload */
- mdelay(20);
- break;
- default:
- /* Wait for EEPROM reload (it happens automatically) */
- mdelay(5);
- break;
- }
-
- /* Disable HW ARPs on ASF enabled adapters */
- if(hw->mac_type >= e1000_82540) {
- manc = E1000_READ_REG(hw, MANC);
- manc &= ~(E1000_MANC_ARP_EN);
- E1000_WRITE_REG(hw, MANC, manc);
- }
-
- if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
- e1000_phy_init_script(hw);
- }
-
- /* Clear interrupt mask to stop board from generating interrupts */
- DEBUGOUT("Masking off all interrupts\n");
- E1000_WRITE_REG(hw, IMC, 0xffffffff);
-
- /* Clear any pending interrupt events. */
- icr = E1000_READ_REG(hw, ICR);
-
- /* If MWI was previously enabled, reenable it. */
- if(hw->mac_type == e1000_82542_rev2_0) {
-#ifdef LINUX_DRIVER
- if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
-#endif
- e1000_pci_set_mwi(hw);
- }
-}
-
-/******************************************************************************
- * Performs basic configuration of the adapter.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Assumes that the controller has previously been reset and is in a
- * post-reset uninitialized state. Initializes the receive address registers,
- * multicast table, and VLAN filter table. Calls routines to setup link
- * configuration and flow control settings. Clears all on-chip counters. Leaves
- * the transmit and receive units disabled and uninitialized.
- *****************************************************************************/
-static int
-e1000_init_hw(struct e1000_hw *hw)
-{
- uint32_t ctrl, status;
- uint32_t i;
- int32_t ret_val;
- uint16_t pcix_cmd_word;
- uint16_t pcix_stat_hi_word;
- uint16_t cmd_mmrbc;
- uint16_t stat_mmrbc;
- e1000_bus_type bus_type = e1000_bus_type_unknown;
-
- DEBUGFUNC("e1000_init_hw");
-
- /* Set the media type and TBI compatibility */
- e1000_set_media_type(hw);
-
- /* Disabling VLAN filtering. */
- DEBUGOUT("Initializing the IEEE VLAN\n");
- E1000_WRITE_REG(hw, VET, 0);
-
- e1000_clear_vfta(hw);
-
- /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
- if(hw->mac_type == e1000_82542_rev2_0) {
- DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
- e1000_pci_clear_mwi(hw);
- E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
- E1000_WRITE_FLUSH(hw);
- mdelay(5);
- }
-
- /* Setup the receive address. This involves initializing all of the Receive
- * Address Registers (RARs 0 - 15).
- */
- e1000_init_rx_addrs(hw);
-
- /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
- if(hw->mac_type == e1000_82542_rev2_0) {
- E1000_WRITE_REG(hw, RCTL, 0);
- E1000_WRITE_FLUSH(hw);
- mdelay(1);
-#ifdef LINUX_DRIVER
- if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
-#endif
- e1000_pci_set_mwi(hw);
- }
-
- /* Zero out the Multicast HASH table */
- DEBUGOUT("Zeroing the MTA\n");
- for(i = 0; i < E1000_MC_TBL_SIZE; i++)
- E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
-
-#if 0
- /* Set the PCI priority bit correctly in the CTRL register. This
- * determines if the adapter gives priority to receives, or if it
- * gives equal priority to transmits and receives.
- */
- if(hw->dma_fairness) {
- ctrl = E1000_READ_REG(hw, CTRL);
- E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
- }
-#endif
-
- switch(hw->mac_type) {
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- break;
- default:
- if (hw->mac_type >= e1000_82543) {
- /* See e1000_get_bus_info() of the Linux driver */
- status = E1000_READ_REG(hw, STATUS);
- bus_type = (status & E1000_STATUS_PCIX_MODE) ?
- e1000_bus_type_pcix : e1000_bus_type_pci;
- }
-
- /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
- if(bus_type == e1000_bus_type_pcix) {
- pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
- pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word);
- cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
- PCIX_COMMAND_MMRBC_SHIFT;
- stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
- PCIX_STATUS_HI_MMRBC_SHIFT;
- if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
- stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
- if(cmd_mmrbc > stat_mmrbc) {
- pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
- pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
- pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER, pcix_cmd_word);
- }
- }
- break;
- }
-
- /* Call a subroutine to configure the link and setup flow control. */
- ret_val = e1000_setup_link(hw);
-
- /* Set the transmit descriptor write-back policy */
- if(hw->mac_type > e1000_82544) {
- ctrl = E1000_READ_REG(hw, TXDCTL);
- ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
- E1000_WRITE_REG(hw, TXDCTL, ctrl);
- }
-
-#if 0
- /* Clear all of the statistics registers (clear on read). It is
- * important that we do this after we have tried to establish link
- * because the symbol error count will increment wildly if there
- * is no link.
- */
- e1000_clear_hw_cntrs(hw);
-#endif
-
- return ret_val;
-}
-
-/******************************************************************************
- * Adjust SERDES output amplitude based on EEPROM setting.
- *
- * hw - Struct containing variables accessed by shared code.
- *****************************************************************************/
-static int32_t
-e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
-{
- uint16_t eeprom_data;
- int32_t ret_val;
-
- DEBUGFUNC("e1000_adjust_serdes_amplitude");
-
- if(hw->media_type != e1000_media_type_internal_serdes)
- return E1000_SUCCESS;
-
- switch(hw->mac_type) {
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- break;
- default:
- return E1000_SUCCESS;
- }
-
- if ((ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
- &eeprom_data))) {
- return ret_val;
- }
-
- if(eeprom_data != EEPROM_RESERVED_WORD) {
- /* Adjust SERDES output amplitude only. */
- eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
- if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL,
- eeprom_data)))
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Configures flow control and link settings.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Determines which flow control settings to use. Calls the apropriate media-
- * specific link configuration function. Configures the flow control settings.
- * Assuming the adapter has a valid link partner, a valid link should be
- * established. Assumes the hardware has previously been reset and the
- * transmitter and receiver are not enabled.
- *****************************************************************************/
-static int
-e1000_setup_link(struct e1000_hw *hw)
-{
- uint32_t ctrl_ext;
- int32_t ret_val;
- uint16_t eeprom_data;
+ uint32_t ctrl_ext;
+ int32_t ret_val;
+ uint16_t eeprom_data;
DEBUGFUNC("e1000_setup_link");
*speed = SPEED_10;
DEBUGOUT("10 Mbs, ");
}
-
- if(status & E1000_STATUS_FD) {
- *duplex = FULL_DUPLEX;
- DEBUGOUT("Full Duplex\r\n");
- } else {
- *duplex = HALF_DUPLEX;
- DEBUGOUT(" Half Duplex\r\n");
+
+ if(status & E1000_STATUS_FD) {
+ *duplex = FULL_DUPLEX;
+ DEBUGOUT("Full Duplex\r\n");
+ } else {
+ *duplex = HALF_DUPLEX;
+ DEBUGOUT(" Half Duplex\r\n");
+ }
+ } else {
+ DEBUGOUT("1000 Mbs, Full Duplex\r\n");
+ *speed = SPEED_1000;
+ *duplex = FULL_DUPLEX;
+ }
+}
+
+/******************************************************************************
+* Blocks until autoneg completes or times out (~4.5 seconds)
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_wait_autoneg(struct e1000_hw *hw)
+{
+ int32_t ret_val;
+ uint16_t i;
+ uint16_t phy_data;
+
+ DEBUGFUNC("e1000_wait_autoneg");
+ DEBUGOUT("Waiting for Auto-Neg to complete.\n");
+
+ /* We will wait for autoneg to complete or 4.5 seconds to expire. */
+ for(i = PHY_AUTO_NEG_TIME; i > 0; i--) {
+ /* Read the MII Status Register and wait for Auto-Neg
+ * Complete bit to be set.
+ */
+ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+ return ret_val;
+ if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+ return ret_val;
+ if(phy_data & MII_SR_AUTONEG_COMPLETE) {
+ DEBUGOUT("Auto-Neg complete.\n");
+ return E1000_SUCCESS;
+ }
+ mdelay(100);
+ }
+ DEBUGOUT("Auto-Neg timedout.\n");
+ return -E1000_ERR_TIMEOUT;
+}
+
+/******************************************************************************
+* Raises the Management Data Clock
+*
+* hw - Struct containing variables accessed by shared code
+* ctrl - Device control register's current value
+******************************************************************************/
+static void
+e1000_raise_mdi_clk(struct e1000_hw *hw,
+ uint32_t *ctrl)
+{
+ /* Raise the clock input to the Management Data Clock (by setting the MDC
+ * bit), and then delay 10 microseconds.
+ */
+ E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
+ E1000_WRITE_FLUSH(hw);
+ udelay(10);
+}
+
+/******************************************************************************
+* Lowers the Management Data Clock
+*
+* hw - Struct containing variables accessed by shared code
+* ctrl - Device control register's current value
+******************************************************************************/
+static void
+e1000_lower_mdi_clk(struct e1000_hw *hw,
+ uint32_t *ctrl)
+{
+ /* Lower the clock input to the Management Data Clock (by clearing the MDC
+ * bit), and then delay 10 microseconds.
+ */
+ E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
+ E1000_WRITE_FLUSH(hw);
+ udelay(10);
+}
+
+/******************************************************************************
+* Shifts data bits out to the PHY
+*
+* hw - Struct containing variables accessed by shared code
+* data - Data to send out to the PHY
+* count - Number of bits to shift out
+*
+* Bits are shifted out in MSB to LSB order.
+******************************************************************************/
+static void
+e1000_shift_out_mdi_bits(struct e1000_hw *hw,
+ uint32_t data,
+ uint16_t count)
+{
+ uint32_t ctrl;
+ uint32_t mask;
+
+ /* We need to shift "count" number of bits out to the PHY. So, the value
+ * in the "data" parameter will be shifted out to the PHY one bit at a
+ * time. In order to do this, "data" must be broken down into bits.
+ */
+ mask = 0x01;
+ mask <<= (count - 1);
+
+ ctrl = E1000_READ_REG(hw, CTRL);
+
+ /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
+ ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
+
+ while(mask) {
+ /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
+ * then raising and lowering the Management Data Clock. A "0" is
+ * shifted out to the PHY by setting the MDIO bit to "0" and then
+ * raising and lowering the clock.
+ */
+ if(data & mask) ctrl |= E1000_CTRL_MDIO;
+ else ctrl &= ~E1000_CTRL_MDIO;
+
+ E1000_WRITE_REG(hw, CTRL, ctrl);
+ E1000_WRITE_FLUSH(hw);
+
+ udelay(10);
+
+ e1000_raise_mdi_clk(hw, &ctrl);
+ e1000_lower_mdi_clk(hw, &ctrl);
+
+ mask = mask >> 1;
+ }
+}
+
+/******************************************************************************
+* Shifts data bits in from the PHY
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Bits are shifted in in MSB to LSB order.
+******************************************************************************/
+static uint16_t
+e1000_shift_in_mdi_bits(struct e1000_hw *hw)
+{
+ uint32_t ctrl;
+ uint16_t data = 0;
+ uint8_t i;
+
+ /* In order to read a register from the PHY, we need to shift in a total
+ * of 18 bits from the PHY. The first two bit (turnaround) times are used
+ * to avoid contention on the MDIO pin when a read operation is performed.
+ * These two bits are ignored by us and thrown away. Bits are "shifted in"
+ * by raising the input to the Management Data Clock (setting the MDC bit),
+ * and then reading the value of the MDIO bit.
+ */
+ ctrl = E1000_READ_REG(hw, CTRL);
+
+ /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
+ ctrl &= ~E1000_CTRL_MDIO_DIR;
+ ctrl &= ~E1000_CTRL_MDIO;
+
+ E1000_WRITE_REG(hw, CTRL, ctrl);
+ E1000_WRITE_FLUSH(hw);
+
+ /* Raise and Lower the clock before reading in the data. This accounts for
+ * the turnaround bits. The first clock occurred when we clocked out the
+ * last bit of the Register Address.
+ */
+ e1000_raise_mdi_clk(hw, &ctrl);
+ e1000_lower_mdi_clk(hw, &ctrl);
+
+ for(data = 0, i = 0; i < 16; i++) {
+ data = data << 1;
+ e1000_raise_mdi_clk(hw, &ctrl);
+ ctrl = E1000_READ_REG(hw, CTRL);
+ /* Check to see if we shifted in a "1". */
+ if(ctrl & E1000_CTRL_MDIO) data |= 1;
+ e1000_lower_mdi_clk(hw, &ctrl);
+ }
+
+ e1000_raise_mdi_clk(hw, &ctrl);
+ e1000_lower_mdi_clk(hw, &ctrl);
+
+ return data;
+}
+
+/*****************************************************************************
+* Reads the value from a PHY register, if the value is on a specific non zero
+* page, sets the page first.
+*
+* hw - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to read
+******************************************************************************/
+static int
+e1000_read_phy_reg(struct e1000_hw *hw,
+ uint32_t reg_addr,
+ uint16_t *phy_data)
+{
+ uint32_t ret_val;
+
+ DEBUGFUNC("e1000_read_phy_reg");
+
+ if(hw->phy_type == e1000_phy_igp &&
+ (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
+ if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
+ (uint16_t)reg_addr)))
+ return ret_val;
+ }
+
+ ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
+ phy_data);
+
+ return ret_val;
+}
+
+static int
+e1000_read_phy_reg_ex(struct e1000_hw *hw,
+ uint32_t reg_addr,
+ uint16_t *phy_data)
+{
+ uint32_t i;
+ uint32_t mdic = 0;
+ const uint32_t phy_addr = 1;
+
+ DEBUGFUNC("e1000_read_phy_reg_ex");
+
+ if(reg_addr > MAX_PHY_REG_ADDRESS) {
+ DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
+ return -E1000_ERR_PARAM;
+ }
+
+ if(hw->mac_type > e1000_82543) {
+ /* Set up Op-code, Phy Address, and register address in the MDI
+ * Control register. The MAC will take care of interfacing with the
+ * PHY to retrieve the desired data.
+ */
+ mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
+ (phy_addr << E1000_MDIC_PHY_SHIFT) |
+ (E1000_MDIC_OP_READ));
+
+ E1000_WRITE_REG(hw, MDIC, mdic);
+
+ /* Poll the ready bit to see if the MDI read completed */
+ for(i = 0; i < 64; i++) {
+ udelay(50);
+ mdic = E1000_READ_REG(hw, MDIC);
+ if(mdic & E1000_MDIC_READY) break;
+ }
+ if(!(mdic & E1000_MDIC_READY)) {
+ DEBUGOUT("MDI Read did not complete\n");
+ return -E1000_ERR_PHY;
+ }
+ if(mdic & E1000_MDIC_ERROR) {
+ DEBUGOUT("MDI Error\n");
+ return -E1000_ERR_PHY;
}
+ *phy_data = (uint16_t) mdic;
} else {
- DEBUGOUT("1000 Mbs, Full Duplex\r\n");
- *speed = SPEED_1000;
- *duplex = FULL_DUPLEX;
+ /* We must first send a preamble through the MDIO pin to signal the
+ * beginning of an MII instruction. This is done by sending 32
+ * consecutive "1" bits.
+ */
+ e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+
+ /* Now combine the next few fields that are required for a read
+ * operation. We use this method instead of calling the
+ * e1000_shift_out_mdi_bits routine five different times. The format of
+ * a MII read instruction consists of a shift out of 14 bits and is
+ * defined as follows:
+ * <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
+ * followed by a shift in of 18 bits. This first two bits shifted in
+ * are TurnAround bits used to avoid contention on the MDIO pin when a
+ * READ operation is performed. These two bits are thrown away
+ * followed by a shift in of 16 bits which contains the desired data.
+ */
+ mdic = ((reg_addr) | (phy_addr << 5) |
+ (PHY_OP_READ << 10) | (PHY_SOF << 12));
+
+ e1000_shift_out_mdi_bits(hw, mdic, 14);
+
+ /* Now that we've shifted out the read command to the MII, we need to
+ * "shift in" the 16-bit value (18 total bits) of the requested PHY
+ * register address.
+ */
+ *phy_data = e1000_shift_in_mdi_bits(hw);
}
+ return E1000_SUCCESS;
}
/******************************************************************************
-* Blocks until autoneg completes or times out (~4.5 seconds)
+* Writes a value to a PHY register
*
* hw - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to write
+* data - data to write to the PHY
******************************************************************************/
+static int
+e1000_write_phy_reg(struct e1000_hw *hw,
+ uint32_t reg_addr,
+ uint16_t phy_data)
+{
+ uint32_t ret_val;
+
+ DEBUGFUNC("e1000_write_phy_reg");
+
+ if(hw->phy_type == e1000_phy_igp &&
+ (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
+ if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
+ (uint16_t)reg_addr)))
+ return ret_val;
+ }
+
+ ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
+ phy_data);
+
+ return ret_val;
+}
+
static int
-e1000_wait_autoneg(struct e1000_hw *hw)
+e1000_write_phy_reg_ex(struct e1000_hw *hw,
+ uint32_t reg_addr,
+ uint16_t phy_data)
{
- int32_t ret_val;
- uint16_t i;
- uint16_t phy_data;
+ uint32_t i;
+ uint32_t mdic = 0;
+ const uint32_t phy_addr = 1;
- DEBUGFUNC("e1000_wait_autoneg");
- DEBUGOUT("Waiting for Auto-Neg to complete.\n");
+ DEBUGFUNC("e1000_write_phy_reg_ex");
- /* We will wait for autoneg to complete or 4.5 seconds to expire. */
- for(i = PHY_AUTO_NEG_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Auto-Neg
- * Complete bit to be set.
+ if(reg_addr > MAX_PHY_REG_ADDRESS) {
+ DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
+ return -E1000_ERR_PARAM;
+ }
+
+ if(hw->mac_type > e1000_82543) {
+ /* Set up Op-code, Phy Address, register address, and data intended
+ * for the PHY register in the MDI Control register. The MAC will take
+ * care of interfacing with the PHY to send the desired data.
*/
- if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
- return ret_val;
- if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
- return ret_val;
- if(phy_data & MII_SR_AUTONEG_COMPLETE) {
- DEBUGOUT("Auto-Neg complete.\n");
- return E1000_SUCCESS;
+ mdic = (((uint32_t) phy_data) |
+ (reg_addr << E1000_MDIC_REG_SHIFT) |
+ (phy_addr << E1000_MDIC_PHY_SHIFT) |
+ (E1000_MDIC_OP_WRITE));
+
+ E1000_WRITE_REG(hw, MDIC, mdic);
+
+ /* Poll the ready bit to see if the MDI read completed */
+ for(i = 0; i < 640; i++) {
+ udelay(5);
+ mdic = E1000_READ_REG(hw, MDIC);
+ if(mdic & E1000_MDIC_READY) break;
}
- mdelay(100);
+ if(!(mdic & E1000_MDIC_READY)) {
+ DEBUGOUT("MDI Write did not complete\n");
+ return -E1000_ERR_PHY;
+ }
+ } else {
+ /* We'll need to use the SW defined pins to shift the write command
+ * out to the PHY. We first send a preamble to the PHY to signal the
+ * beginning of the MII instruction. This is done by sending 32
+ * consecutive "1" bits.
+ */
+ e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+
+ /* Now combine the remaining required fields that will indicate a
+ * write operation. We use this method instead of calling the
+ * e1000_shift_out_mdi_bits routine for each field in the command. The
+ * format of a MII write instruction is as follows:
+ * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
+ */
+ mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
+ (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
+ mdic <<= 16;
+ mdic |= (uint32_t) phy_data;
+
+ e1000_shift_out_mdi_bits(hw, mdic, 32);
}
- DEBUGOUT("Auto-Neg timedout.\n");
- return -E1000_ERR_TIMEOUT;
-}
-/******************************************************************************
-* Raises the Management Data Clock
-*
-* hw - Struct containing variables accessed by shared code
-* ctrl - Device control register's current value
-******************************************************************************/
-static void
-e1000_raise_mdi_clk(struct e1000_hw *hw,
- uint32_t *ctrl)
-{
- /* Raise the clock input to the Management Data Clock (by setting the MDC
- * bit), and then delay 10 microseconds.
- */
- E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
- E1000_WRITE_FLUSH(hw);
- udelay(10);
+ return E1000_SUCCESS;
}
/******************************************************************************
-* Lowers the Management Data Clock
+* Returns the PHY to the power-on reset state
*
* hw - Struct containing variables accessed by shared code
-* ctrl - Device control register's current value
******************************************************************************/
static void
-e1000_lower_mdi_clk(struct e1000_hw *hw,
- uint32_t *ctrl)
+e1000_phy_hw_reset(struct e1000_hw *hw)
{
- /* Lower the clock input to the Management Data Clock (by clearing the MDC
- * bit), and then delay 10 microseconds.
- */
- E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
- E1000_WRITE_FLUSH(hw);
- udelay(10);
+ uint32_t ctrl, ctrl_ext;
+
+ DEBUGFUNC("e1000_phy_hw_reset");
+
+ DEBUGOUT("Resetting Phy...\n");
+
+ if(hw->mac_type > e1000_82543) {
+ /* Read the device control register and assert the E1000_CTRL_PHY_RST
+ * bit. Then, take it out of reset.
+ */
+ ctrl = E1000_READ_REG(hw, CTRL);
+ E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
+ E1000_WRITE_FLUSH(hw);
+ mdelay(10);
+ E1000_WRITE_REG(hw, CTRL, ctrl);
+ E1000_WRITE_FLUSH(hw);
+ } else {
+ /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
+ * bit to put the PHY into reset. Then, take it out of reset.
+ */
+ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+ ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
+ ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+ E1000_WRITE_FLUSH(hw);
+ mdelay(10);
+ ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+ E1000_WRITE_FLUSH(hw);
+ }
+ udelay(150);
}
/******************************************************************************
-* Shifts data bits out to the PHY
+* Resets the PHY
*
* hw - Struct containing variables accessed by shared code
-* data - Data to send out to the PHY
-* count - Number of bits to shift out
*
-* Bits are shifted out in MSB to LSB order.
+* Sets bit 15 of the MII Control regiser
******************************************************************************/
-static void
-e1000_shift_out_mdi_bits(struct e1000_hw *hw,
- uint32_t data,
- uint16_t count)
+static int
+e1000_phy_reset(struct e1000_hw *hw)
{
- uint32_t ctrl;
- uint32_t mask;
+ int32_t ret_val;
+ uint16_t phy_data;
- /* We need to shift "count" number of bits out to the PHY. So, the value
- * in the "data" parameter will be shifted out to the PHY one bit at a
- * time. In order to do this, "data" must be broken down into bits.
- */
- mask = 0x01;
- mask <<= (count - 1);
-
- ctrl = E1000_READ_REG(hw, CTRL);
-
- /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
- ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
-
- while(mask) {
- /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
- * then raising and lowering the Management Data Clock. A "0" is
- * shifted out to the PHY by setting the MDIO bit to "0" and then
- * raising and lowering the clock.
- */
- if(data & mask) ctrl |= E1000_CTRL_MDIO;
- else ctrl &= ~E1000_CTRL_MDIO;
+ DEBUGFUNC("e1000_phy_reset");
+
+ if(hw->mac_type != e1000_82541_rev_2) {
+ if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
+ return ret_val;
- E1000_WRITE_REG(hw, CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
+ phy_data |= MII_CR_RESET;
+ if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
+ return ret_val;
- udelay(10);
+ udelay(1);
+ } else e1000_phy_hw_reset(hw);
- e1000_raise_mdi_clk(hw, &ctrl);
- e1000_lower_mdi_clk(hw, &ctrl);
+ if(hw->phy_type == e1000_phy_igp)
+ e1000_phy_init_script(hw);
- mask = mask >> 1;
- }
+ return E1000_SUCCESS;
}
/******************************************************************************
-* Shifts data bits in from the PHY
+* Probes the expected PHY address for known PHY IDs
*
* hw - Struct containing variables accessed by shared code
-*
-* Bits are shifted in in MSB to LSB order.
******************************************************************************/
-static uint16_t
-e1000_shift_in_mdi_bits(struct e1000_hw *hw)
+static int
+e1000_detect_gig_phy(struct e1000_hw *hw)
{
- uint32_t ctrl;
- uint16_t data = 0;
- uint8_t i;
+ int32_t phy_init_status, ret_val;
+ uint16_t phy_id_high, phy_id_low;
+ boolean_t match = FALSE;
- /* In order to read a register from the PHY, we need to shift in a total
- * of 18 bits from the PHY. The first two bit (turnaround) times are used
- * to avoid contention on the MDIO pin when a read operation is performed.
- * These two bits are ignored by us and thrown away. Bits are "shifted in"
- * by raising the input to the Management Data Clock (setting the MDC bit),
- * and then reading the value of the MDIO bit.
- */
- ctrl = E1000_READ_REG(hw, CTRL);
-
- /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
- ctrl &= ~E1000_CTRL_MDIO_DIR;
- ctrl &= ~E1000_CTRL_MDIO;
+ DEBUGFUNC("e1000_detect_gig_phy");
- E1000_WRITE_REG(hw, CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
+ /* Read the PHY ID Registers to identify which PHY is onboard. */
+ if((ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high)))
+ return ret_val;
+
+ hw->phy_id = (uint32_t) (phy_id_high << 16);
+ udelay(20);
+ if((ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low)))
+ return ret_val;
- /* Raise and Lower the clock before reading in the data. This accounts for
- * the turnaround bits. The first clock occurred when we clocked out the
- * last bit of the Register Address.
- */
- e1000_raise_mdi_clk(hw, &ctrl);
- e1000_lower_mdi_clk(hw, &ctrl);
+ hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
+#ifdef LINUX_DRIVER
+ hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
+#endif
- for(data = 0, i = 0; i < 16; i++) {
- data = data << 1;
- e1000_raise_mdi_clk(hw, &ctrl);
- ctrl = E1000_READ_REG(hw, CTRL);
- /* Check to see if we shifted in a "1". */
- if(ctrl & E1000_CTRL_MDIO) data |= 1;
- e1000_lower_mdi_clk(hw, &ctrl);
+ switch(hw->mac_type) {
+ case e1000_82543:
+ if(hw->phy_id == M88E1000_E_PHY_ID) match = TRUE;
+ break;
+ case e1000_82544:
+ if(hw->phy_id == M88E1000_I_PHY_ID) match = TRUE;
+ break;
+ case e1000_82540:
+ case e1000_82545:
+ case e1000_82545_rev_3:
+ case e1000_82546:
+ case e1000_82546_rev_3:
+ if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
+ break;
+ case e1000_82541:
+ case e1000_82541_rev_2:
+ case e1000_82547:
+ case e1000_82547_rev_2:
+ if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
+ break;
+ default:
+ DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
+ return -E1000_ERR_CONFIG;
}
-
- e1000_raise_mdi_clk(hw, &ctrl);
- e1000_lower_mdi_clk(hw, &ctrl);
-
- return data;
+ phy_init_status = e1000_set_phy_type(hw);
+
+ if ((match) && (phy_init_status == E1000_SUCCESS)) {
+ DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
+ return E1000_SUCCESS;
+ }
+ DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
+ return -E1000_ERR_PHY;
}
-/*****************************************************************************
-* Reads the value from a PHY register, if the value is on a specific non zero
-* page, sets the page first.
-*
-* hw - Struct containing variables accessed by shared code
-* reg_addr - address of the PHY register to read
-******************************************************************************/
-static int
-e1000_read_phy_reg(struct e1000_hw *hw,
- uint32_t reg_addr,
- uint16_t *phy_data)
+/******************************************************************************
+ * Sets up eeprom variables in the hw struct. Must be called after mac_type
+ * is configured.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_init_eeprom_params(struct e1000_hw *hw)
{
- uint32_t ret_val;
+ struct e1000_eeprom_info *eeprom = &hw->eeprom;
+ uint32_t eecd = E1000_READ_REG(hw, EECD);
+ uint16_t eeprom_size;
- DEBUGFUNC("e1000_read_phy_reg");
+ DEBUGFUNC("e1000_init_eeprom_params");
- if(hw->phy_type == e1000_phy_igp &&
- (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
- if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
- (uint16_t)reg_addr)))
- return ret_val;
+ switch (hw->mac_type) {
+ case e1000_82542_rev2_0:
+ case e1000_82542_rev2_1:
+ case e1000_82543:
+ case e1000_82544:
+ eeprom->type = e1000_eeprom_microwire;
+ eeprom->word_size = 64;
+ eeprom->opcode_bits = 3;
+ eeprom->address_bits = 6;
+ eeprom->delay_usec = 50;
+ break;
+ case e1000_82540:
+ case e1000_82545:
+ case e1000_82545_rev_3:
+ case e1000_82546:
+ case e1000_82546_rev_3:
+ eeprom->type = e1000_eeprom_microwire;
+ eeprom->opcode_bits = 3;
+ eeprom->delay_usec = 50;
+ if(eecd & E1000_EECD_SIZE) {
+ eeprom->word_size = 256;
+ eeprom->address_bits = 8;
+ } else {
+ eeprom->word_size = 64;
+ eeprom->address_bits = 6;
+ }
+ break;
+ case e1000_82541:
+ case e1000_82541_rev_2:
+ case e1000_82547:
+ case e1000_82547_rev_2:
+ if (eecd & E1000_EECD_TYPE) {
+ eeprom->type = e1000_eeprom_spi;
+ if (eecd & E1000_EECD_ADDR_BITS) {
+ eeprom->page_size = 32;
+ eeprom->address_bits = 16;
+ } else {
+ eeprom->page_size = 8;
+ eeprom->address_bits = 8;
+ }
+ } else {
+ eeprom->type = e1000_eeprom_microwire;
+ eeprom->opcode_bits = 3;
+ eeprom->delay_usec = 50;
+ if (eecd & E1000_EECD_ADDR_BITS) {
+ eeprom->word_size = 256;
+ eeprom->address_bits = 8;
+ } else {
+ eeprom->word_size = 64;
+ eeprom->address_bits = 6;
+ }
+ }
+ break;
+ default:
+ eeprom->type = e1000_eeprom_spi;
+ if (eecd & E1000_EECD_ADDR_BITS) {
+ eeprom->page_size = 32;
+ eeprom->address_bits = 16;
+ } else {
+ eeprom->page_size = 8;
+ eeprom->address_bits = 8;
+ }
+ break;
}
- ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
- phy_data);
+ if (eeprom->type == e1000_eeprom_spi) {
+ eeprom->opcode_bits = 8;
+ eeprom->delay_usec = 1;
+ eeprom->word_size = 64;
+ if (e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) {
+ eeprom_size &= EEPROM_SIZE_MASK;
- return ret_val;
+ 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:
+ break;
+ }
+ }
+ }
+}
+
+/******************************************************************************
+ * Raises the EEPROM's clock input.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * eecd - EECD's current value
+ *****************************************************************************/
+static void
+e1000_raise_ee_clk(struct e1000_hw *hw,
+ uint32_t *eecd)
+{
+ /* Raise the clock input to the EEPROM (by setting the SK bit), and then
+ * wait <delay> microseconds.
+ */
+ *eecd = *eecd | E1000_EECD_SK;
+ E1000_WRITE_REG(hw, EECD, *eecd);
+ E1000_WRITE_FLUSH(hw);
+ udelay(hw->eeprom.delay_usec);
+}
+
+/******************************************************************************
+ * Lowers the EEPROM's clock input.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * eecd - EECD's current value
+ *****************************************************************************/
+static void
+e1000_lower_ee_clk(struct e1000_hw *hw,
+ uint32_t *eecd)
+{
+ /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
+ * wait 50 microseconds.
+ */
+ *eecd = *eecd & ~E1000_EECD_SK;
+ E1000_WRITE_REG(hw, EECD, *eecd);
+ E1000_WRITE_FLUSH(hw);
+ udelay(hw->eeprom.delay_usec);
}
-static int
-e1000_read_phy_reg_ex(struct e1000_hw *hw,
- uint32_t reg_addr,
- uint16_t *phy_data)
+/******************************************************************************
+ * Shift data bits out to the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * data - data to send to the EEPROM
+ * count - number of bits to shift out
+ *****************************************************************************/
+static void
+e1000_shift_out_ee_bits(struct e1000_hw *hw,
+ uint16_t data,
+ uint16_t count)
{
- uint32_t i;
- uint32_t mdic = 0;
- const uint32_t phy_addr = 1;
-
- DEBUGFUNC("e1000_read_phy_reg_ex");
+ struct e1000_eeprom_info *eeprom = &hw->eeprom;
+ uint32_t eecd;
+ uint32_t mask;
- if(reg_addr > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
- return -E1000_ERR_PARAM;
+ /* We need to shift "count" bits out to the EEPROM. So, value in the
+ * "data" parameter will be shifted out to the EEPROM one bit at a time.
+ * In order to do this, "data" must be broken down into bits.
+ */
+ mask = 0x01 << (count - 1);
+ eecd = E1000_READ_REG(hw, EECD);
+ if (eeprom->type == e1000_eeprom_microwire) {
+ eecd &= ~E1000_EECD_DO;
+ } else if (eeprom->type == e1000_eeprom_spi) {
+ eecd |= E1000_EECD_DO;
}
-
- if(hw->mac_type > e1000_82543) {
- /* Set up Op-code, Phy Address, and register address in the MDI
- * Control register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
+ do {
+ /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
+ * and then raising and then lowering the clock (the SK bit controls
+ * the clock input to the EEPROM). A "0" is shifted out to the EEPROM
+ * by setting "DI" to "0" and then raising and then lowering the clock.
*/
- mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
- (phy_addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_READ));
+ eecd &= ~E1000_EECD_DI;
- E1000_WRITE_REG(hw, MDIC, mdic);
-
- /* Poll the ready bit to see if the MDI read completed */
- for(i = 0; i < 64; i++) {
- udelay(50);
- mdic = E1000_READ_REG(hw, MDIC);
- if(mdic & E1000_MDIC_READY) break;
- }
- if(!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Read did not complete\n");
- return -E1000_ERR_PHY;
- }
- if(mdic & E1000_MDIC_ERROR) {
- DEBUGOUT("MDI Error\n");
- return -E1000_ERR_PHY;
- }
- *phy_data = (uint16_t) mdic;
- } else {
- /* We must first send a preamble through the MDIO pin to signal the
- * beginning of an MII instruction. This is done by sending 32
- * consecutive "1" bits.
- */
- e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+ if(data & mask)
+ eecd |= E1000_EECD_DI;
- /* Now combine the next few fields that are required for a read
- * operation. We use this method instead of calling the
- * e1000_shift_out_mdi_bits routine five different times. The format of
- * a MII read instruction consists of a shift out of 14 bits and is
- * defined as follows:
- * <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
- * followed by a shift in of 18 bits. This first two bits shifted in
- * are TurnAround bits used to avoid contention on the MDIO pin when a
- * READ operation is performed. These two bits are thrown away
- * followed by a shift in of 16 bits which contains the desired data.
- */
- mdic = ((reg_addr) | (phy_addr << 5) |
- (PHY_OP_READ << 10) | (PHY_SOF << 12));
+ E1000_WRITE_REG(hw, EECD, eecd);
+ E1000_WRITE_FLUSH(hw);
- e1000_shift_out_mdi_bits(hw, mdic, 14);
+ udelay(eeprom->delay_usec);
- /* Now that we've shifted out the read command to the MII, we need to
- * "shift in" the 16-bit value (18 total bits) of the requested PHY
- * register address.
- */
- *phy_data = e1000_shift_in_mdi_bits(hw);
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Writes a value to a PHY register
-*
-* hw - Struct containing variables accessed by shared code
-* reg_addr - address of the PHY register to write
-* data - data to write to the PHY
-******************************************************************************/
-static int
-e1000_write_phy_reg(struct e1000_hw *hw,
- uint32_t reg_addr,
- uint16_t phy_data)
-{
- uint32_t ret_val;
-
- DEBUGFUNC("e1000_write_phy_reg");
-
- if(hw->phy_type == e1000_phy_igp &&
- (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
- if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
- (uint16_t)reg_addr)))
- return ret_val;
- }
-
- ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
- phy_data);
+ e1000_raise_ee_clk(hw, &eecd);
+ e1000_lower_ee_clk(hw, &eecd);
+
+ mask = mask >> 1;
+
+ } while(mask);
- return ret_val;
+ /* We leave the "DI" bit set to "0" when we leave this routine. */
+ eecd &= ~E1000_EECD_DI;
+ E1000_WRITE_REG(hw, EECD, eecd);
}
-static int
-e1000_write_phy_reg_ex(struct e1000_hw *hw,
- uint32_t reg_addr,
- uint16_t phy_data)
+/******************************************************************************
+ * Shift data bits in from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static uint16_t
+e1000_shift_in_ee_bits(struct e1000_hw *hw,
+ uint16_t count)
{
+ uint32_t eecd;
uint32_t i;
- uint32_t mdic = 0;
- const uint32_t phy_addr = 1;
+ uint16_t data;
- DEBUGFUNC("e1000_write_phy_reg_ex");
+ /* In order to read a register from the EEPROM, we need to shift 'count'
+ * bits in from the EEPROM. Bits are "shifted in" by raising the clock
+ * input to the EEPROM (setting the SK bit), and then reading the value of
+ * the "DO" bit. During this "shifting in" process the "DI" bit should
+ * always be clear.
+ */
- if(reg_addr > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
- return -E1000_ERR_PARAM;
- }
+ eecd = E1000_READ_REG(hw, EECD);
- if(hw->mac_type > e1000_82543) {
- /* Set up Op-code, Phy Address, register address, and data intended
- * for the PHY register in the MDI Control register. The MAC will take
- * care of interfacing with the PHY to send the desired data.
- */
- mdic = (((uint32_t) phy_data) |
- (reg_addr << E1000_MDIC_REG_SHIFT) |
- (phy_addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_WRITE));
+ eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
+ data = 0;
+
+ for(i = 0; i < count; i++) {
+ data = data << 1;
+ e1000_raise_ee_clk(hw, &eecd);
- E1000_WRITE_REG(hw, MDIC, mdic);
+ eecd = E1000_READ_REG(hw, EECD);
- /* Poll the ready bit to see if the MDI read completed */
- for(i = 0; i < 640; i++) {
+ eecd &= ~(E1000_EECD_DI);
+ if(eecd & E1000_EECD_DO)
+ data |= 1;
+
+ e1000_lower_ee_clk(hw, &eecd);
+ }
+
+ return data;
+}
+
+/******************************************************************************
+ * Prepares EEPROM for access
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
+ * function should be called before issuing a command to the EEPROM.
+ *****************************************************************************/
+static int32_t
+e1000_acquire_eeprom(struct e1000_hw *hw)
+{
+ struct e1000_eeprom_info *eeprom = &hw->eeprom;
+ uint32_t eecd, i=0;
+
+ eecd = E1000_READ_REG(hw, EECD);
+
+ /* Request EEPROM Access */
+ if(hw->mac_type > e1000_82544) {
+ eecd |= E1000_EECD_REQ;
+ E1000_WRITE_REG(hw, EECD, eecd);
+ eecd = E1000_READ_REG(hw, EECD);
+ while((!(eecd & E1000_EECD_GNT)) &&
+ (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
+ i++;
udelay(5);
- mdic = E1000_READ_REG(hw, MDIC);
- if(mdic & E1000_MDIC_READY) break;
+ eecd = E1000_READ_REG(hw, EECD);
}
- if(!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Write did not complete\n");
- return -E1000_ERR_PHY;
+ if(!(eecd & E1000_EECD_GNT)) {
+ eecd &= ~E1000_EECD_REQ;
+ E1000_WRITE_REG(hw, EECD, eecd);
+ DEBUGOUT("Could not acquire EEPROM grant\n");
+ return -E1000_ERR_EEPROM;
}
- } else {
- /* We'll need to use the SW defined pins to shift the write command
- * out to the PHY. We first send a preamble to the PHY to signal the
- * beginning of the MII instruction. This is done by sending 32
- * consecutive "1" bits.
- */
- e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
-
- /* Now combine the remaining required fields that will indicate a
- * write operation. We use this method instead of calling the
- * e1000_shift_out_mdi_bits routine for each field in the command. The
- * format of a MII write instruction is as follows:
- * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
- */
- mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
- (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
- mdic <<= 16;
- mdic |= (uint32_t) phy_data;
-
- e1000_shift_out_mdi_bits(hw, mdic, 32);
+ }
+
+ /* Setup EEPROM for Read/Write */
+
+ if (eeprom->type == e1000_eeprom_microwire) {
+ /* Clear SK and DI */
+ eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
+ E1000_WRITE_REG(hw, EECD, eecd);
+
+ /* Set CS */
+ eecd |= E1000_EECD_CS;
+ E1000_WRITE_REG(hw, EECD, eecd);
+ } else if (eeprom->type == e1000_eeprom_spi) {
+ /* Clear SK and CS */
+ eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+ E1000_WRITE_REG(hw, EECD, eecd);
+ udelay(1);
}
return E1000_SUCCESS;
}
/******************************************************************************
-* Returns the PHY to the power-on reset state
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
+ * Returns EEPROM to a "standby" state
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
static void
-e1000_phy_hw_reset(struct e1000_hw *hw)
+e1000_standby_eeprom(struct e1000_hw *hw)
{
- uint32_t ctrl, ctrl_ext;
+ struct e1000_eeprom_info *eeprom = &hw->eeprom;
+ uint32_t eecd;
+
+ eecd = E1000_READ_REG(hw, EECD);
- DEBUGFUNC("e1000_phy_hw_reset");
+ if(eeprom->type == e1000_eeprom_microwire) {
+
+ /* Deselect EEPROM */
+ eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+ E1000_WRITE_REG(hw, EECD, eecd);
+ E1000_WRITE_FLUSH(hw);
+ udelay(eeprom->delay_usec);
- DEBUGOUT("Resetting Phy...\n");
+ /* Clock high */
+ eecd |= E1000_EECD_SK;
+ E1000_WRITE_REG(hw, EECD, eecd);
+ E1000_WRITE_FLUSH(hw);
+ udelay(eeprom->delay_usec);
- if(hw->mac_type > e1000_82543) {
- /* Read the device control register and assert the E1000_CTRL_PHY_RST
- * bit. Then, take it out of reset.
- */
- ctrl = E1000_READ_REG(hw, CTRL);
- E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
+ /* Select EEPROM */
+ eecd |= E1000_EECD_CS;
+ E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
- mdelay(10);
- E1000_WRITE_REG(hw, CTRL, ctrl);
+ udelay(eeprom->delay_usec);
+
+ /* Clock low */
+ eecd &= ~E1000_EECD_SK;
+ E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
- } else {
- /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
- * bit to put the PHY into reset. Then, take it out of reset.
- */
- ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
- ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+ udelay(eeprom->delay_usec);
+ } else if(eeprom->type == e1000_eeprom_spi) {
+ /* Toggle CS to flush commands */
+ eecd |= E1000_EECD_CS;
+ E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
- mdelay(10);
- ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+ udelay(eeprom->delay_usec);
+ eecd &= ~E1000_EECD_CS;
+ E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
+ udelay(eeprom->delay_usec);
}
- udelay(150);
}
/******************************************************************************
-* Resets the PHY
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Sets bit 15 of the MII Control regiser
-******************************************************************************/
-static int
-e1000_phy_reset(struct e1000_hw *hw)
+ * Terminates a command by inverting the EEPROM's chip select pin
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_release_eeprom(struct e1000_hw *hw)
{
- int32_t ret_val;
- uint16_t phy_data;
+ uint32_t eecd;
- DEBUGFUNC("e1000_phy_reset");
+ eecd = E1000_READ_REG(hw, EECD);
- if(hw->mac_type != e1000_82541_rev_2) {
- if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
- return ret_val;
-
- phy_data |= MII_CR_RESET;
- if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
- return ret_val;
-
- udelay(1);
- } else e1000_phy_hw_reset(hw);
+ if (hw->eeprom.type == e1000_eeprom_spi) {
+ eecd |= E1000_EECD_CS; /* Pull CS high */
+ eecd &= ~E1000_EECD_SK; /* Lower SCK */
+
+ E1000_WRITE_REG(hw, EECD, eecd);
+
+ udelay(hw->eeprom.delay_usec);
+ } else if(hw->eeprom.type == e1000_eeprom_microwire) {
+ /* cleanup eeprom */
+
+ /* CS on Microwire is active-high */
+ eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+
+ E1000_WRITE_REG(hw, EECD, eecd);
+
+ /* Rising edge of clock */
+ eecd |= E1000_EECD_SK;
+ E1000_WRITE_REG(hw, EECD, eecd);
+ E1000_WRITE_FLUSH(hw);
+ udelay(hw->eeprom.delay_usec);
+
+ /* Falling edge of clock */
+ eecd &= ~E1000_EECD_SK;
+ E1000_WRITE_REG(hw, EECD, eecd);
+ E1000_WRITE_FLUSH(hw);
+ udelay(hw->eeprom.delay_usec);
+ }
+
+ /* Stop requesting EEPROM access */
+ if(hw->mac_type > e1000_82544) {
+ eecd &= ~E1000_EECD_REQ;
+ E1000_WRITE_REG(hw, EECD, eecd);
+ }
+}
+
+/******************************************************************************
+ * Reads a 16 bit word from the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int32_t
+e1000_spi_eeprom_ready(struct e1000_hw *hw)
+{
+ uint16_t retry_count = 0;
+ uint8_t spi_stat_reg;
+
+ /* Read "Status Register" repeatedly until the LSB is cleared. The
+ * EEPROM will signal that the command has been completed by clearing
+ * bit 0 of the internal status register. If it's not cleared within
+ * 5 milliseconds, then error out.
+ */
+ retry_count = 0;
+ do {
+ e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
+ hw->eeprom.opcode_bits);
+ spi_stat_reg = (uint8_t)e1000_shift_in_ee_bits(hw, 8);
+ if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
+ break;
+
+ udelay(5);
+ retry_count += 5;
+
+ } while(retry_count < EEPROM_MAX_RETRY_SPI);
+
+ /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
+ * only 0-5mSec on 5V devices)
+ */
+ if(retry_count >= EEPROM_MAX_RETRY_SPI) {
+ DEBUGOUT("SPI EEPROM Status error\n");
+ return -E1000_ERR_EEPROM;
+ }
+
+ return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Reads a 16 bit word from the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset of word in the EEPROM to read
+ * data - word read from the EEPROM
+ * words - number of words to read
+ *****************************************************************************/
+static int
+e1000_read_eeprom(struct e1000_hw *hw,
+ uint16_t offset,
+ uint16_t words,
+ uint16_t *data)
+{
+ struct e1000_eeprom_info *eeprom = &hw->eeprom;
+ uint32_t i = 0;
+
+ DEBUGFUNC("e1000_read_eeprom");
+
+ /* A check for invalid values: offset too large, too many words, and not
+ * enough words.
+ */
+ if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
+ (words == 0)) {
+ DEBUGOUT("\"words\" parameter out of bounds\n");
+ return -E1000_ERR_EEPROM;
+ }
+
+ /* Prepare the EEPROM for reading */
+ if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+ return -E1000_ERR_EEPROM;
+
+ if(eeprom->type == e1000_eeprom_spi) {
+ uint16_t word_in;
+ uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
+
+ if(e1000_spi_eeprom_ready(hw)) {
+ e1000_release_eeprom(hw);
+ return -E1000_ERR_EEPROM;
+ }
+
+ e1000_standby_eeprom(hw);
+
+ /* Some SPI eeproms use the 8th address bit embedded in the opcode */
+ if((eeprom->address_bits == 8) && (offset >= 128))
+ read_opcode |= EEPROM_A8_OPCODE_SPI;
+
+ /* Send the READ command (opcode + addr) */
+ e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
+ e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits);
+
+ /* Read the data. The address of the eeprom internally increments with
+ * each byte (spi) being read, saving on the overhead of eeprom setup
+ * and tear-down. The address counter will roll over if reading beyond
+ * the size of the eeprom, thus allowing the entire memory to be read
+ * starting from any offset. */
+ for (i = 0; i < words; i++) {
+ word_in = e1000_shift_in_ee_bits(hw, 16);
+ data[i] = (word_in >> 8) | (word_in << 8);
+ }
+ } else if(eeprom->type == e1000_eeprom_microwire) {
+ for (i = 0; i < words; i++) {
+ /* Send the READ command (opcode + addr) */
+ e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
+ eeprom->opcode_bits);
+ e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i),
+ eeprom->address_bits);
+
+ /* Read the data. For microwire, each word requires the overhead
+ * of eeprom setup and tear-down. */
+ data[i] = e1000_shift_in_ee_bits(hw, 16);
+ e1000_standby_eeprom(hw);
+ }
+ }
- if(hw->phy_type == e1000_phy_igp)
- e1000_phy_init_script(hw);
+ /* End this read operation */
+ e1000_release_eeprom(hw);
return E1000_SUCCESS;
}
/******************************************************************************
-* Probes the expected PHY address for known PHY IDs
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
+ * Verifies that the EEPROM has a valid checksum
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Reads the first 64 16 bit words of the EEPROM and sums the values read.
+ * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
+ * valid.
+ *****************************************************************************/
static int
-e1000_detect_gig_phy(struct e1000_hw *hw)
+e1000_validate_eeprom_checksum(struct e1000_hw *hw)
{
- int32_t phy_init_status, ret_val;
- uint16_t phy_id_high, phy_id_low;
- boolean_t match = FALSE;
+ uint16_t checksum = 0;
+ uint16_t i, eeprom_data;
- DEBUGFUNC("e1000_detect_gig_phy");
-
- /* Read the PHY ID Registers to identify which PHY is onboard. */
- if((ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high)))
- return ret_val;
+ DEBUGFUNC("e1000_validate_eeprom_checksum");
- hw->phy_id = (uint32_t) (phy_id_high << 16);
- udelay(20);
- if((ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low)))
- return ret_val;
-
- hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
-#ifdef LINUX_DRIVER
- hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
-#endif
-
- switch(hw->mac_type) {
- case e1000_82543:
- if(hw->phy_id == M88E1000_E_PHY_ID) match = TRUE;
- break;
- case e1000_82544:
- if(hw->phy_id == M88E1000_I_PHY_ID) match = TRUE;
- break;
- case e1000_82540:
- case e1000_82545:
- case e1000_82545_rev_3:
- case e1000_82546:
- case e1000_82546_rev_3:
- if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
- break;
- case e1000_82541:
- case e1000_82541_rev_2:
- case e1000_82547:
- case e1000_82547_rev_2:
- if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
- break;
- default:
- DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
- return -E1000_ERR_CONFIG;
+ for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
+ if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
+ DEBUGOUT("EEPROM Read Error\n");
+ return -E1000_ERR_EEPROM;
+ }
+ checksum += eeprom_data;
}
- phy_init_status = e1000_set_phy_type(hw);
-
- if ((match) && (phy_init_status == E1000_SUCCESS)) {
- DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
+
+ if(checksum == (uint16_t) EEPROM_SUM)
return E1000_SUCCESS;
+ else {
+ DEBUGOUT("EEPROM Checksum Invalid\n");
+ return -E1000_ERR_EEPROM;
}
- DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
- return -E1000_ERR_PHY;
}
/******************************************************************************
- * Sets up eeprom variables in the hw struct. Must be called after mac_type
- * is configured.
+ * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
+ * second function of dual function devices
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-static void
-e1000_init_eeprom_params(struct e1000_hw *hw)
+static int
+e1000_read_mac_addr(struct e1000_hw *hw)
{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd = E1000_READ_REG(hw, EECD);
- uint16_t eeprom_size;
+ uint16_t offset;
+ uint16_t eeprom_data;
+ int i;
- DEBUGFUNC("e1000_init_eeprom_params");
+ DEBUGFUNC("e1000_read_mac_addr");
- switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- case e1000_82544:
- eeprom->type = e1000_eeprom_microwire;
- eeprom->word_size = 64;
- eeprom->opcode_bits = 3;
- eeprom->address_bits = 6;
- eeprom->delay_usec = 50;
- break;
- case e1000_82540:
- case e1000_82545:
- case e1000_82545_rev_3:
- case e1000_82546:
- case e1000_82546_rev_3:
- eeprom->type = e1000_eeprom_microwire;
- eeprom->opcode_bits = 3;
- eeprom->delay_usec = 50;
- if(eecd & E1000_EECD_SIZE) {
- eeprom->word_size = 256;
- eeprom->address_bits = 8;
- } else {
- eeprom->word_size = 64;
- eeprom->address_bits = 6;
- }
- break;
- case e1000_82541:
- case e1000_82541_rev_2:
- case e1000_82547:
- case e1000_82547_rev_2:
- if (eecd & E1000_EECD_TYPE) {
- eeprom->type = e1000_eeprom_spi;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->page_size = 32;
- eeprom->address_bits = 16;
- } else {
- eeprom->page_size = 8;
- eeprom->address_bits = 8;
- }
- } else {
- eeprom->type = e1000_eeprom_microwire;
- eeprom->opcode_bits = 3;
- eeprom->delay_usec = 50;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->word_size = 256;
- eeprom->address_bits = 8;
- } else {
- eeprom->word_size = 64;
- eeprom->address_bits = 6;
- }
- }
- break;
- default:
- eeprom->type = e1000_eeprom_spi;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->page_size = 32;
- eeprom->address_bits = 16;
- } else {
- eeprom->page_size = 8;
- eeprom->address_bits = 8;
+ for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
+ offset = i >> 1;
+ if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
+ DEBUGOUT("EEPROM Read Error\n");
+ return -E1000_ERR_EEPROM;
}
- break;
+ hw->mac_addr[i] = eeprom_data & 0xff;
+ hw->mac_addr[i+1] = (eeprom_data >> 8) & 0xff;
}
+ if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
+ (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
+ /* Invert the last bit if this is the second device */
+ hw->mac_addr[5] ^= 1;
+ return E1000_SUCCESS;
+}
- if (eeprom->type == e1000_eeprom_spi) {
- eeprom->opcode_bits = 8;
- eeprom->delay_usec = 1;
- eeprom->word_size = 64;
- if (e1000_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:
- break;
- }
- }
+/******************************************************************************
+ * Initializes receive address filters.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Places the MAC address in receive address register 0 and clears the rest
+ * of the receive addresss registers. Clears the multicast table. Assumes
+ * the receiver is in reset when the routine is called.
+ *****************************************************************************/
+static void
+e1000_init_rx_addrs(struct e1000_hw *hw)
+{
+ uint32_t i;
+ uint32_t addr_low;
+ uint32_t addr_high;
+
+ DEBUGFUNC("e1000_init_rx_addrs");
+
+ /* Setup the receive address. */
+ DEBUGOUT("Programming MAC Address into RAR[0]\n");
+ addr_low = (hw->mac_addr[0] |
+ (hw->mac_addr[1] << 8) |
+ (hw->mac_addr[2] << 16) | (hw->mac_addr[3] << 24));
+
+ addr_high = (hw->mac_addr[4] |
+ (hw->mac_addr[5] << 8) | E1000_RAH_AV);
+
+ E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
+ E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
+
+ /* Zero out the other 15 receive addresses. */
+ DEBUGOUT("Clearing RAR[1-15]\n");
+ for(i = 1; i < E1000_RAR_ENTRIES; i++) {
+ E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
+ E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
}
}
+/******************************************************************************
+ * Clears the VLAN filer table
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_clear_vfta(struct e1000_hw *hw)
+{
+ uint32_t offset;
+
+ for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
+ E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
+}
+
+
+/******************************************************************************
+ * Functions from e1000_main.c of the linux driver
+ ******************************************************************************/
+
/**
* e1000_reset - Reset the adapter
*/
return E1000_SUCCESS;
}
+
+/******************************************************************************
+ * Functions not present in the linux driver
+ ******************************************************************************/
+
static void fill_rx (void)
{
struct e1000_rx_desc *rd;