aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c33
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h20
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c164
3 files changed, 153 insertions, 64 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 8a250c38fb82..8b04880ee05d 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -3138,6 +3138,39 @@ err:
3138 return status; 3138 return status;
3139} 3139}
3140 3140
3141int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
3142 int vf_num)
3143{
3144 struct be_mcc_wrb *wrb;
3145 struct be_cmd_req_get_iface_list *req;
3146 struct be_cmd_resp_get_iface_list *resp;
3147 int status;
3148
3149 spin_lock_bh(&adapter->mcc_lock);
3150
3151 wrb = wrb_from_mccq(adapter);
3152 if (!wrb) {
3153 status = -EBUSY;
3154 goto err;
3155 }
3156 req = embedded_payload(wrb);
3157
3158 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3159 OPCODE_COMMON_GET_IFACE_LIST, sizeof(*resp),
3160 wrb, NULL);
3161 req->hdr.domain = vf_num + 1;
3162
3163 status = be_mcc_notify_wait(adapter);
3164 if (!status) {
3165 resp = (struct be_cmd_resp_get_iface_list *)req;
3166 vf_cfg->if_handle = le32_to_cpu(resp->if_desc.if_id);
3167 }
3168
3169err:
3170 spin_unlock_bh(&adapter->mcc_lock);
3171 return status;
3172}
3173
3141/* Uses sync mcc */ 3174/* Uses sync mcc */
3142int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain) 3175int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
3143{ 3176{
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index d6552e19ffee..96970860c915 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -203,6 +203,7 @@ struct be_mcc_mailbox {
203#define OPCODE_COMMON_GET_FN_PRIVILEGES 170 203#define OPCODE_COMMON_GET_FN_PRIVILEGES 170
204#define OPCODE_COMMON_READ_OBJECT 171 204#define OPCODE_COMMON_READ_OBJECT 171
205#define OPCODE_COMMON_WRITE_OBJECT 172 205#define OPCODE_COMMON_WRITE_OBJECT 172
206#define OPCODE_COMMON_GET_IFACE_LIST 194
206#define OPCODE_COMMON_ENABLE_DISABLE_VF 196 207#define OPCODE_COMMON_ENABLE_DISABLE_VF 196
207 208
208#define OPCODE_ETH_RSS_CONFIG 1 209#define OPCODE_ETH_RSS_CONFIG 1
@@ -1795,6 +1796,23 @@ static inline bool check_privilege(struct be_adapter *adapter, u32 flags)
1795 return flags & adapter->cmd_privileges ? true : false; 1796 return flags & adapter->cmd_privileges ? true : false;
1796} 1797}
1797 1798
1799/************** Get IFACE LIST *******************/
1800struct be_if_desc {
1801 u32 if_id;
1802 u32 cap_flags;
1803 u32 en_flags;
1804};
1805
1806struct be_cmd_req_get_iface_list {
1807 struct be_cmd_req_hdr hdr;
1808};
1809
1810struct be_cmd_resp_get_iface_list {
1811 struct be_cmd_req_hdr hdr;
1812 u32 if_cnt;
1813 struct be_if_desc if_desc;
1814};
1815
1798extern int be_pci_fnum_get(struct be_adapter *adapter); 1816extern int be_pci_fnum_get(struct be_adapter *adapter);
1799extern int be_fw_wait_ready(struct be_adapter *adapter); 1817extern int be_fw_wait_ready(struct be_adapter *adapter);
1800extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, 1818extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
@@ -1917,4 +1935,6 @@ extern int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags,
1917 1935
1918extern int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, 1936extern int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps,
1919 u8 domain); 1937 u8 domain);
1938extern int be_cmd_get_if_id(struct be_adapter *adapter,
1939 struct be_vf_cfg *vf_cfg, int vf_num);
1920extern int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain); 1940extern int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 5c995700e534..7d534818d2fb 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2597,7 +2597,7 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable)
2597 * These addresses are programmed in the ASIC by the PF and the VF driver 2597 * These addresses are programmed in the ASIC by the PF and the VF driver
2598 * queries for the MAC address during its probe. 2598 * queries for the MAC address during its probe.
2599 */ 2599 */
2600static inline int be_vf_eth_addr_config(struct be_adapter *adapter) 2600static int be_vf_eth_addr_config(struct be_adapter *adapter)
2601{ 2601{
2602 u32 vf; 2602 u32 vf;
2603 int status = 0; 2603 int status = 0;
@@ -2626,13 +2626,34 @@ static inline int be_vf_eth_addr_config(struct be_adapter *adapter)
2626 return status; 2626 return status;
2627} 2627}
2628 2628
2629static int be_vfs_mac_query(struct be_adapter *adapter)
2630{
2631 int status, vf;
2632 u8 mac[ETH_ALEN];
2633 struct be_vf_cfg *vf_cfg;
2634 bool active;
2635
2636 for_all_vfs(adapter, vf_cfg, vf) {
2637 be_cmd_get_mac_from_list(adapter, mac, &active,
2638 &vf_cfg->pmac_id, 0);
2639
2640 status = be_cmd_mac_addr_query(adapter, mac, false,
2641 vf_cfg->if_handle, 0);
2642 if (status)
2643 return status;
2644 memcpy(vf_cfg->mac_addr, mac, ETH_ALEN);
2645 }
2646 return 0;
2647}
2648
2629static void be_vf_clear(struct be_adapter *adapter) 2649static void be_vf_clear(struct be_adapter *adapter)
2630{ 2650{
2631 struct be_vf_cfg *vf_cfg; 2651 struct be_vf_cfg *vf_cfg;
2632 u32 vf; 2652 u32 vf;
2633 2653
2634 if (be_find_vfs(adapter, ASSIGNED)) { 2654 if (be_find_vfs(adapter, ASSIGNED)) {
2635 dev_warn(&adapter->pdev->dev, "VFs are assigned to VMs\n"); 2655 dev_warn(&adapter->pdev->dev,
2656 "VFs are assigned to VMs: not disabling VFs\n");
2636 goto done; 2657 goto done;
2637 } 2658 }
2638 2659
@@ -2681,21 +2702,29 @@ static int be_clear(struct be_adapter *adapter)
2681 return 0; 2702 return 0;
2682} 2703}
2683 2704
2684static void be_get_vf_if_cap_flags(struct be_adapter *adapter, 2705static int be_vfs_if_create(struct be_adapter *adapter)
2685 u32 *cap_flags, u8 domain)
2686{ 2706{
2687 bool profile_present = false; 2707 struct be_vf_cfg *vf_cfg;
2708 u32 cap_flags, en_flags, vf;
2688 int status; 2709 int status;
2689 2710
2690 if (lancer_chip(adapter)) { 2711 cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
2691 status = be_cmd_get_profile_config(adapter, cap_flags, domain); 2712 BE_IF_FLAGS_MULTICAST;
2692 if (!status)
2693 profile_present = true;
2694 }
2695 2713
2696 if (!profile_present) 2714 for_all_vfs(adapter, vf_cfg, vf) {
2697 *cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | 2715 if (!BE3_chip(adapter))
2698 BE_IF_FLAGS_MULTICAST; 2716 be_cmd_get_profile_config(adapter, &cap_flags, vf + 1);
2717
2718 /* If a FW profile exists, then cap_flags are updated */
2719 en_flags = cap_flags & (BE_IF_FLAGS_UNTAGGED |
2720 BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST);
2721 status = be_cmd_if_create(adapter, cap_flags, en_flags,
2722 &vf_cfg->if_handle, vf + 1);
2723 if (status)
2724 goto err;
2725 }
2726err:
2727 return status;
2699} 2728}
2700 2729
2701static int be_vf_setup_init(struct be_adapter *adapter) 2730static int be_vf_setup_init(struct be_adapter *adapter)
@@ -2718,65 +2747,70 @@ static int be_vf_setup_init(struct be_adapter *adapter)
2718static int be_vf_setup(struct be_adapter *adapter) 2747static int be_vf_setup(struct be_adapter *adapter)
2719{ 2748{
2720 struct be_vf_cfg *vf_cfg; 2749 struct be_vf_cfg *vf_cfg;
2721 struct device *dev = &adapter->pdev->dev;
2722 u32 cap_flags, en_flags, vf;
2723 u16 def_vlan, lnk_speed; 2750 u16 def_vlan, lnk_speed;
2724 int status, enabled_vfs; 2751 int status, old_vfs, vf;
2725 2752 struct device *dev = &adapter->pdev->dev;
2726 enabled_vfs = be_find_vfs(adapter, ENABLED);
2727 if (enabled_vfs) {
2728 dev_warn(dev, "%d VFs are already enabled\n", enabled_vfs);
2729 dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
2730 return 0;
2731 }
2732
2733 if (num_vfs > adapter->dev_num_vfs) {
2734 dev_warn(dev, "Device supports %d VFs and not %d\n",
2735 adapter->dev_num_vfs, num_vfs);
2736 num_vfs = adapter->dev_num_vfs;
2737 }
2738 2753
2739 status = pci_enable_sriov(adapter->pdev, num_vfs); 2754 old_vfs = be_find_vfs(adapter, ENABLED);
2740 if (!status) { 2755 if (old_vfs) {
2741 adapter->num_vfs = num_vfs; 2756 dev_info(dev, "%d VFs are already enabled\n", old_vfs);
2757 if (old_vfs != num_vfs)
2758 dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
2759 adapter->num_vfs = old_vfs;
2742 } else { 2760 } else {
2743 /* Platform doesn't support SRIOV though device supports it */ 2761 if (num_vfs > adapter->dev_num_vfs)
2744 dev_warn(dev, "SRIOV enable failed\n"); 2762 dev_info(dev, "Device supports %d VFs and not %d\n",
2745 return 0; 2763 adapter->dev_num_vfs, num_vfs);
2764 adapter->num_vfs = min_t(u16, num_vfs, adapter->dev_num_vfs);
2765
2766 status = pci_enable_sriov(adapter->pdev, num_vfs);
2767 if (status) {
2768 dev_err(dev, "SRIOV enable failed\n");
2769 adapter->num_vfs = 0;
2770 return 0;
2771 }
2746 } 2772 }
2747 2773
2748 status = be_vf_setup_init(adapter); 2774 status = be_vf_setup_init(adapter);
2749 if (status) 2775 if (status)
2750 goto err; 2776 goto err;
2751 2777
2752 for_all_vfs(adapter, vf_cfg, vf) { 2778 if (old_vfs) {
2753 be_get_vf_if_cap_flags(adapter, &cap_flags, vf + 1); 2779 for_all_vfs(adapter, vf_cfg, vf) {
2754 2780 status = be_cmd_get_if_id(adapter, vf_cfg, vf);
2755 en_flags = cap_flags & (BE_IF_FLAGS_UNTAGGED | 2781 if (status)
2756 BE_IF_FLAGS_BROADCAST | 2782 goto err;
2757 BE_IF_FLAGS_MULTICAST); 2783 }
2758 2784 } else {
2759 status = be_cmd_if_create(adapter, cap_flags, en_flags, 2785 status = be_vfs_if_create(adapter);
2760 &vf_cfg->if_handle, vf + 1);
2761 if (status) 2786 if (status)
2762 goto err; 2787 goto err;
2763 } 2788 }
2764 2789
2765 if (!enabled_vfs) { 2790 if (old_vfs) {
2791 status = be_vfs_mac_query(adapter);
2792 if (status)
2793 goto err;
2794 } else {
2766 status = be_vf_eth_addr_config(adapter); 2795 status = be_vf_eth_addr_config(adapter);
2767 if (status) 2796 if (status)
2768 goto err; 2797 goto err;
2769 } 2798 }
2770 2799
2771 for_all_vfs(adapter, vf_cfg, vf) { 2800 for_all_vfs(adapter, vf_cfg, vf) {
2772 lnk_speed = 1000; 2801 /* BE3 FW, by default, caps VF TX-rate to 100mbps.
2773 status = be_cmd_set_qos(adapter, lnk_speed, vf + 1); 2802 * Allow full available bandwidth
2774 if (status) 2803 */
2775 goto err; 2804 if (BE3_chip(adapter) && !old_vfs)
2776 vf_cfg->tx_rate = lnk_speed * 10; 2805 be_cmd_set_qos(adapter, 1000, vf+1);
2806
2807 status = be_cmd_link_status_query(adapter, &lnk_speed,
2808 NULL, vf + 1);
2809 if (!status)
2810 vf_cfg->tx_rate = lnk_speed;
2777 2811
2778 status = be_cmd_get_hsw_config(adapter, &def_vlan, 2812 status = be_cmd_get_hsw_config(adapter, &def_vlan,
2779 vf + 1, vf_cfg->if_handle); 2813 vf + 1, vf_cfg->if_handle);
2780 if (status) 2814 if (status)
2781 goto err; 2815 goto err;
2782 vf_cfg->def_vid = def_vlan; 2816 vf_cfg->def_vid = def_vlan;
@@ -2785,6 +2819,8 @@ static int be_vf_setup(struct be_adapter *adapter)
2785 } 2819 }
2786 return 0; 2820 return 0;
2787err: 2821err:
2822 dev_err(dev, "VF setup failed\n");
2823 be_vf_clear(adapter);
2788 return status; 2824 return status;
2789} 2825}
2790 2826
@@ -2838,12 +2874,12 @@ static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle,
2838 2874
2839static void be_get_resources(struct be_adapter *adapter) 2875static void be_get_resources(struct be_adapter *adapter)
2840{ 2876{
2841 int status; 2877 u16 dev_num_vfs;
2878 int pos, status;
2842 bool profile_present = false; 2879 bool profile_present = false;
2843 2880
2844 if (lancer_chip(adapter)) { 2881 if (!BEx_chip(adapter)) {
2845 status = be_cmd_get_func_config(adapter); 2882 status = be_cmd_get_func_config(adapter);
2846
2847 if (!status) 2883 if (!status)
2848 profile_present = true; 2884 profile_present = true;
2849 } 2885 }
@@ -2899,13 +2935,21 @@ static void be_get_resources(struct be_adapter *adapter)
2899 if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) 2935 if (adapter->function_caps & BE_FUNCTION_CAPS_RSS)
2900 adapter->if_cap_flags |= BE_IF_FLAGS_RSS; 2936 adapter->if_cap_flags |= BE_IF_FLAGS_RSS;
2901 } 2937 }
2938
2939 pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV);
2940 if (pos) {
2941 pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF,
2942 &dev_num_vfs);
2943 if (BE3_chip(adapter))
2944 dev_num_vfs = min_t(u16, dev_num_vfs, MAX_VFS);
2945 adapter->dev_num_vfs = dev_num_vfs;
2946 }
2902} 2947}
2903 2948
2904/* Routine to query per function resource limits */ 2949/* Routine to query per function resource limits */
2905static int be_get_config(struct be_adapter *adapter) 2950static int be_get_config(struct be_adapter *adapter)
2906{ 2951{
2907 int pos, status; 2952 int status;
2908 u16 dev_num_vfs;
2909 2953
2910 status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, 2954 status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
2911 &adapter->function_mode, 2955 &adapter->function_mode,
@@ -2923,14 +2967,6 @@ static int be_get_config(struct be_adapter *adapter)
2923 goto err; 2967 goto err;
2924 } 2968 }
2925 2969
2926 pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV);
2927 if (pos) {
2928 pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF,
2929 &dev_num_vfs);
2930 if (!lancer_chip(adapter))
2931 dev_num_vfs = min_t(u16, dev_num_vfs, MAX_VFS);
2932 adapter->dev_num_vfs = dev_num_vfs;
2933 }
2934err: 2970err:
2935 return status; 2971 return status;
2936} 2972}