static int cxgbe_set_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *eeprom) { struct port_info *pi = (struct port_info *)(dev->data->dev_private); struct adapter *adapter = pi->adapter; u8 *buf; int err = 0; u32 aligned_offset, aligned_len, *p; if (eeprom->magic != EEPROM_MAGIC) return -EINVAL; aligned_offset = eeprom->offset & ~3; aligned_len = (eeprom->length + (eeprom->offset & 3) + 3) & ~3; if (adapter->pf > 0) { u32 start = 1024 + adapter->pf * EEPROMPFSIZE; if (aligned_offset < start || aligned_offset + aligned_len > start + EEPROMPFSIZE) return -EPERM; } if (aligned_offset != eeprom->offset || aligned_len != eeprom->length) { /* RMW possibly needed for first or last words. */ buf = rte_zmalloc(NULL, aligned_len, 0); if (!buf) return -ENOMEM; err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf); if (!err && aligned_len > 4) err = eeprom_rd_phys(adapter, aligned_offset + aligned_len - 4, (u32 *)&buf[aligned_len - 4]); if (err) goto out; rte_memcpy(buf + (eeprom->offset & 3), eeprom->data, eeprom->length); } else { buf = eeprom->data; } err = t4_seeprom_wp(adapter, false); if (err) goto out; for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) { err = eeprom_wr_phys(adapter, aligned_offset, *p); aligned_offset += 4; } if (!err) err = t4_seeprom_wp(adapter, true); out: if (buf != eeprom->data) rte_free(buf); return err; }
static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { u8 *buf; int err = 0; u32 aligned_offset, aligned_len, *p; struct adapter *adapter = netdev2adap(dev); if (eeprom->magic != EEPROM_MAGIC) return -EINVAL; aligned_offset = eeprom->offset & ~3; aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3; if (adapter->pf > 0) { u32 start = 1024 + adapter->pf * EEPROMPFSIZE; if (aligned_offset < start || aligned_offset + aligned_len > start + EEPROMPFSIZE) return -EPERM; } if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) { /* RMW possibly needed for first or last words. */ buf = kmalloc(aligned_len, GFP_KERNEL); if (!buf) return -ENOMEM; err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf); if (!err && aligned_len > 4) err = eeprom_rd_phys(adapter, aligned_offset + aligned_len - 4, (u32 *)&buf[aligned_len - 4]); if (err) goto out; memcpy(buf + (eeprom->offset & 3), data, eeprom->len); } else { buf = data; } err = t4_seeprom_wp(adapter, false); if (err) goto out; for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) { err = eeprom_wr_phys(adapter, aligned_offset, *p); aligned_offset += 4; } if (!err) err = t4_seeprom_wp(adapter, true); out: if (buf != data) kfree(buf); return err; }