Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26acc712 authored by Jitendra Kalsaria's avatar Jitendra Kalsaria Committed by David S. Miller
Browse files

qlcnic: Fix flash access interface to application



Application expects flash data in little endian, but driver reads/writes
flash data using readl()/writel() APIs which swaps data on big endian machine.
So, swap the data after reading from and before writing to flash memory.

Signed-off-by: default avatarJitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: default avatarShahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d7155691
Loading
Loading
Loading
Loading
+14 −1
Original line number Original line Diff line number Diff line
@@ -268,7 +268,7 @@ struct qlcnic_fdt {
	u16	cksum;
	u16	cksum;
	u16	unused;
	u16	unused;
	u8	model[16];
	u8	model[16];
	u16	mfg_id;
	u8	mfg_id;
	u16	id;
	u16	id;
	u8	flag;
	u8	flag;
	u8	erase_cmd;
	u8	erase_cmd;
@@ -2362,6 +2362,19 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter)
		return QLC_DEFAULT_VNIC_COUNT;
		return QLC_DEFAULT_VNIC_COUNT;
}
}


static inline void qlcnic_swap32_buffer(u32 *buffer, int count)
{
#if defined(__BIG_ENDIAN)
	u32 *tmp = buffer;
	int i;

	for (i = 0; i < count; i++) {
		*tmp = swab32(*tmp);
		tmp++;
	}
#endif
}

#ifdef CONFIG_QLCNIC_HWMON
#ifdef CONFIG_QLCNIC_HWMON
void qlcnic_register_hwmon_dev(struct qlcnic_adapter *);
void qlcnic_register_hwmon_dev(struct qlcnic_adapter *);
void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *);
void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *);
+3 −3
Original line number Original line Diff line number Diff line
@@ -2603,7 +2603,7 @@ int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
	}
	}


	qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
	qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
				     (addr));
				     (addr & 0xFFFF0000));


	range = flash_offset + (count * sizeof(u32));
	range = flash_offset + (count * sizeof(u32));
	/* Check if data is spread across multiple sectors */
	/* Check if data is spread across multiple sectors */
@@ -2753,7 +2753,7 @@ int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
	ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
	ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
						(u8 *)&adapter->ahw->fdt,
						(u8 *)&adapter->ahw->fdt,
						count);
						count);

	qlcnic_swap32_buffer((u32 *)&adapter->ahw->fdt, count);
	qlcnic_83xx_unlock_flash(adapter);
	qlcnic_83xx_unlock_flash(adapter);
	return ret;
	return ret;
}
}
@@ -2788,7 +2788,7 @@ int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,


	addr1 = (sector_start_addr & 0xFF) << 16;
	addr1 = (sector_start_addr & 0xFF) << 16;
	addr2 = (sector_start_addr & 0xFF0000) >> 16;
	addr2 = (sector_start_addr & 0xFF0000) >> 16;
	reversed_addr = addr1 | addr2;
	reversed_addr = addr1 | addr2 | (sector_start_addr & 0xFF00);


	qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
	qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
				     reversed_addr);
				     reversed_addr);
+15 −1
Original line number Original line Diff line number Diff line
@@ -280,6 +280,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
	if (ret != 0)
	if (ret != 0)
		return ret;
		return ret;
	qlcnic_read_crb(adapter, buf, offset, size);
	qlcnic_read_crb(adapter, buf, offset, size);
	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));


	return size;
	return size;
}
}
@@ -296,6 +297,7 @@ static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
	if (ret != 0)
	if (ret != 0)
		return ret;
		return ret;


	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
	qlcnic_write_crb(adapter, buf, offset, size);
	qlcnic_write_crb(adapter, buf, offset, size);
	return size;
	return size;
}
}
@@ -329,6 +331,7 @@ static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
		return -EIO;
		return -EIO;


	memcpy(buf, &data, size);
	memcpy(buf, &data, size);
	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));


	return size;
	return size;
}
}
@@ -346,6 +349,7 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
	if (ret != 0)
	if (ret != 0)
		return ret;
		return ret;


	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
	memcpy(&data, buf, size);
	memcpy(&data, buf, size);


	if (qlcnic_pci_mem_write_2M(adapter, offset, data))
	if (qlcnic_pci_mem_write_2M(adapter, offset, data))
