void eeprom_dump(void *instance) { struct e1000g *Adapter = (struct e1000g *)instance; struct e1000_hw *hw = &Adapter->shared; uint16_t eeprom[WPL], size_field; int i, ret, sign, size, lines, offset = 0; int ee_size[] = {128, 256, 512, 1024, 2048, 4096, 16 * 1024, 32 * 1024, 64 * 1024}; mutex_enter(&e1000g_nvm_lock); if (ret = e1000_read_nvm(hw, 0x12, 1, &size_field)) { e1000g_log(Adapter, CE_WARN, "e1000_read_nvm failed to read size: %d", ret); goto eeprom_dump_end; } sign = (size_field & 0xc000) >> 14; if (sign != 1) { e1000g_log(Adapter, CE_WARN, "eeprom_dump invalid signature: %d", sign); } size = (size_field & 0x3c00) >> 10; if (size < 0 || size > 11) { e1000g_log(Adapter, CE_WARN, "eeprom_dump invalid size: %d", size); } e1000g_log(Adapter, CE_CONT, "eeprom_dump size field: %d eeprom bytes: %d\n", size, ee_size[size]); e1000g_log(Adapter, CE_CONT, "e1000_read_nvm hebs: %d\n", ((size_field & 0x000f) >> 10)); lines = ee_size[size] / WPL / 2; e1000g_log(Adapter, CE_CONT, "dump eeprom %d lines of %d words per line\n", lines, WPL); for (i = 0; i < lines; i++) { if (ret = e1000_read_nvm(hw, offset, WPL, eeprom)) { e1000g_log(Adapter, CE_WARN, "e1000_read_nvm failed: %d", ret); goto eeprom_dump_end; } e1000g_log(Adapter, CE_CONT, "0x%04x %04x %04x %04x %04x %04x %04x %04x %04x\n", offset, eeprom[0], eeprom[1], eeprom[2], eeprom[3], eeprom[4], eeprom[5], eeprom[6], eeprom[7]); offset += WPL; } eeprom_dump_end: mutex_exit(&e1000g_nvm_lock); }
static int e1000_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; u16 *eeprom_buff; int first_word; int last_word; int ret_val = 0; u16 i; if (eeprom->len == 0) return -EINVAL; eeprom->magic = adapter->pdev->vendor | (adapter->pdev->device << 16); first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; if (hw->nvm.type == e1000_nvm_eeprom_spi) { ret_val = e1000_read_nvm(hw, first_word, last_word - first_word + 1, eeprom_buff); } else { for (i = 0; i < last_word - first_word + 1; i++) { ret_val = e1000_read_nvm(hw, first_word + i, 1, &eeprom_buff[i]); if (ret_val) break; } } if (ret_val) { /* a read error occurred, throw away the result */ memset(eeprom_buff, 0xff, sizeof(u16) * (last_word - first_word + 1)); } else { /* Device's eeprom is always little-endian, word addressable */ for (i = 0; i < last_word - first_word + 1; i++) le16_to_cpus(&eeprom_buff[i]); } memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); kfree(eeprom_buff); return ret_val; }
/** * e1000e_enable_mng_pass_thru - Check if management passthrough is needed * @hw: pointer to the HW structure * * Verifies the hardware needs to leave interface enabled so that frames can * be directed to and from the management interface. **/ bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) { u32 manc; u32 fwsm, factps; manc = er32(MANC); if (!(manc & E1000_MANC_RCV_TCO_EN)) return false; if (hw->mac.has_fwsm) { fwsm = er32(FWSM); factps = er32(FACTPS); if (!(factps & E1000_FACTPS_MNGCG) && ((fwsm & E1000_FWSM_MODE_MASK) == (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) return true; } else if ((hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82583)) { u16 data; factps = er32(FACTPS); e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); if (!(factps & E1000_FACTPS_MNGCG) && ((data & E1000_NVM_INIT_CTRL2_MNGM) == (e1000_mng_mode_pt << 13))) return true; } else if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) { return true; } return false; }
static ssize_t igb_maclla1(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { struct e1000_hw *hw; u16 eeprom_buff[6]; int first_word = 0x37; int word_count = 6; int rc; struct igb_adapter *adapter = igb_get_adapter(kobj); if (adapter == NULL) return snprintf(buf, PAGE_SIZE, "error: no adapter\n"); hw = &adapter->hw; if (hw == NULL) return snprintf(buf, PAGE_SIZE, "error: no hw data\n"); return 0; rc = e1000_read_nvm(hw, first_word, word_count, eeprom_buff); if (rc != E1000_SUCCESS) return 0; switch (hw->bus.func) { case 0: return snprintf(buf, PAGE_SIZE, "0x%04X%04X%04X\n", eeprom_buff[0], eeprom_buff[1], eeprom_buff[2]); case 1: return snprintf(buf, PAGE_SIZE, "0x%04X%04X%04X\n", eeprom_buff[3], eeprom_buff[4], eeprom_buff[5]); } return snprintf(buf, PAGE_SIZE, "unexpected port %d\n", hw->bus.func); }
/** * e1000_enable_mng_pass_thru - Check if management passthrough is needed * @hw: pointer to the HW structure * * Verifies the hardware needs to leave interface enabled so that frames can * be directed to and from the management interface. **/ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) { u32 manc; u32 fwsm, factps; bool ret_val = FALSE; DEBUGFUNC("e1000_enable_mng_pass_thru"); if (!hw->mac.asf_firmware_present) goto out; manc = E1000_READ_REG(hw, E1000_MANC); if (!(manc & E1000_MANC_RCV_TCO_EN)) goto out; if (hw->mac.has_fwsm) { fwsm = E1000_READ_REG(hw, E1000_FWSM); factps = E1000_READ_REG(hw, E1000_FACTPS); if (!(factps & E1000_FACTPS_MNGCG) && ((fwsm & E1000_FWSM_MODE_MASK) == (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { ret_val = TRUE; goto out; } } else if ((hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82583)) { u16 data; factps = E1000_READ_REG(hw, E1000_FACTPS); e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); if (!(factps & E1000_FACTPS_MNGCG) && ((data & E1000_NVM_INIT_CTRL2_MNGM) == (e1000_mng_mode_pt << 13))) { ret_val = TRUE; goto out; } } else if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) { ret_val = TRUE; goto out; } out: return ret_val; }
void IntelMausi::intelEEPROMChecks(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; int ret_val; u16 buf = 0; if (hw->mac.type != e1000_82573) return; ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf); le16_to_cpus(&buf); if (!ret_val && (!(buf & (1 << 0)))) { /* Deep Smart Power Down (DSPD) */ IOLog("Ethernet [IntelMausi]: Warning: detected DSPD enabled in EEPROM.\n"); } }
static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data) { u16 temp; u16 checksum = 0; u16 i; *data = 0; /* Read and add up the contents of the EEPROM */ for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { if ((e1000_read_nvm(&adapter->hw, i, 1, &temp)) < 0) { *data = 1; return *data; } checksum += temp; } /* If Checksum is not Correct return error else test passed */ if ((checksum != (u16) NVM_SUM) && !(*data)) *data = 2; return *data; }
static int igb_maclla1(char *page, char **start, off_t off, int count, int *eof, void *data) { struct e1000_hw *hw; u16 eeprom_buff[6]; int first_word = 0x37; int word_count = 6; int rc; struct igb_adapter *adapter = (struct igb_adapter *)data; if (adapter == NULL) return snprintf(page, count, "error: no adapter\n"); hw = &adapter->hw; if (hw == NULL) return snprintf(page, count, "error: no hw data\n"); rc = e1000_read_nvm(hw, first_word, word_count, eeprom_buff); if (rc != E1000_SUCCESS) return 0; switch (hw->bus.func) { case 0: return snprintf(page, count, "0x%04X%04X%04X\n", eeprom_buff[0], eeprom_buff[1], eeprom_buff[2]); case 1: return snprintf(page, count, "0x%04X%04X%04X\n", eeprom_buff[3], eeprom_buff[4], eeprom_buff[5]); } return snprintf(page, count, "unexpected port %d\n", hw->bus.func); }
static int e1000_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; u16 *eeprom_buff; void *ptr; int max_len; int first_word; int last_word; int ret_val = 0; u16 i; if (eeprom->len == 0) return -EOPNOTSUPP; if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) return -EFAULT; if (adapter->flags & FLAG_READ_ONLY_NVM) return -EINVAL; max_len = hw->nvm.word_size * 2; first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; eeprom_buff = kmalloc(max_len, GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; ptr = (void *)eeprom_buff; if (eeprom->offset & 1) { /* need read/modify/write of first changed EEPROM word */ /* only the second byte of the word is being modified */ ret_val = e1000_read_nvm(hw, first_word, 1, &eeprom_buff[0]); ptr++; } if (((eeprom->offset + eeprom->len) & 1) && (!ret_val)) /* need read/modify/write of last changed EEPROM word */ /* only the first byte of the word is being modified */ ret_val = e1000_read_nvm(hw, last_word, 1, &eeprom_buff[last_word - first_word]); if (ret_val) goto out; /* Device's eeprom is always little-endian, word addressable */ for (i = 0; i < last_word - first_word + 1; i++) le16_to_cpus(&eeprom_buff[i]); memcpy(ptr, bytes, eeprom->len); for (i = 0; i < last_word - first_word + 1; i++) cpu_to_le16s(&eeprom_buff[i]); ret_val = e1000_write_nvm(hw, first_word, last_word - first_word + 1, eeprom_buff); if (ret_val) goto out; /* * Update the checksum over the first part of the EEPROM if needed * and flush shadow RAM for applicable controllers */ if ((first_word <= NVM_CHECKSUM_REG) || (hw->mac.type == e1000_82583) || (hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82573)) ret_val = e1000e_update_nvm_checksum(hw); out: kfree(eeprom_buff); return ret_val; }