Skip to content

Commit 26acc71

Browse files
Jitendra Kalsariadavem330
authored andcommitted
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: Jitendra Kalsaria <[email protected]> Signed-off-by: Shahed Shaikh <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d715569 commit 26acc71

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

drivers/net/ethernet/qlogic/qlcnic/qlcnic.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ struct qlcnic_fdt {
268268
u16 cksum;
269269
u16 unused;
270270
u8 model[16];
271-
u16 mfg_id;
271+
u8 mfg_id;
272272
u16 id;
273273
u8 flag;
274274
u8 erase_cmd;
@@ -2362,6 +2362,19 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter)
23622362
return QLC_DEFAULT_VNIC_COUNT;
23632363
}
23642364

2365+
static inline void qlcnic_swap32_buffer(u32 *buffer, int count)
2366+
{
2367+
#if defined(__BIG_ENDIAN)
2368+
u32 *tmp = buffer;
2369+
int i;
2370+
2371+
for (i = 0; i < count; i++) {
2372+
*tmp = swab32(*tmp);
2373+
tmp++;
2374+
}
2375+
#endif
2376+
}
2377+
23652378
#ifdef CONFIG_QLCNIC_HWMON
23662379
void qlcnic_register_hwmon_dev(struct qlcnic_adapter *);
23672380
void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *);

drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,7 +2603,7 @@ int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
26032603
}
26042604

26052605
qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
2606-
(addr));
2606+
(addr & 0xFFFF0000));
26072607

26082608
range = flash_offset + (count * sizeof(u32));
26092609
/* Check if data is spread across multiple sectors */
@@ -2753,7 +2753,7 @@ int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
27532753
ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
27542754
(u8 *)&adapter->ahw->fdt,
27552755
count);
2756-
2756+
qlcnic_swap32_buffer((u32 *)&adapter->ahw->fdt, count);
27572757
qlcnic_83xx_unlock_flash(adapter);
27582758
return ret;
27592759
}
@@ -2788,7 +2788,7 @@ int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
27882788

27892789
addr1 = (sector_start_addr & 0xFF) << 16;
27902790
addr2 = (sector_start_addr & 0xFF0000) >> 16;
2791-
reversed_addr = addr1 | addr2;
2791+
reversed_addr = addr1 | addr2 | (sector_start_addr & 0xFF00);
27922792

27932793
qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
27942794
reversed_addr);

drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
280280
if (ret != 0)
281281
return ret;
282282
qlcnic_read_crb(adapter, buf, offset, size);
283+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
283284

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

300+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
299301
qlcnic_write_crb(adapter, buf, offset, size);
300302
return size;
301303
}
@@ -329,6 +331,7 @@ static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
329331
return -EIO;
330332

331333
memcpy(buf, &data, size);
334+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
332335

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

352+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
349353
memcpy(&data, buf, size);
350354

351355
if (qlcnic_pci_mem_write_2M(adapter, offset, data))
@@ -412,6 +416,7 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
412416
if (rem)
413417
return QL_STATUS_INVALID_PARAM;
414418

419+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
415420
pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
416421
ret = validate_pm_config(adapter, pm_cfg, count);
417422

@@ -474,6 +479,7 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
474479
pm_cfg[pci_func].dest_npar = 0;
475480
pm_cfg[pci_func].pci_func = i;
476481
}
482+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
477483
return size;
478484
}
479485

@@ -555,6 +561,7 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
555561
if (rem)
556562
return QL_STATUS_INVALID_PARAM;
557563

564+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
558565
esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
559566
ret = validate_esw_config(adapter, esw_cfg, count);
560567
if (ret)
@@ -649,6 +656,7 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
649656
if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
650657
return QL_STATUS_INVALID_PARAM;
651658
}
659+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
652660
return size;
653661
}
654662

@@ -688,6 +696,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
688696
if (rem)
689697
return QL_STATUS_INVALID_PARAM;
690698

699+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
691700
np_cfg = (struct qlcnic_npar_func_cfg *)buf;
692701
ret = validate_npar_config(adapter, np_cfg, count);
693702
if (ret)
@@ -759,6 +768,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
759768
np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques;
760769
np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques;
761770
}
771+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
762772
return size;
763773
}
764774

@@ -916,6 +926,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
916926

917927
pci_cfg = (struct qlcnic_pci_func_cfg *)buf;
918928
count = size / sizeof(struct qlcnic_pci_func_cfg);
929+
qlcnic_swap32_buffer((u32 *)pci_info, size / sizeof(u32));
919930
for (i = 0; i < count; i++) {
920931
pci_cfg[i].pci_func = pci_info[i].id;
921932
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,
969980
}
970981

971982
qlcnic_83xx_unlock_flash(adapter);
983+
qlcnic_swap32_buffer((u32 *)p_read_buf, count);
972984
memcpy(buf, p_read_buf, size);
973985
kfree(p_read_buf);
974986

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

1001+
count = size / sizeof(u32);
1002+
qlcnic_swap32_buffer((u32 *)buf, count);
9891003
memcpy(p_cache, buf, size);
9901004
p_src = p_cache;
991-
count = size / sizeof(u32);
9921005

9931006
if (qlcnic_83xx_lock_flash(adapter) != 0) {
9941007
kfree(p_cache);
@@ -1053,6 +1066,7 @@ static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter,
10531066
if (!p_cache)
10541067
return -ENOMEM;
10551068

1069+
qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
10561070
memcpy(p_cache, buf, size);
10571071
p_src = p_cache;
10581072
count = size / sizeof(u32);

0 commit comments

Comments
 (0)