Commit 42a20397 authored by Rahul Lakkireddy's avatar Rahul Lakkireddy Committed by David S. Miller

cxgb4: fix endianness when flashing boot image

Boot images are copied to memory and updated with current underlying
device ID before flashing them to adapter. Ensure the updated images
are always flashed in Big Endian to allow the firmware to read the
new images during boot properly.

Fixes: 55088355 ("cxgb4: add support to flash boot image")
Signed-off-by: default avatarRahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 33e38144
...@@ -3060,16 +3060,19 @@ int t4_read_flash(struct adapter *adapter, unsigned int addr, ...@@ -3060,16 +3060,19 @@ int t4_read_flash(struct adapter *adapter, unsigned int addr,
* @addr: the start address to write * @addr: the start address to write
* @n: length of data to write in bytes * @n: length of data to write in bytes
* @data: the data to write * @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 * 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. * 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, 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; 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) if (addr >= adapter->params.sf_size || offset + n > SF_PAGE_SIZE)
return -EINVAL; return -EINVAL;
...@@ -3080,10 +3083,14 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr, ...@@ -3080,10 +3083,14 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr,
(ret = sf1_write(adapter, 4, 1, 1, val)) != 0) (ret = sf1_write(adapter, 4, 1, 1, val)) != 0)
goto unlock; goto unlock;
for (left = n; left; left -= c) { for (left = n; left; left -= c, data += c) {
c = min(left, 4U); c = min(left, 4U);
for (val = 0, i = 0; i < c; ++i) for (val = 0, i = 0; i < c; ++i) {
val = (val << 8) + *data++; 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); ret = sf1_write(adapter, c, c != left, 1, val);
if (ret) if (ret)
...@@ -3096,7 +3103,8 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr, ...@@ -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 */ t4_write_reg(adapter, SF_OP_A, 0); /* unlock SF */
/* Read the page to verify the write succeeded */ /* 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) if (ret)
return ret; return ret;
...@@ -3692,7 +3700,7 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) ...@@ -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); memcpy(first_page, fw_data, SF_PAGE_SIZE);
((struct fw_hdr *)first_page)->fw_ver = cpu_to_be32(0xffffffff); ((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) if (ret)
goto out; goto out;
...@@ -3700,14 +3708,14 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) ...@@ -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) { for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
addr += SF_PAGE_SIZE; addr += SF_PAGE_SIZE;
fw_data += 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) if (ret)
goto out; goto out;
} }
ret = t4_write_flash(adap, ret = t4_write_flash(adap, fw_start + offsetof(struct fw_hdr, fw_ver),
fw_start + offsetof(struct fw_hdr, fw_ver), sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver,
sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver); true);
out: out:
if (ret) if (ret)
dev_err(adap->pdev_dev, "firmware download failed, error %d\n", dev_err(adap->pdev_dev, "firmware download failed, error %d\n",
...@@ -10208,7 +10216,7 @@ int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) ...@@ -10208,7 +10216,7 @@ int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
n = size - i; n = size - i;
else else
n = SF_PAGE_SIZE; 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) if (ret)
goto out; goto out;
...@@ -10677,13 +10685,14 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data, ...@@ -10677,13 +10685,14 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data,
for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) { for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
addr += SF_PAGE_SIZE; addr += SF_PAGE_SIZE;
boot_data += 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) if (ret)
goto out; goto out;
} }
ret = t4_write_flash(adap, boot_sector, SF_PAGE_SIZE, ret = t4_write_flash(adap, boot_sector, SF_PAGE_SIZE,
(const u8 *)header); (const u8 *)header, false);
out: out:
if (ret) if (ret)
...@@ -10758,7 +10767,7 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) ...@@ -10758,7 +10767,7 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
for (i = 0; i < size; i += SF_PAGE_SIZE) { for (i = 0; i < size; i += SF_PAGE_SIZE) {
n = min_t(u32, 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) if (ret)
goto out; goto out;
...@@ -10770,7 +10779,8 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) ...@@ -10770,7 +10779,8 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
for (i = 0; i < npad; i++) { for (i = 0; i < npad; i++) {
u8 data = 0; 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) if (ret)
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment