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; }
static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, u8 *data) { int i, err = 0; struct adapter *adapter = netdev2adap(dev); u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL); if (!buf) return -ENOMEM; e->magic = EEPROM_MAGIC; for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4) err = eeprom_rd_phys(adapter, i, (u32 *)&buf[i]); if (!err) memcpy(data, buf + e->offset, e->len); kfree(buf); return err; }
static int cxgbe_get_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *e) { struct port_info *pi = (struct port_info *)(dev->data->dev_private); struct adapter *adapter = pi->adapter; u32 i, err = 0; u8 *buf = rte_zmalloc(NULL, EEPROMSIZE, 0); if (!buf) return -ENOMEM; e->magic = EEPROM_MAGIC; for (i = e->offset & ~3; !err && i < e->offset + e->length; i += 4) err = eeprom_rd_phys(adapter, i, (u32 *)&buf[i]); if (!err) rte_memcpy(e->data, buf + e->offset, e->length); rte_free(buf); return err; }