static int ixgb_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) { struct ixgb_adapter *adapter = netdev_priv(netdev); struct ixgb_hw *hw = &adapter->hw; u16 *eeprom_buff; void *ptr; int max_len, first_word, last_word; u16 i; if (eeprom->len == 0) return -EINVAL; if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) return -EFAULT; max_len = ixgb_get_eeprom_len(netdev); if (eeprom->offset > eeprom->offset + eeprom->len) return -EINVAL; if ((eeprom->offset + eeprom->len) > max_len) eeprom->len = (max_len - eeprom->offset); 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 */ eeprom_buff[0] = ixgb_read_eeprom(hw, first_word); ptr++; } if ((eeprom->offset + eeprom->len) & 1) { /* need read/modify/write of last changed EEPROM word */ /* only the first byte of the word is being modified */ eeprom_buff[last_word - first_word] = ixgb_read_eeprom(hw, last_word); } memcpy(ptr, bytes, eeprom->len); for (i = 0; i <= (last_word - first_word); i++) ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]); /* Update the checksum over the first part of the EEPROM if needed */ if (first_word <= EEPROM_CHECKSUM_REG) ixgb_update_eeprom_checksum(hw); kfree(eeprom_buff); return 0; }
/****************************************************************************** * Reads eeprom and stores data in shared structure. * Validates eeprom checksum and eeprom signature. * * hw - Struct containing variables accessed by shared code * * Returns: * true: if eeprom read is successful * false: otherwise. *****************************************************************************/ bool ixgb_get_eeprom_data(struct ixgb_hw *hw) { u16 i; u16 checksum = 0; struct ixgb_ee_map_type *ee_map; ENTER(); ee_map = (struct ixgb_ee_map_type *)hw->eeprom; pr_debug("Reading eeprom data\n"); for (i = 0; i < IXGB_EEPROM_SIZE ; i++) { u16 ee_data; ee_data = ixgb_read_eeprom(hw, i); checksum += ee_data; hw->eeprom[i] = cpu_to_le16(ee_data); } if (checksum != (u16) EEPROM_SUM) { pr_debug("Checksum invalid\n"); /* clear the init_ctrl_reg_1 to signify that the cache is * invalidated */ ee_map->init_ctrl_reg_1 = cpu_to_le16(EEPROM_ICW1_SIGNATURE_CLEAR); return false; } if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK)) != cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) { pr_debug("Signature invalid\n"); return false; } return true; }
/****************************************************************************** * Reads eeprom and stores data in shared structure. * Validates eeprom checksum and eeprom signature. * * hw - Struct containing variables accessed by shared code * * Returns: * TRUE: if eeprom read is successful * FALSE: otherwise. *****************************************************************************/ boolean_t ixgb_get_eeprom_data(struct ixgb_hw *hw) { uint16_t i; uint16_t checksum = 0; struct ixgb_ee_map_type *ee_map; DEBUGFUNC("ixgb_get_eeprom_data"); ee_map = (struct ixgb_ee_map_type *) hw->eeprom; DEBUGOUT("ixgb_ee: Reading eeprom data\n"); for (i=0; i < IXGB_EEPROM_SIZE ; i++) { uint16_t ee_data; ee_data = ixgb_read_eeprom(hw, i); checksum += ee_data; hw->eeprom[i] = le16_to_cpu (ee_data); } if (checksum != (uint16_t) EEPROM_SUM) { DEBUGOUT("ixgb_ee: Checksum invalid.\n"); return (FALSE); } if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK)) != le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) { DEBUGOUT("ixgb_ee: Signature invalid.\n"); return(FALSE); } return(TRUE); }
static int ixgb_ethtool_seeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { struct ixgb_adapter *adapter = dev->priv; struct ixgb_hw *hw = &adapter->hw; /* We are under rtnl, so static is OK */ static uint16_t eeprom_buff[IXGB_EEPROM_SIZE]; int i, first_word, last_word; char *ptr; if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) return -EFAULT; first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; ptr = (char *)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 */ eeprom_buff[0] = ixgb_read_eeprom(hw, first_word); ptr++; } if ((eeprom->offset + eeprom->len) & 1) { /* need read/modify/write of last changed EEPROM word */ /* only the first byte of the word is being modified */ eeprom_buff[last_word - first_word] = ixgb_read_eeprom(hw, last_word); } memcpy(ptr, data, eeprom->len); for (i = 0; i <= (last_word - first_word); i++) ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]); /* Update the checksum over the first part of the EEPROM if needed */ if (first_word <= EEPROM_CHECKSUM_REG) ixgb_update_eeprom_checksum(hw); return 0; }
/****************************************************************************** * Calculates the EEPROM checksum and writes it to the EEPROM * * hw - Struct containing variables accessed by shared code * * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA. * Writes the difference to word offset 63 of the EEPROM. *****************************************************************************/ void ixgb_update_eeprom_checksum(struct ixgb_hw *hw) { u16 checksum = 0; u16 i; for (i = 0; i < EEPROM_CHECKSUM_REG; i++) checksum += ixgb_read_eeprom(hw, i); checksum = (u16) EEPROM_SUM - checksum; ixgb_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum); }
/****************************************************************************** * 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 sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is * valid. * * Returns: * true: Checksum is valid * false: Checksum is not valid. *****************************************************************************/ bool ixgb_validate_eeprom_checksum(struct ixgb_hw *hw) { u16 checksum = 0; u16 i; for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) checksum += ixgb_read_eeprom(hw, i); if (checksum == (u16) EEPROM_SUM) return true; else return false; }
/****************************************************************************** * Calculates the EEPROM checksum and writes it to the EEPROM * * hw - Struct containing variables accessed by shared code * * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA. * Writes the difference to word offset 63 of the EEPROM. *****************************************************************************/ void ixgb_update_eeprom_checksum(struct ixgb_hw *hw) { uint16_t checksum = 0; uint16_t i; for(i = 0; i < EEPROM_CHECKSUM_REG; i++) checksum += ixgb_read_eeprom(hw, i); checksum = (uint16_t)EEPROM_SUM - checksum; ixgb_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum); return; }
/****************************************************************************** * 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 sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is * valid. * * Returns: * TRUE: Checksum is valid * FALSE: Checksum is not valid. *****************************************************************************/ boolean_t ixgb_validate_eeprom_checksum(struct ixgb_hw *hw) { uint16_t checksum = 0; uint16_t i; for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) checksum += ixgb_read_eeprom(hw, i); if(checksum == (uint16_t)EEPROM_SUM) return (TRUE); else return (FALSE); }