Merge branch 'cxgb4-fixes'
Rahul Lakkireddy says: ==================== cxgb4: bug fixes for ethtool flash ops This series of patches add bug fixes in ethtool flash operations. Patch 1 fixes an endianness issue when writing boot image to flash after the device ID has been updated. Patch 2 fixes sleep in atomic when writing PHY firmware to flash. Patch 3 fixes issue with PHY firmware image not getting written to flash when chip is still running. -==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
f4cdcae03f
|
@ -1337,13 +1337,27 @@ static int cxgb4_ethtool_flash_phy(struct net_device *netdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
spin_lock_bh(&adap->win0_lock);
|
||||
ret = t4_load_phy_fw(adap, MEMWIN_NIC, NULL, data, size);
|
||||
spin_unlock_bh(&adap->win0_lock);
|
||||
if (ret)
|
||||
dev_err(adap->pdev_dev, "Failed to load PHY FW\n");
|
||||
/* We have to RESET the chip/firmware because we need the
|
||||
* chip in uninitialized state for loading new PHY image.
|
||||
* Otherwise, the running firmware will only store the PHY
|
||||
* image in local RAM which will be lost after next reset.
|
||||
*/
|
||||
ret = t4_fw_reset(adap, adap->mbox, PIORSTMODE_F | PIORST_F);
|
||||
if (ret < 0) {
|
||||
dev_err(adap->pdev_dev,
|
||||
"Set FW to RESET for flashing PHY FW failed. ret: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
ret = t4_load_phy_fw(adap, MEMWIN_NIC, NULL, data, size);
|
||||
if (ret < 0) {
|
||||
dev_err(adap->pdev_dev, "Failed to load PHY FW. ret: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxgb4_ethtool_flash_fw(struct net_device *netdev,
|
||||
|
|
|
@ -4424,10 +4424,8 @@ static int adap_init0_phy(struct adapter *adap)
|
|||
|
||||
/* Load PHY Firmware onto adapter.
|
||||
*/
|
||||
spin_lock_bh(&adap->win0_lock);
|
||||
ret = t4_load_phy_fw(adap, MEMWIN_NIC, phy_info->phy_fw_version,
|
||||
(u8 *)phyf->data, phyf->size);
|
||||
spin_unlock_bh(&adap->win0_lock);
|
||||
if (ret < 0)
|
||||
dev_err(adap->pdev_dev, "PHY Firmware transfer error %d\n",
|
||||
-ret);
|
||||
|
|
|
@ -3060,16 +3060,19 @@ int t4_read_flash(struct adapter *adapter, unsigned int addr,
|
|||
* @addr: the start address to write
|
||||
* @n: length of data to write in bytes
|
||||
* @data: the data to write
|
||||
* @byte_oriented: whether to store data as bytes or as words
|
||||
*
|
||||
* Writes up to a page of data (256 bytes) to the serial flash starting
|
||||
* at the given address. All the data must be written to the same page.
|
||||
* If @byte_oriented is set the write data is stored as byte stream
|
||||
* (i.e. matches what on disk), otherwise in big-endian.
|
||||
*/
|
||||
static int t4_write_flash(struct adapter *adapter, unsigned int addr,
|
||||
unsigned int n, const u8 *data)
|
||||
unsigned int n, const u8 *data, bool byte_oriented)
|
||||
{
|
||||
int ret;
|
||||
u32 buf[64];
|
||||
unsigned int i, c, left, val, offset = addr & 0xff;
|
||||
u32 buf[64];
|
||||
int ret;
|
||||
|
||||
if (addr >= adapter->params.sf_size || offset + n > SF_PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
@ -3080,10 +3083,14 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr,
|
|||
(ret = sf1_write(adapter, 4, 1, 1, val)) != 0)
|
||||
goto unlock;
|
||||
|
||||
for (left = n; left; left -= c) {
|
||||
for (left = n; left; left -= c, data += c) {
|
||||
c = min(left, 4U);
|
||||
for (val = 0, i = 0; i < c; ++i)
|
||||
val = (val << 8) + *data++;
|
||||
for (val = 0, i = 0; i < c; ++i) {
|
||||
if (byte_oriented)
|
||||
val = (val << 8) + data[i];
|
||||
else
|
||||
val = (val << 8) + data[c - i - 1];
|
||||
}
|
||||
|
||||
ret = sf1_write(adapter, c, c != left, 1, val);
|
||||
if (ret)
|
||||
|
@ -3096,7 +3103,8 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr,
|
|||
t4_write_reg(adapter, SF_OP_A, 0); /* unlock SF */
|
||||
|
||||
/* Read the page to verify the write succeeded */
|
||||
ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1);
|
||||
ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf,
|
||||
byte_oriented);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -3692,7 +3700,7 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
|
|||
*/
|
||||
memcpy(first_page, fw_data, SF_PAGE_SIZE);
|
||||
((struct fw_hdr *)first_page)->fw_ver = cpu_to_be32(0xffffffff);
|
||||
ret = t4_write_flash(adap, fw_start, SF_PAGE_SIZE, first_page);
|
||||
ret = t4_write_flash(adap, fw_start, SF_PAGE_SIZE, first_page, true);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@ -3700,14 +3708,14 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
|
|||
for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
|
||||
addr += SF_PAGE_SIZE;
|
||||
fw_data += SF_PAGE_SIZE;
|
||||
ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data);
|
||||
ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data, true);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = t4_write_flash(adap,
|
||||
fw_start + offsetof(struct fw_hdr, fw_ver),
|
||||
sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver);
|
||||
ret = t4_write_flash(adap, fw_start + offsetof(struct fw_hdr, fw_ver),
|
||||
sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver,
|
||||
true);
|
||||
out:
|
||||
if (ret)
|
||||
dev_err(adap->pdev_dev, "firmware download failed, error %d\n",
|
||||
|
@ -3812,9 +3820,11 @@ int t4_load_phy_fw(struct adapter *adap, int win,
|
|||
/* Copy the supplied PHY Firmware image to the adapter memory location
|
||||
* allocated by the adapter firmware.
|
||||
*/
|
||||
spin_lock_bh(&adap->win0_lock);
|
||||
ret = t4_memory_rw(adap, win, mtype, maddr,
|
||||
phy_fw_size, (__be32 *)phy_fw_data,
|
||||
T4_MEMORY_WRITE);
|
||||
spin_unlock_bh(&adap->win0_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -10208,7 +10218,7 @@ int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
|
|||
n = size - i;
|
||||
else
|
||||
n = SF_PAGE_SIZE;
|
||||
ret = t4_write_flash(adap, addr, n, cfg_data);
|
||||
ret = t4_write_flash(adap, addr, n, cfg_data, true);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@ -10677,13 +10687,14 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data,
|
|||
for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
|
||||
addr += SF_PAGE_SIZE;
|
||||
boot_data += SF_PAGE_SIZE;
|
||||
ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, boot_data);
|
||||
ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, boot_data,
|
||||
false);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = t4_write_flash(adap, boot_sector, SF_PAGE_SIZE,
|
||||
(const u8 *)header);
|
||||
(const u8 *)header, false);
|
||||
|
||||
out:
|
||||
if (ret)
|
||||
|
@ -10758,7 +10769,7 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
|
|||
for (i = 0; i < size; i += SF_PAGE_SIZE) {
|
||||
n = min_t(u32, size - i, SF_PAGE_SIZE);
|
||||
|
||||
ret = t4_write_flash(adap, addr, n, cfg_data);
|
||||
ret = t4_write_flash(adap, addr, n, cfg_data, false);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@ -10770,7 +10781,8 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
|
|||
for (i = 0; i < npad; i++) {
|
||||
u8 data = 0;
|
||||
|
||||
ret = t4_write_flash(adap, cfg_addr + size + i, 1, &data);
|
||||
ret = t4_write_flash(adap, cfg_addr + size + i, 1, &data,
|
||||
false);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче