mirror of https://gitee.com/openkylin/linux.git
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:
commit
9a6d33c307
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue