Commit 9a6d33c3 authored by David S. Miller's avatar David S. Miller

Merge branch 'qlcnic'

Shahed Shaikh says:

====================
qlcnic: Bug fixes

This series fixes some bugs related to endianess.

Please apply this series to net.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d7155691 3d8623e6
...@@ -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);
......
...@@ -1378,31 +1378,45 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) ...@@ -1378,31 +1378,45 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
{ {
struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info; struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info;
const struct firmware *fw = fw_info->fw; const struct firmware *fw = fw_info->fw;
u32 dest, *p_cache; u32 dest, *p_cache, *temp;
int i, ret = -EIO; int i, ret = -EIO;
__le32 *temp_le;
u8 data[16]; u8 data[16];
size_t size; size_t size;
u64 addr; u64 addr;
temp = kzalloc(fw->size, GFP_KERNEL);
if (!temp) {
release_firmware(fw);
fw_info->fw = NULL;
return -ENOMEM;
}
temp_le = (__le32 *)fw->data;
/* FW image in file is in little endian, swap the data to nullify
* the effect of writel() operation on big endian platform.
*/
for (i = 0; i < fw->size / sizeof(u32); i++)
temp[i] = __le32_to_cpu(temp_le[i]);
dest = QLCRDX(adapter->ahw, QLCNIC_FW_IMAGE_ADDR); dest = QLCRDX(adapter->ahw, QLCNIC_FW_IMAGE_ADDR);
size = (fw->size & ~0xF); size = (fw->size & ~0xF);
p_cache = (u32 *)fw->data; p_cache = temp;
addr = (u64)dest; addr = (u64)dest;
ret = qlcnic_ms_mem_write128(adapter, addr, ret = qlcnic_ms_mem_write128(adapter, addr,
p_cache, size / 16); p_cache, size / 16);
if (ret) { if (ret) {
dev_err(&adapter->pdev->dev, "MS memory write failed\n"); dev_err(&adapter->pdev->dev, "MS memory write failed\n");
release_firmware(fw); goto exit;
fw_info->fw = NULL;
return -EIO;
} }
/* alignment check */ /* alignment check */
if (fw->size & 0xF) { if (fw->size & 0xF) {
addr = dest + size; addr = dest + size;
for (i = 0; i < (fw->size & 0xF); i++) for (i = 0; i < (fw->size & 0xF); i++)
data[i] = fw->data[size + i]; data[i] = temp[size + i];
for (; i < 16; i++) for (; i < 16; i++)
data[i] = 0; data[i] = 0;
ret = qlcnic_ms_mem_write128(adapter, addr, ret = qlcnic_ms_mem_write128(adapter, addr,
...@@ -1410,15 +1424,16 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) ...@@ -1410,15 +1424,16 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
if (ret) { if (ret) {
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
"MS memory write failed\n"); "MS memory write failed\n");
release_firmware(fw); goto exit;
fw_info->fw = NULL;
return -EIO;
} }
} }
exit:
release_firmware(fw); release_firmware(fw);
fw_info->fw = NULL; fw_info->fw = NULL;
kfree(temp);
return 0; return ret;
} }
static void qlcnic_83xx_dump_pause_control_regs(struct qlcnic_adapter *adapter) static void qlcnic_83xx_dump_pause_control_regs(struct qlcnic_adapter *adapter)
......
...@@ -47,15 +47,26 @@ struct qlcnic_common_entry_hdr { ...@@ -47,15 +47,26 @@ struct qlcnic_common_entry_hdr {
u32 type; u32 type;
u32 offset; u32 offset;
u32 cap_size; u32 cap_size;
#if defined(__LITTLE_ENDIAN)
u8 mask; u8 mask;
u8 rsvd[2]; u8 rsvd[2];
u8 flags; u8 flags;
#else
u8 flags;
u8 rsvd[2];
u8 mask;
#endif
} __packed; } __packed;
struct __crb { struct __crb {
u32 addr; u32 addr;
#if defined(__LITTLE_ENDIAN)
u8 stride; u8 stride;
u8 rsvd1[3]; u8 rsvd1[3];
#else
u8 rsvd1[3];
u8 stride;
#endif
u32 data_size; u32 data_size;
u32 no_ops; u32 no_ops;
u32 rsvd2[4]; u32 rsvd2[4];
...@@ -63,15 +74,28 @@ struct __crb { ...@@ -63,15 +74,28 @@ struct __crb {
struct __ctrl { struct __ctrl {
u32 addr; u32 addr;
#if defined(__LITTLE_ENDIAN)
u8 stride; u8 stride;
u8 index_a; u8 index_a;
u16 timeout; u16 timeout;
#else
u16 timeout;
u8 index_a;
u8 stride;
#endif
u32 data_size; u32 data_size;
u32 no_ops; u32 no_ops;
#if defined(__LITTLE_ENDIAN)
u8 opcode; u8 opcode;
u8 index_v; u8 index_v;
u8 shl_val; u8 shl_val;
u8 shr_val; u8 shr_val;
#else
u8 shr_val;
u8 shl_val;
u8 index_v;
u8 opcode;
#endif
u32 val1; u32 val1;
u32 val2; u32 val2;
u32 val3; u32 val3;
...@@ -79,16 +103,27 @@ struct __ctrl { ...@@ -79,16 +103,27 @@ struct __ctrl {
struct __cache { struct __cache {
u32 addr; u32 addr;
#if defined(__LITTLE_ENDIAN)
u16 stride; u16 stride;
u16 init_tag_val; u16 init_tag_val;
#else
u16 init_tag_val;
u16 stride;
#endif
u32 size; u32 size;
u32 no_ops; u32 no_ops;
u32 ctrl_addr; u32 ctrl_addr;
u32 ctrl_val; u32 ctrl_val;
u32 read_addr; u32 read_addr;
#if defined(__LITTLE_ENDIAN)
u8 read_addr_stride; u8 read_addr_stride;
u8 read_addr_num; u8 read_addr_num;
u8 rsvd1[2]; u8 rsvd1[2];
#else
u8 rsvd1[2];
u8 read_addr_num;
u8 read_addr_stride;
#endif
} __packed; } __packed;
struct __ocm { struct __ocm {
...@@ -122,23 +157,39 @@ struct __mux { ...@@ -122,23 +157,39 @@ struct __mux {
struct __queue { struct __queue {
u32 sel_addr; u32 sel_addr;
#if defined(__LITTLE_ENDIAN)
u16 stride; u16 stride;
u8 rsvd[2]; u8 rsvd[2];
#else
u8 rsvd[2];
u16 stride;
#endif
u32 size; u32 size;
u32 no_ops; u32 no_ops;
u8 rsvd2[8]; u8 rsvd2[8];
u32 read_addr; u32 read_addr;
#if defined(__LITTLE_ENDIAN)
u8 read_addr_stride; u8 read_addr_stride;
u8 read_addr_cnt; u8 read_addr_cnt;
u8 rsvd3[2]; u8 rsvd3[2];
#else
u8 rsvd3[2];
u8 read_addr_cnt;
u8 read_addr_stride;
#endif
} __packed; } __packed;
struct __pollrd { struct __pollrd {
u32 sel_addr; u32 sel_addr;
u32 read_addr; u32 read_addr;
u32 sel_val; u32 sel_val;
#if defined(__LITTLE_ENDIAN)
u16 sel_val_stride; u16 sel_val_stride;
u16 no_ops; u16 no_ops;
#else
u16 no_ops;
u16 sel_val_stride;
#endif
u32 poll_wait; u32 poll_wait;
u32 poll_mask; u32 poll_mask;
u32 data_size; u32 data_size;
...@@ -153,9 +204,15 @@ struct __mux2 { ...@@ -153,9 +204,15 @@ struct __mux2 {
u32 no_ops; u32 no_ops;
u32 sel_val_mask; u32 sel_val_mask;
u32 read_addr; u32 read_addr;
#if defined(__LITTLE_ENDIAN)
u8 sel_val_stride; u8 sel_val_stride;
u8 data_size; u8 data_size;
u8 rsvd[2]; u8 rsvd[2];
#else
u8 rsvd[2];
u8 data_size;
u8 sel_val_stride;
#endif
} __packed; } __packed;
struct __pollrdmwr { struct __pollrdmwr {
......
...@@ -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