@@ -412,6 +416,7 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
	if (rem)
	if (rem)
		return QL_STATUS_INVALID_PARAM;
		return QL_STATUS_INVALID_PARAM;


	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
	pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
	pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
	ret = validate_pm_config(adapter, pm_cfg, count);
	ret = validate_pm_config(adapter, pm_cfg, count);


@@ -474,6 +479,7 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
		pm_cfg[pci_func].dest_npar = 0;
		pm_cfg[pci_func].dest_npar = 0;
		pm_cfg[pci_func].pci_func = i;
		pm_cfg[pci_func].pci_func = i;
	}
	}
	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
	return size;
	return size;
}
}


@@ -555,6 +561,7 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
	if (rem)
	if (rem)
		return QL_STATUS_INVALID_PARAM;
		return QL_STATUS_INVALID_PARAM;


	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
	esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
	esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
	ret = validate_esw_config(adapter, esw_cfg, count);
	ret = validate_esw_config(adapter, esw_cfg, count);
	if (ret)
	if (ret)
@@ -649,6 +656,7 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
		if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
		if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
			return QL_STATUS_INVALID_PARAM;
			return QL_STATUS_INVALID_PARAM;
	}
	}
	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
	return size;
	return size;
}
}


@@ -688,6 +696,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
	if (rem)
	if (rem)
		return QL_STATUS_INVALID_PARAM;
		return QL_STATUS_INVALID_PARAM;


	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
	np_cfg = (struct qlcnic_npar_func_cfg *)buf;
	np_cfg = (struct qlcnic_npar_func_cfg *)buf;
	ret = validate_npar_config(adapter, np_cfg, count);
	ret = validate_npar_config(adapter, np_cfg, count);
	if (ret)
	if (ret)
@@ -759,6 +768,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
		np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques;
		np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques;
		np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques;
		np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques;
	}
	}
	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
	return size;
	return size;
}
}


@@ -916,6 +926,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,


	pci_cfg = (struct qlcnic_pci_func_cfg *)buf;
	pci_cfg = (struct qlcnic_pci_func_cfg *)buf;
	count = size / sizeof(struct qlcnic_pci_func_cfg);
	count = size / sizeof(struct qlcnic_pci_func_cfg);
	qlcnic_swap32_buffer((u32 *)pci_info, size / sizeof(u32));
	for (i = 0; i < count; i++) {
	for (i = 0; i < count; i++) {
		pci_cfg[i].pci_func = pci_info[i].id;
		pci_cfg[i].pci_func = pci_info[i].id;
		pci_cfg[i].func_type = pci_info[i].type;
		pci_cfg[i].func_type = pci_info[i].type;
@@ -969,6 +980,7 @@ static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp,
	}
	}


	qlcnic_83xx_unlock_flash(adapter);
	qlcnic_83xx_unlock_flash(adapter);
	qlcnic_swap32_buffer((u32 *)p_read_buf, count);
	memcpy(buf, p_read_buf, size);
	memcpy(buf, p_read_buf, size);
	kfree(p_read_buf);
	kfree(p_read_buf);


@@ -986,9 +998,10 @@ static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter,
	if (!p_cache)
	if (!p_cache)
		return -ENOMEM;
		return -ENOMEM;


	count = size / sizeof(u32);
	qlcnic_swap32_buffer((u32 *)buf, count);
	memcpy(p_cache, buf, size);
	memcpy(p_cache, buf, size);
	p_src = p_cache;
	p_src = p_cache;
	count = size / sizeof(u32);


	if (qlcnic_83xx_lock_flash(adapter) != 0) {
	if (qlcnic_83xx_lock_flash(adapter) != 0) {
		kfree(p_cache);
		kfree(p_cache);
@@ -1053,6 +1066,7 @@ static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter,
	if (!p_cache)
	if (!p_cache)
		return -ENOMEM;
		return -ENOMEM;


	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
	memcpy(p_cache, buf, size);
	memcpy(p_cache, buf, size);
	p_src = p_cache;
	p_src = p_cache;
	count = size / sizeof(u32);
	count = size / sizeof(u32);