diff options
author | Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> | 2014-08-18 09:31:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-21 20:43:15 -0400 |
commit | 26acc712526e9a8a849c819ffb8fe2d4e1f7c063 (patch) | |
tree | 944ef40ac308fa7f76409887e7749fb1a49e9227 | |
parent | d7155691127d69dff28e371e61fa68375a70a456 (diff) |
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 <jitendra.kalsaria@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 16 |
3 files changed, 32 insertions, 5 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 16039d1497b8..b84f5ea3d659 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -268,7 +268,7 @@ struct qlcnic_fdt { | |||
268 | u16 cksum; | 268 | u16 cksum; |
269 | u16 unused; | 269 | u16 unused; |
270 | u8 model[16]; | 270 | u8 model[16]; |
271 | u16 mfg_id; | 271 | u8 mfg_id; |
272 | u16 id; | 272 | u16 id; |
273 | u8 flag; | 273 | u8 flag; |
274 | u8 erase_cmd; | 274 | u8 erase_cmd; |
@@ -2362,6 +2362,19 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter) | |||
2362 | return QLC_DEFAULT_VNIC_COUNT; | 2362 | return QLC_DEFAULT_VNIC_COUNT; |
2363 | } | 2363 | } |
2364 | 2364 | ||
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 | |||
2365 | #ifdef CONFIG_QLCNIC_HWMON | 2378 | #ifdef CONFIG_QLCNIC_HWMON |
2366 | void qlcnic_register_hwmon_dev(struct qlcnic_adapter *); | 2379 | void qlcnic_register_hwmon_dev(struct qlcnic_adapter *); |
2367 | void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *); | 2380 | void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index a4a4ec0b68f8..476e4998ef99 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -2603,7 +2603,7 @@ int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter, | |||
2603 | } | 2603 | } |
2604 | 2604 | ||
2605 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW, | 2605 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW, |
2606 | (addr)); | 2606 | (addr & 0xFFFF0000)); |
2607 | 2607 | ||
2608 | range = flash_offset + (count * sizeof(u32)); | 2608 | range = flash_offset + (count * sizeof(u32)); |
2609 | /* Check if data is spread across multiple sectors */ | 2609 | /* Check if data is spread across multiple sectors */ |
@@ -2753,7 +2753,7 @@ int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter) | |||
2753 | ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION, | 2753 | ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION, |
2754 | (u8 *)&adapter->ahw->fdt, | 2754 | (u8 *)&adapter->ahw->fdt, |
2755 | count); | 2755 | count); |
2756 | 2756 | qlcnic_swap32_buffer((u32 *)&adapter->ahw->fdt, count); | |
2757 | qlcnic_83xx_unlock_flash(adapter); | 2757 | qlcnic_83xx_unlock_flash(adapter); |
2758 | return ret; | 2758 | return ret; |
2759 | } | 2759 | } |
@@ -2788,7 +2788,7 @@ int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter, | |||
2788 | 2788 | ||
2789 | addr1 = (sector_start_addr & 0xFF) << 16; | 2789 | addr1 = (sector_start_addr & 0xFF) << 16; |
2790 | addr2 = (sector_start_addr & 0xFF0000) >> 16; | 2790 | addr2 = (sector_start_addr & 0xFF0000) >> 16; |
2791 | reversed_addr = addr1 | addr2; | 2791 | reversed_addr = addr1 | addr2 | (sector_start_addr & 0xFF00); |
2792 | 2792 | ||
2793 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, | 2793 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, |
2794 | reversed_addr); | 2794 | reversed_addr); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index f5786d5792df..59a721fba018 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -280,6 +280,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, | |||
280 | if (ret != 0) | 280 | if (ret != 0) |
281 | return ret; | 281 | return ret; |
282 | qlcnic_read_crb(adapter, buf, offset, size); | 282 | qlcnic_read_crb(adapter, buf, offset, size); |
283 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
283 | 284 | ||
284 | return size; | 285 | return size; |
285 | } | 286 | } |
@@ -296,6 +297,7 @@ static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj, | |||
296 | if (ret != 0) | 297 | if (ret != 0) |
297 | return ret; | 298 | return ret; |
298 | 299 | ||
300 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
299 | qlcnic_write_crb(adapter, buf, offset, size); | 301 | qlcnic_write_crb(adapter, buf, offset, size); |
300 | return size; | 302 | return size; |
301 | } | 303 | } |
@@ -329,6 +331,7 @@ static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj, | |||
329 | return -EIO; | 331 | return -EIO; |
330 | 332 | ||
331 | memcpy(buf, &data, size); | 333 | memcpy(buf, &data, size); |
334 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
332 | 335 | ||
333 | return size; | 336 | return size; |
334 | } | 337 | } |
@@ -346,6 +349,7 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, | |||
346 | if (ret != 0) | 349 | if (ret != 0) |
347 | return ret; | 350 | return ret; |
348 | 351 | ||
352 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
349 | memcpy(&data, buf, size); | 353 | memcpy(&data, buf, size); |
350 | 354 | ||
351 | if (qlcnic_pci_mem_write_2M(adapter, offset, data)) | 355 | 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 | if (rem) | 416 | if (rem) |
413 | return QL_STATUS_INVALID_PARAM; | 417 | return QL_STATUS_INVALID_PARAM; |
414 | 418 | ||
419 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
415 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; | 420 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; |
416 | ret = validate_pm_config(adapter, pm_cfg, count); | 421 | ret = validate_pm_config(adapter, pm_cfg, count); |
417 | 422 | ||
@@ -474,6 +479,7 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, | |||
474 | pm_cfg[pci_func].dest_npar = 0; | 479 | pm_cfg[pci_func].dest_npar = 0; |
475 | pm_cfg[pci_func].pci_func = i; | 480 | pm_cfg[pci_func].pci_func = i; |
476 | } | 481 | } |
482 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
477 | return size; | 483 | return size; |
478 | } | 484 | } |
479 | 485 | ||
@@ -555,6 +561,7 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
555 | if (rem) | 561 | if (rem) |
556 | return QL_STATUS_INVALID_PARAM; | 562 | return QL_STATUS_INVALID_PARAM; |
557 | 563 | ||
564 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
558 | esw_cfg = (struct qlcnic_esw_func_cfg *)buf; | 565 | esw_cfg = (struct qlcnic_esw_func_cfg *)buf; |
559 | ret = validate_esw_config(adapter, esw_cfg, count); | 566 | ret = validate_esw_config(adapter, esw_cfg, count); |
560 | if (ret) | 567 | if (ret) |
@@ -649,6 +656,7 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, | |||
649 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) | 656 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) |
650 | return QL_STATUS_INVALID_PARAM; | 657 | return QL_STATUS_INVALID_PARAM; |
651 | } | 658 | } |
659 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
652 | return size; | 660 | return size; |
653 | } | 661 | } |
654 | 662 | ||
@@ -688,6 +696,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
688 | if (rem) | 696 | if (rem) |
689 | return QL_STATUS_INVALID_PARAM; | 697 | return QL_STATUS_INVALID_PARAM; |
690 | 698 | ||
699 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
691 | np_cfg = (struct qlcnic_npar_func_cfg *)buf; | 700 | np_cfg = (struct qlcnic_npar_func_cfg *)buf; |
692 | ret = validate_npar_config(adapter, np_cfg, count); | 701 | ret = validate_npar_config(adapter, np_cfg, count); |
693 | if (ret) | 702 | if (ret) |
@@ -759,6 +768,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
759 | np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques; | 768 | np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques; |
760 | np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques; | 769 | np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques; |
761 | } | 770 | } |
771 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
762 | return size; | 772 | return size; |
763 | } | 773 | } |
764 | 774 | ||
@@ -916,6 +926,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
916 | 926 | ||
917 | pci_cfg = (struct qlcnic_pci_func_cfg *)buf; | 927 | pci_cfg = (struct qlcnic_pci_func_cfg *)buf; |
918 | count = size / sizeof(struct qlcnic_pci_func_cfg); | 928 | count = size / sizeof(struct qlcnic_pci_func_cfg); |
929 | qlcnic_swap32_buffer((u32 *)pci_info, size / sizeof(u32)); | ||
919 | for (i = 0; i < count; i++) { | 930 | for (i = 0; i < count; i++) { |
920 | pci_cfg[i].pci_func = pci_info[i].id; | 931 | pci_cfg[i].pci_func = pci_info[i].id; |
921 | pci_cfg[i].func_type = pci_info[i].type; | 932 | 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 | } | 980 | } |
970 | 981 | ||
971 | qlcnic_83xx_unlock_flash(adapter); | 982 | qlcnic_83xx_unlock_flash(adapter); |
983 | qlcnic_swap32_buffer((u32 *)p_read_buf, count); | ||
972 | memcpy(buf, p_read_buf, size); | 984 | memcpy(buf, p_read_buf, size); |
973 | kfree(p_read_buf); | 985 | kfree(p_read_buf); |
974 | 986 | ||
@@ -986,9 +998,10 @@ static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter, | |||
986 | if (!p_cache) | 998 | if (!p_cache) |
987 | return -ENOMEM; | 999 | return -ENOMEM; |
988 | 1000 | ||
1001 | count = size / sizeof(u32); | ||
1002 | qlcnic_swap32_buffer((u32 *)buf, count); | ||
989 | memcpy(p_cache, buf, size); | 1003 | memcpy(p_cache, buf, size); |
990 | p_src = p_cache; | 1004 | p_src = p_cache; |
991 | count = size / sizeof(u32); | ||
992 | 1005 | ||
993 | if (qlcnic_83xx_lock_flash(adapter) != 0) { | 1006 | if (qlcnic_83xx_lock_flash(adapter) != 0) { |
994 | kfree(p_cache); | 1007 | kfree(p_cache); |
@@ -1053,6 +1066,7 @@ static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter, | |||
1053 | if (!p_cache) | 1066 | if (!p_cache) |
1054 | return -ENOMEM; | 1067 | return -ENOMEM; |
1055 | 1068 | ||
1069 | qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32)); | ||
1056 | memcpy(p_cache, buf, size); | 1070 | memcpy(p_cache, buf, size); |
1057 | p_src = p_cache; | 1071 | p_src = p_cache; |
1058 | count = size / sizeof(u32); | 1072 | count = size / sizeof(u32); |