diff options
author | Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> | 2014-02-21 13:20:11 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-24 18:43:19 -0500 |
commit | d91abf903b1d39f46251305328e245c76f14b349 (patch) | |
tree | 77a37610a5d9be5b92a266bcb80b852e6232b60a /drivers | |
parent | 225837a076b284ac408a3b0104584ae0ad117a0c (diff) |
qlcnic: Updates to QLogic application/driver interface for virtual NIC configuration
Qlogic application interface in the driver which has larger than 8 vNIC
configuration support has been updated to handle the following cases:
o Only 8 or lower total vNICs were enabled within the vNIC 0-7 range
o vNICs were enabled in the vNIC 0-15 range such that enabled vNICs were
not contiguous and only 8 or lower number of total VNICs were enabled
o Disconnect in the vNIC mapping between application and driver when the
enabled VNICs were dis contiguous
Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 102 |
1 files changed, 37 insertions, 65 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 3d64113a35af..448d156c3d08 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -350,33 +350,15 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, | |||
350 | return size; | 350 | return size; |
351 | } | 351 | } |
352 | 352 | ||
353 | static u32 qlcnic_get_pci_func_count(struct qlcnic_adapter *adapter) | ||
354 | { | ||
355 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
356 | u32 count = 0; | ||
357 | |||
358 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) | ||
359 | return ahw->total_nic_func; | ||
360 | |||
361 | if (ahw->total_pci_func <= QLC_DEFAULT_VNIC_COUNT) | ||
362 | count = QLC_DEFAULT_VNIC_COUNT; | ||
363 | else | ||
364 | count = ahw->max_vnic_func; | ||
365 | |||
366 | return count; | ||
367 | } | ||
368 | |||
369 | int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) | 353 | int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) |
370 | { | 354 | { |
371 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
372 | int i; | 355 | int i; |
373 | 356 | ||
374 | for (i = 0; i < pci_func_count; i++) { | 357 | for (i = 0; i < adapter->ahw->max_vnic_func; i++) { |
375 | if (adapter->npars[i].pci_func == pci_func) | 358 | if (adapter->npars[i].pci_func == pci_func) |
376 | return i; | 359 | return i; |
377 | } | 360 | } |
378 | 361 | return -EINVAL; | |
379 | return -1; | ||
380 | } | 362 | } |
381 | 363 | ||
382 | static int validate_pm_config(struct qlcnic_adapter *adapter, | 364 | static int validate_pm_config(struct qlcnic_adapter *adapter, |
@@ -464,23 +446,21 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, | |||
464 | { | 446 | { |
465 | struct device *dev = container_of(kobj, struct device, kobj); | 447 | struct device *dev = container_of(kobj, struct device, kobj); |
466 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 448 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
467 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
468 | struct qlcnic_pm_func_cfg *pm_cfg; | 449 | struct qlcnic_pm_func_cfg *pm_cfg; |
469 | int i, pm_cfg_size; | ||
470 | u8 pci_func; | 450 | u8 pci_func; |
451 | u32 count; | ||
452 | int i; | ||
471 | 453 | ||
472 | pm_cfg_size = pci_func_count * sizeof(*pm_cfg); | 454 | memset(buf, 0, size); |
473 | if (size != pm_cfg_size) | ||
474 | return QL_STATUS_INVALID_PARAM; | ||
475 | |||
476 | memset(buf, 0, pm_cfg_size); | ||
477 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; | 455 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; |
478 | 456 | count = size / sizeof(struct qlcnic_pm_func_cfg); | |
479 | for (i = 0; i < pci_func_count; i++) { | 457 | for (i = 0; i < adapter->ahw->total_nic_func; i++) { |
480 | pci_func = adapter->npars[i].pci_func; | 458 | pci_func = adapter->npars[i].pci_func; |
481 | if (!adapter->npars[i].active) | 459 | if (pci_func >= count) { |
460 | dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n", | ||
461 | __func__, adapter->ahw->total_nic_func, count); | ||
482 | continue; | 462 | continue; |
483 | 463 | } | |
484 | if (!adapter->npars[i].eswitch_status) | 464 | if (!adapter->npars[i].eswitch_status) |
485 | continue; | 465 | continue; |
486 | 466 | ||
@@ -494,7 +474,6 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, | |||
494 | static int validate_esw_config(struct qlcnic_adapter *adapter, | 474 | static int validate_esw_config(struct qlcnic_adapter *adapter, |
495 | struct qlcnic_esw_func_cfg *esw_cfg, int count) | 475 | struct qlcnic_esw_func_cfg *esw_cfg, int count) |
496 | { | 476 | { |
497 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
498 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 477 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
499 | int i, ret; | 478 | int i, ret; |
500 | u32 op_mode; | 479 | u32 op_mode; |
@@ -507,7 +486,7 @@ static int validate_esw_config(struct qlcnic_adapter *adapter, | |||
507 | 486 | ||
508 | for (i = 0; i < count; i++) { | 487 | for (i = 0; i < count; i++) { |
509 | pci_func = esw_cfg[i].pci_func; | 488 | pci_func = esw_cfg[i].pci_func; |
510 | if (pci_func >= pci_func_count) | 489 | if (pci_func >= ahw->max_vnic_func) |
511 | return QL_STATUS_INVALID_PARAM; | 490 | return QL_STATUS_INVALID_PARAM; |
512 | 491 | ||
513 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) | 492 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) |
@@ -642,23 +621,21 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, | |||
642 | { | 621 | { |
643 | struct device *dev = container_of(kobj, struct device, kobj); | 622 | struct device *dev = container_of(kobj, struct device, kobj); |
644 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 623 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
645 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
646 | struct qlcnic_esw_func_cfg *esw_cfg; | 624 | struct qlcnic_esw_func_cfg *esw_cfg; |
647 | size_t esw_cfg_size; | 625 | u8 pci_func; |
648 | u8 i, pci_func; | 626 | u32 count; |
649 | 627 | int i; | |
650 | esw_cfg_size = pci_func_count * sizeof(*esw_cfg); | ||
651 | if (size != esw_cfg_size) | ||
652 | return QL_STATUS_INVALID_PARAM; | ||
653 | 628 | ||
654 | memset(buf, 0, esw_cfg_size); | 629 | memset(buf, 0, size); |
655 | esw_cfg = (struct qlcnic_esw_func_cfg *)buf; | 630 | esw_cfg = (struct qlcnic_esw_func_cfg *)buf; |
656 | 631 | count = size / sizeof(struct qlcnic_esw_func_cfg); | |
657 | for (i = 0; i < pci_func_count; i++) { | 632 | for (i = 0; i < adapter->ahw->total_nic_func; i++) { |
658 | pci_func = adapter->npars[i].pci_func; | 633 | pci_func = adapter->npars[i].pci_func; |
659 | if (!adapter->npars[i].active) | 634 | if (pci_func >= count) { |
635 | dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n", | ||
636 | __func__, adapter->ahw->total_nic_func, count); | ||
660 | continue; | 637 | continue; |
661 | 638 | } | |
662 | if (!adapter->npars[i].eswitch_status) | 639 | if (!adapter->npars[i].eswitch_status) |
663 | continue; | 640 | continue; |
664 | 641 | ||
@@ -741,23 +718,24 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
741 | { | 718 | { |
742 | struct device *dev = container_of(kobj, struct device, kobj); | 719 | struct device *dev = container_of(kobj, struct device, kobj); |
743 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 720 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
744 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
745 | struct qlcnic_npar_func_cfg *np_cfg; | 721 | struct qlcnic_npar_func_cfg *np_cfg; |
746 | struct qlcnic_info nic_info; | 722 | struct qlcnic_info nic_info; |
747 | size_t np_cfg_size; | ||
748 | int i, ret; | 723 | int i, ret; |
749 | 724 | u32 count; | |
750 | np_cfg_size = pci_func_count * sizeof(*np_cfg); | ||
751 | if (size != np_cfg_size) | ||
752 | return QL_STATUS_INVALID_PARAM; | ||
753 | 725 | ||
754 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); | 726 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); |
755 | memset(buf, 0, np_cfg_size); | 727 | memset(buf, 0, size); |
756 | np_cfg = (struct qlcnic_npar_func_cfg *)buf; | 728 | np_cfg = (struct qlcnic_npar_func_cfg *)buf; |
757 | 729 | ||
758 | for (i = 0; i < pci_func_count; i++) { | 730 | count = size / sizeof(struct qlcnic_npar_func_cfg); |
731 | for (i = 0; i < adapter->ahw->total_nic_func; i++) { | ||
759 | if (qlcnic_is_valid_nic_func(adapter, i) < 0) | 732 | if (qlcnic_is_valid_nic_func(adapter, i) < 0) |
760 | continue; | 733 | continue; |
734 | if (adapter->npars[i].pci_func >= count) { | ||
735 | dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n", | ||
736 | __func__, adapter->ahw->total_nic_func, count); | ||
737 | continue; | ||
738 | } | ||
761 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); | 739 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); |
762 | if (ret) | 740 | if (ret) |
763 | return ret; | 741 | return ret; |
@@ -783,7 +761,6 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, | |||
783 | { | 761 | { |
784 | struct device *dev = container_of(kobj, struct device, kobj); | 762 | struct device *dev = container_of(kobj, struct device, kobj); |
785 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 763 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
786 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
787 | struct qlcnic_esw_statistics port_stats; | 764 | struct qlcnic_esw_statistics port_stats; |
788 | int ret; | 765 | int ret; |
789 | 766 | ||
@@ -793,7 +770,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, | |||
793 | if (size != sizeof(struct qlcnic_esw_statistics)) | 770 | if (size != sizeof(struct qlcnic_esw_statistics)) |
794 | return QL_STATUS_INVALID_PARAM; | 771 | return QL_STATUS_INVALID_PARAM; |
795 | 772 | ||
796 | if (offset >= pci_func_count) | 773 | if (offset >= adapter->ahw->max_vnic_func) |
797 | return QL_STATUS_INVALID_PARAM; | 774 | return QL_STATUS_INVALID_PARAM; |
798 | 775 | ||
799 | memset(&port_stats, 0, size); | 776 | memset(&port_stats, 0, size); |
@@ -884,13 +861,12 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file, | |||
884 | 861 | ||
885 | struct device *dev = container_of(kobj, struct device, kobj); | 862 | struct device *dev = container_of(kobj, struct device, kobj); |
886 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 863 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
887 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
888 | int ret; | 864 | int ret; |
889 | 865 | ||
890 | if (qlcnic_83xx_check(adapter)) | 866 | if (qlcnic_83xx_check(adapter)) |
891 | return QLC_STATUS_UNSUPPORTED_CMD; | 867 | return QLC_STATUS_UNSUPPORTED_CMD; |
892 | 868 | ||
893 | if (offset >= pci_func_count) | 869 | if (offset >= adapter->ahw->max_vnic_func) |
894 | return QL_STATUS_INVALID_PARAM; | 870 | return QL_STATUS_INVALID_PARAM; |
895 | 871 | ||
896 | ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, | 872 | ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, |
@@ -914,17 +890,12 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
914 | { | 890 | { |
915 | struct device *dev = container_of(kobj, struct device, kobj); | 891 | struct device *dev = container_of(kobj, struct device, kobj); |
916 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 892 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
917 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
918 | struct qlcnic_pci_func_cfg *pci_cfg; | 893 | struct qlcnic_pci_func_cfg *pci_cfg; |
919 | struct qlcnic_pci_info *pci_info; | 894 | struct qlcnic_pci_info *pci_info; |
920 | size_t pci_cfg_sz; | ||
921 | int i, ret; | 895 | int i, ret; |
896 | u32 count; | ||
922 | 897 | ||
923 | pci_cfg_sz = pci_func_count * sizeof(*pci_cfg); | 898 | pci_info = kcalloc(size, sizeof(*pci_info), GFP_KERNEL); |
924 | if (size != pci_cfg_sz) | ||
925 | return QL_STATUS_INVALID_PARAM; | ||
926 | |||
927 | pci_info = kcalloc(pci_func_count, sizeof(*pci_info), GFP_KERNEL); | ||
928 | if (!pci_info) | 899 | if (!pci_info) |
929 | return -ENOMEM; | 900 | return -ENOMEM; |
930 | 901 | ||
@@ -935,7 +906,8 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
935 | } | 906 | } |
936 | 907 | ||
937 | pci_cfg = (struct qlcnic_pci_func_cfg *)buf; | 908 | pci_cfg = (struct qlcnic_pci_func_cfg *)buf; |
938 | for (i = 0; i < pci_func_count; i++) { | 909 | count = size / sizeof(struct qlcnic_pci_func_cfg); |
910 | for (i = 0; i < count; i++) { | ||
939 | pci_cfg[i].pci_func = pci_info[i].id; | 911 | pci_cfg[i].pci_func = pci_info[i].id; |
940 | pci_cfg[i].func_type = pci_info[i].type; | 912 | pci_cfg[i].func_type = pci_info[i].type; |
941 | pci_cfg[i].func_state = 0; | 913 | pci_cfg[i].func_state = 0; |