📄 e1000.c
字号:
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 voide1000_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 voide1000_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)) {#ifdef PORT_IO_AND_MEMORY_IO_DIFFER E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));#else E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));#endif 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) {#ifdef PORT_IO_AND_MEMORY_IO_DIFFER 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;#endif 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 inte1000_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_te1000_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -