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: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2014-08-21 17:43:20 -07:00
commit 9a6d33c307
5 changed files with 114 additions and 15 deletions

View File

@ -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;
@ -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 *);

View File

@ -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 */
@ -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;
}
@ -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);

View File

@ -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;
const struct firmware *fw = fw_info->fw;
u32 dest, *p_cache;
u32 dest, *p_cache, *temp;
int i, ret = -EIO;
__le32 *temp_le;
u8 data[16];
size_t size;
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);
size = (fw->size & ~0xF);
p_cache = (u32 *)fw->data;
p_cache = temp;
addr = (u64)dest;
ret = qlcnic_ms_mem_write128(adapter, addr,
p_cache, size / 16);
if (ret) {
dev_err(&adapter->pdev->dev, "MS memory write failed\n");
release_firmware(fw);
fw_info->fw = NULL;
return -EIO;
goto exit;
}
/* alignment check */
if (fw->size & 0xF) {
addr = dest + size;
for (i = 0; i < (fw->size & 0xF); i++)
data[i] = fw->data[size + i];
data[i] = temp[size + i];
for (; i < 16; i++)
data[i] = 0;
ret = qlcnic_ms_mem_write128(adapter, addr,
@ -1410,15 +1424,16 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
if (ret) {
dev_err(&adapter->pdev->dev,
"MS memory write failed\n");
release_firmware(fw);
fw_info->fw = NULL;
return -EIO;
goto exit;
}
}
exit:
release_firmware(fw);
fw_info->fw = NULL;
kfree(temp);
return 0;
return ret;
}
static void qlcnic_83xx_dump_pause_control_regs(struct qlcnic_adapter *adapter)

View File

@ -47,15 +47,26 @@ struct qlcnic_common_entry_hdr {
u32 type;
u32 offset;
u32 cap_size;
#if defined(__LITTLE_ENDIAN)
u8 mask;
u8 rsvd[2];
u8 flags;
#else
u8 flags;
u8 rsvd[2];
u8 mask;
#endif
} __packed;
struct __crb {
u32 addr;
#if defined(__LITTLE_ENDIAN)
u8 stride;
u8 rsvd1[3];
#else
u8 rsvd1[3];
u8 stride;
#endif
u32 data_size;
u32 no_ops;
u32 rsvd2[4];
@ -63,15 +74,28 @@ struct __crb {
struct __ctrl {
u32 addr;
#if defined(__LITTLE_ENDIAN)
u8 stride;
u8 index_a;
u16 timeout;
#else
u16 timeout;
u8 index_a;
u8 stride;
#endif
u32 data_size;
u32 no_ops;
#if defined(__LITTLE_ENDIAN)
u8 opcode;
u8 index_v;
u8 shl_val;
u8 shr_val;
#else
u8 shr_val;
u8 shl_val;
u8 index_v;
u8 opcode;
#endif
u32 val1;
u32 val2;
u32 val3;
@ -79,16 +103,27 @@ struct __ctrl {
struct __cache {
u32 addr;
#if defined(__LITTLE_ENDIAN)
u16 stride;
u16 init_tag_val;
#else
u16 init_tag_val;
u16 stride;
#endif
u32 size;
u32 no_ops;
u32 ctrl_addr;
u32 ctrl_val;
u32 read_addr;
#if defined(__LITTLE_ENDIAN)
u8 read_addr_stride;
u8 read_addr_num;
u8 rsvd1[2];
#else
u8 rsvd1[2];
u8 read_addr_num;
u8 read_addr_stride;
#endif
} __packed;
struct __ocm {
@ -122,23 +157,39 @@ struct __mux {
struct __queue {
u32 sel_addr;
#if defined(__LITTLE_ENDIAN)
u16 stride;
u8 rsvd[2];
#else
u8 rsvd[2];
u16 stride;
#endif
u32 size;
u32 no_ops;
u8 rsvd2[8];
u32 read_addr;
#if defined(__LITTLE_ENDIAN)
u8 read_addr_stride;
u8 read_addr_cnt;
u8 rsvd3[2];
#else
u8 rsvd3[2];
u8 read_addr_cnt;
u8 read_addr_stride;
#endif
} __packed;
struct __pollrd {
u32 sel_addr;
u32 read_addr;
u32 sel_val;
#if defined(__LITTLE_ENDIAN)
u16 sel_val_stride;
u16 no_ops;
#else
u16 no_ops;
u16 sel_val_stride;
#endif
u32 poll_wait;
u32 poll_mask;
u32 data_size;
@ -153,9 +204,15 @@ struct __mux2 {
u32 no_ops;
u32 sel_val_mask;
u32 read_addr;
#if defined(__LITTLE_ENDIAN)
u8 sel_val_stride;
u8 data_size;
u8 rsvd[2];
#else
u8 rsvd[2];
u8 data_size;
u8 sel_val_stride;
#endif
} __packed;
struct __pollrdmwr {

View File

@ -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;
}
@ -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;
}
@ -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;
}
@ -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))
@ -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);
@ -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;
}
@ -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)
@ -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;
}
@ -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)
@ -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;
}
@ -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;
@ -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);
@ -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);
@ -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);