diff options
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 6 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 96 |
2 files changed, 102 insertions, 0 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index db6d3ea1b9f0..94b04657576b 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -161,6 +161,9 @@ enum ixgbe_ring_f_enum { | |||
161 | RING_F_DCB, | 161 | RING_F_DCB, |
162 | RING_F_VMDQ, | 162 | RING_F_VMDQ, |
163 | RING_F_RSS, | 163 | RING_F_RSS, |
164 | #ifdef IXGBE_FCOE | ||
165 | RING_F_FCOE, | ||
166 | #endif /* IXGBE_FCOE */ | ||
164 | 167 | ||
165 | RING_F_ARRAY_SIZE /* must be last in enum set */ | 168 | RING_F_ARRAY_SIZE /* must be last in enum set */ |
166 | }; | 169 | }; |
@@ -168,6 +171,9 @@ enum ixgbe_ring_f_enum { | |||
168 | #define IXGBE_MAX_DCB_INDICES 8 | 171 | #define IXGBE_MAX_DCB_INDICES 8 |
169 | #define IXGBE_MAX_RSS_INDICES 16 | 172 | #define IXGBE_MAX_RSS_INDICES 16 |
170 | #define IXGBE_MAX_VMDQ_INDICES 16 | 173 | #define IXGBE_MAX_VMDQ_INDICES 16 |
174 | #ifdef IXGBE_FCOE | ||
175 | #define IXGBE_MAX_FCOE_INDICES 8 | ||
176 | #endif /* IXGBE_FCOE */ | ||
171 | struct ixgbe_ring_feature { | 177 | struct ixgbe_ring_feature { |
172 | int indices; | 178 | int indices; |
173 | int mask; | 179 | int mask; |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fe0ac8bdb10b..68edeab0fbb8 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -1756,6 +1756,17 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index) | |||
1756 | else | 1756 | else |
1757 | dev_err(&adapter->pdev->dev, "Invalid DCB " | 1757 | dev_err(&adapter->pdev->dev, "Invalid DCB " |
1758 | "configuration\n"); | 1758 | "configuration\n"); |
1759 | #ifdef IXGBE_FCOE | ||
1760 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { | ||
1761 | struct ixgbe_ring_feature *f; | ||
1762 | |||
1763 | rx_ring = &adapter->rx_ring[queue0]; | ||
1764 | f = &adapter->ring_feature[RING_F_FCOE]; | ||
1765 | if ((queue0 == 0) && (index > rx_ring->reg_idx)) | ||
1766 | queue0 = f->mask + index - | ||
1767 | rx_ring->reg_idx - 1; | ||
1768 | } | ||
1769 | #endif /* IXGBE_FCOE */ | ||
1759 | } else { | 1770 | } else { |
1760 | queue0 = index; | 1771 | queue0 = index; |
1761 | } | 1772 | } |
@@ -2842,6 +2853,47 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) | |||
2842 | return ret; | 2853 | return ret; |
2843 | } | 2854 | } |
2844 | 2855 | ||
2856 | #ifdef IXGBE_FCOE | ||
2857 | /** | ||
2858 | * ixgbe_set_fcoe_queues: Allocate queues for Fiber Channel over Ethernet (FCoE) | ||
2859 | * @adapter: board private structure to initialize | ||
2860 | * | ||
2861 | * FCoE RX FCRETA can use up to 8 rx queues for up to 8 different exchanges. | ||
2862 | * The ring feature mask is not used as a mask for FCoE, as it can take any 8 | ||
2863 | * rx queues out of the max number of rx queues, instead, it is used as the | ||
2864 | * index of the first rx queue used by FCoE. | ||
2865 | * | ||
2866 | **/ | ||
2867 | static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) | ||
2868 | { | ||
2869 | bool ret = false; | ||
2870 | struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; | ||
2871 | |||
2872 | f->indices = min((int)num_online_cpus(), f->indices); | ||
2873 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { | ||
2874 | #ifdef CONFIG_IXGBE_DCB | ||
2875 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | ||
2876 | DPRINTK(PROBE, INFO, "FCOE enabled with DCB \n"); | ||
2877 | ixgbe_set_dcb_queues(adapter); | ||
2878 | } | ||
2879 | #endif | ||
2880 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { | ||
2881 | DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n"); | ||
2882 | ixgbe_set_rss_queues(adapter); | ||
2883 | } | ||
2884 | /* adding FCoE rx rings to the end */ | ||
2885 | f->mask = adapter->num_rx_queues; | ||
2886 | adapter->num_rx_queues += f->indices; | ||
2887 | if (adapter->num_tx_queues == 0) | ||
2888 | adapter->num_tx_queues = f->indices; | ||
2889 | |||
2890 | ret = true; | ||
2891 | } | ||
2892 | |||
2893 | return ret; | ||
2894 | } | ||
2895 | |||
2896 | #endif /* IXGBE_FCOE */ | ||
2845 | /* | 2897 | /* |
2846 | * ixgbe_set_num_queues: Allocate queues for device, feature dependant | 2898 | * ixgbe_set_num_queues: Allocate queues for device, feature dependant |
2847 | * @adapter: board private structure to initialize | 2899 | * @adapter: board private structure to initialize |
@@ -2855,6 +2907,11 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) | |||
2855 | **/ | 2907 | **/ |
2856 | static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) | 2908 | static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) |
2857 | { | 2909 | { |
2910 | #ifdef IXGBE_FCOE | ||
2911 | if (ixgbe_set_fcoe_queues(adapter)) | ||
2912 | goto done; | ||
2913 | |||
2914 | #endif /* IXGBE_FCOE */ | ||
2858 | #ifdef CONFIG_IXGBE_DCB | 2915 | #ifdef CONFIG_IXGBE_DCB |
2859 | if (ixgbe_set_dcb_queues(adapter)) | 2916 | if (ixgbe_set_dcb_queues(adapter)) |
2860 | goto done; | 2917 | goto done; |
@@ -3030,6 +3087,39 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) | |||
3030 | } | 3087 | } |
3031 | #endif | 3088 | #endif |
3032 | 3089 | ||
3090 | #ifdef IXGBE_FCOE | ||
3091 | /** | ||
3092 | * ixgbe_cache_ring_fcoe - Descriptor ring to register mapping for the FCoE | ||
3093 | * @adapter: board private structure to initialize | ||
3094 | * | ||
3095 | * Cache the descriptor ring offsets for FCoE mode to the assigned rings. | ||
3096 | * | ||
3097 | */ | ||
3098 | static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) | ||
3099 | { | ||
3100 | int i, fcoe_i = 0; | ||
3101 | bool ret = false; | ||
3102 | struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; | ||
3103 | |||
3104 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { | ||
3105 | #ifdef CONFIG_IXGBE_DCB | ||
3106 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | ||
3107 | ixgbe_cache_ring_dcb(adapter); | ||
3108 | fcoe_i = adapter->rx_ring[0].reg_idx + 1; | ||
3109 | } | ||
3110 | #endif /* CONFIG_IXGBE_DCB */ | ||
3111 | if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { | ||
3112 | ixgbe_cache_ring_rss(adapter); | ||
3113 | fcoe_i = f->mask; | ||
3114 | } | ||
3115 | for (i = 0; i < f->indices; i++, fcoe_i++) | ||
3116 | adapter->rx_ring[f->mask + i].reg_idx = fcoe_i; | ||
3117 | ret = true; | ||
3118 | } | ||
3119 | return ret; | ||
3120 | } | ||
3121 | |||
3122 | #endif /* IXGBE_FCOE */ | ||
3033 | /** | 3123 | /** |
3034 | * ixgbe_cache_ring_register - Descriptor ring to register mapping | 3124 | * ixgbe_cache_ring_register - Descriptor ring to register mapping |
3035 | * @adapter: board private structure to initialize | 3125 | * @adapter: board private structure to initialize |
@@ -3047,6 +3137,11 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) | |||
3047 | adapter->rx_ring[0].reg_idx = 0; | 3137 | adapter->rx_ring[0].reg_idx = 0; |
3048 | adapter->tx_ring[0].reg_idx = 0; | 3138 | adapter->tx_ring[0].reg_idx = 0; |
3049 | 3139 | ||
3140 | #ifdef IXGBE_FCOE | ||
3141 | if (ixgbe_cache_ring_fcoe(adapter)) | ||
3142 | return; | ||
3143 | |||
3144 | #endif /* IXGBE_FCOE */ | ||
3050 | #ifdef CONFIG_IXGBE_DCB | 3145 | #ifdef CONFIG_IXGBE_DCB |
3051 | if (ixgbe_cache_ring_dcb(adapter)) | 3146 | if (ixgbe_cache_ring_dcb(adapter)) |
3052 | return; | 3147 | return; |
@@ -3420,6 +3515,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) | |||
3420 | adapter->flags |= IXGBE_FLAG_RSC_ENABLED; | 3515 | adapter->flags |= IXGBE_FLAG_RSC_ENABLED; |
3421 | #ifdef IXGBE_FCOE | 3516 | #ifdef IXGBE_FCOE |
3422 | adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; | 3517 | adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; |
3518 | adapter->ring_feature[RING_F_FCOE].indices = IXGBE_FCRETA_SIZE; | ||
3423 | #endif /* IXGBE_FCOE */ | 3519 | #endif /* IXGBE_FCOE */ |
3424 | } | 3520 | } |
3425 | 3521 | ||