Commit f4cdcae0 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 33e38144 6d297540
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -1337,15 +1337,29 @@ 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;
	}

	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,
				  const u8 *data, u32 size)
{
+0 −2
Original line number Diff line number Diff line
@@ -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);
+29 −17
Original line number Diff line number Diff line
@@ -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;
	}