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

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
...@@ -268,7 +268,7 @@ struct qlcnic_fdt { ...@@ -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) ...@@ -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 *);
......
...@@ -2603,7 +2603,7 @@ int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter, ...@@ -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) ...@@ -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, ...@@ -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);
......
...@@ -280,6 +280,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
......
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