Skip to content

Commit

Permalink
qlcnic: Fix flash access interface to application
Browse files Browse the repository at this point in the history
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: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jitendra Kalsaria authored and David S. Miller committed Aug 22, 2014
1 parent d715569 commit 26acc71
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
15 changes: 14 additions & 1 deletion drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ struct qlcnic_fdt {
u16 cksum;
u16 unused;
u8 model[16];
u16 mfg_id;
u8 mfg_id;
u16 id;
u8 flag;
u8 erase_cmd;
Expand Down Expand Up @@ -2362,6 +2362,19 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter)
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
void qlcnic_register_hwmon_dev(struct qlcnic_adapter *);
void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *);
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
(addr));
(addr & 0xFFFF0000));

range = flash_offset + (count * sizeof(u32));
/* Check if data is spread across multiple sectors */
Expand Down Expand Up @@ -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,
(u8 *)&adapter->ahw->fdt,
count);

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

addr1 = (sector_start_addr & 0xFF) << 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,
reversed_addr);
Expand Down
16 changes: 15 additions & 1 deletion drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
if (ret != 0)
return ret;
qlcnic_read_crb(adapter, buf, offset, size);
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));

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

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

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

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

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

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

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

Expand Down Expand Up @@ -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].pci_func = i;
}
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
return size;
}

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

qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
ret = validate_esw_config(adapter, esw_cfg, count);
if (ret)
Expand Down Expand Up @@ -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]))
return QL_STATUS_INVALID_PARAM;
}
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
return size;
}

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

qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
np_cfg = (struct qlcnic_npar_func_cfg *)buf;
ret = validate_npar_config(adapter, np_cfg, count);
if (ret)
Expand Down Expand Up @@ -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_rx_queues = nic_info.max_rx_ques;
}
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
return size;
}

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

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

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

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

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

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

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

0 comments on commit 26acc71

Please sign in to comment.