📄 e1000.c
字号:
eecd &= ~E1000_EECD_CS; E1000_WRITE_REG(hw, EECD, eecd); E1000_WRITE_FLUSH(hw); udelay(eeprom->delay_usec); }}/****************************************************************************** * Terminates a command by inverting the EEPROM's chip select pin * * hw - Struct containing variables accessed by shared code *****************************************************************************/static voide1000_release_eeprom(struct e1000_hw *hw){ uint32_t eecd; eecd = E1000_READ_REG(hw, EECD); 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_te1000_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 inte1000_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); } } /* End this read operation */ e1000_release_eeprom(hw); return E1000_SUCCESS;}/****************************************************************************** * 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 inte1000_validate_eeprom_checksum(struct e1000_hw *hw){ uint16_t checksum = 0; uint16_t i, eeprom_data; DEBUGFUNC("e1000_validate_eeprom_checksum"); 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(checksum == (uint16_t) EEPROM_SUM) return E1000_SUCCESS; else { DEBUGOUT("EEPROM Checksum Invalid\n"); return -E1000_ERR_EEPROM; }}/****************************************************************************** * 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 int e1000_read_mac_addr(struct e1000_hw *hw){ uint16_t offset; uint16_t eeprom_data; int i; DEBUGFUNC("e1000_read_mac_addr"); 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;}/****************************************************************************** * 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 voide1000_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 voide1000_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);}/****************************************************************************** * Set the phy type member in the hw struct. * * hw - Struct containing variables accessed by shared code *****************************************************************************/static int32_te1000_set_phy_type(struct e1000_hw *hw){ 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 E1000_SUCCESS;}/****************************************************************************** * IGP phy init script - initializes the GbE PHY * * hw - Struct containing variables accessed by shared code *****************************************************************************/static voide1000_phy_init_script(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); if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused); fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK; coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK; if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) { coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10; fine -= IGP01E1000_ANALOG_FUSE_FINE_1; } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH) fine -= IGP01E1000_ANALOG_FUSE_FINE_10; fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) | (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) | (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK); 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); } } }}/****************************************************************************** * Set the mac type member in the hw struct. * * hw - Struct containing variables accessed by shared code *****************************************************************************/static inte1000_set_mac_type(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -