Merge branch 'linux-next' of git://git.infradead.org/~dedekind/ubi-2.6
[linux-2.6] / drivers / net / ixgbe / ixgbe_dcb.c
1 /*******************************************************************************
2
3   Intel 10 Gigabit PCI Express Linux driver
4   Copyright(c) 1999 - 2007 Intel Corporation.
5
6   This program is free software; you can redistribute it and/or modify it
7   under the terms and conditions of the GNU General Public License,
8   version 2, as published by the Free Software Foundation.
9
10   This program is distributed in the hope it will be useful, but WITHOUT
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13   more details.
14
15   You should have received a copy of the GNU General Public License along with
16   this program; if not, write to the Free Software Foundation, Inc.,
17   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19   The full GNU General Public License is included in this distribution in
20   the file called "COPYING".
21
22   Contact Information:
23   Linux NICS <linux.nics@intel.com>
24   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
25   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26
27 *******************************************************************************/
28
29
30 #include "ixgbe.h"
31 #include "ixgbe_type.h"
32 #include "ixgbe_dcb.h"
33 #include "ixgbe_dcb_82598.h"
34
35 /**
36  * ixgbe_dcb_config - Struct containing DCB settings.
37  * @dcb_config: Pointer to DCB config structure
38  *
39  * This function checks DCB rules for DCB settings.
40  * The following rules are checked:
41  * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%.
42  * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth
43  *    Group must total 100.
44  * 3. A Traffic Class should not be set to both Link Strict Priority
45  *    and Group Strict Priority.
46  * 4. Link strict Bandwidth Groups can only have link strict traffic classes
47  *    with zero bandwidth.
48  */
49 s32 ixgbe_dcb_check_config(struct ixgbe_dcb_config *dcb_config)
50 {
51         struct tc_bw_alloc *p;
52         s32 ret_val = 0;
53         u8 i, j, bw = 0, bw_id;
54         u8 bw_sum[2][MAX_BW_GROUP];
55         bool link_strict[2][MAX_BW_GROUP];
56
57         memset(bw_sum, 0, sizeof(bw_sum));
58         memset(link_strict, 0, sizeof(link_strict));
59
60         /* First Tx, then Rx */
61         for (i = 0; i < 2; i++) {
62                 /* Check each traffic class for rule violation */
63                 for (j = 0; j < MAX_TRAFFIC_CLASS; j++) {
64                         p = &dcb_config->tc_config[j].path[i];
65
66                         bw = p->bwg_percent;
67                         bw_id = p->bwg_id;
68
69                         if (bw_id >= MAX_BW_GROUP) {
70                                 ret_val = DCB_ERR_CONFIG;
71                                 goto err_config;
72                         }
73                         if (p->prio_type == prio_link) {
74                                 link_strict[i][bw_id] = true;
75                                 /* Link strict should have zero bandwidth */
76                                 if (bw) {
77                                         ret_val = DCB_ERR_LS_BW_NONZERO;
78                                         goto err_config;
79                                 }
80                         } else if (!bw) {
81                                 /*
82                                  * Traffic classes without link strict
83                                  * should have non-zero bandwidth.
84                                  */
85                                 ret_val = DCB_ERR_TC_BW_ZERO;
86                                 goto err_config;
87                         }
88                         bw_sum[i][bw_id] += bw;
89                 }
90
91                 bw = 0;
92
93                 /* Check each bandwidth group for rule violation */
94                 for (j = 0; j < MAX_BW_GROUP; j++) {
95                         bw += dcb_config->bw_percentage[i][j];
96                         /*
97                          * Sum of bandwidth percentages of all traffic classes
98                          * within a Bandwidth Group must total 100 except for
99                          * link strict group (zero bandwidth).
100                          */
101                         if (link_strict[i][j]) {
102                                 if (bw_sum[i][j]) {
103                                         /*
104                                          * Link strict group should have zero
105                                          * bandwidth.
106                                          */
107                                         ret_val = DCB_ERR_LS_BWG_NONZERO;
108                                         goto err_config;
109                                 }
110                         } else if (bw_sum[i][j] != BW_PERCENT &&
111                                    bw_sum[i][j] != 0) {
112                                 ret_val = DCB_ERR_TC_BW;
113                                 goto err_config;
114                         }
115                 }
116
117                 if (bw != BW_PERCENT) {
118                         ret_val = DCB_ERR_BW_GROUP;
119                         goto err_config;
120                 }
121         }
122
123 err_config:
124         return ret_val;
125 }
126
127 /**
128  * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits
129  * @ixgbe_dcb_config: Struct containing DCB settings.
130  * @direction: Configuring either Tx or Rx.
131  *
132  * This function calculates the credits allocated to each traffic class.
133  * It should be called only after the rules are checked by
134  * ixgbe_dcb_check_config().
135  */
136 s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config,
137                                    u8 direction)
138 {
139         struct tc_bw_alloc *p;
140         s32 ret_val = 0;
141         /* Initialization values default for Tx settings */
142         u32 credit_refill       = 0;
143         u32 credit_max          = 0;
144         u16 link_percentage     = 0;
145         u8  bw_percent          = 0;
146         u8  i;
147
148         if (dcb_config == NULL) {
149                 ret_val = DCB_ERR_CONFIG;
150                 goto out;
151         }
152
153         /* Find out the link percentage for each TC first */
154         for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
155                 p = &dcb_config->tc_config[i].path[direction];
156                 bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
157
158                 link_percentage = p->bwg_percent;
159                 /* Must be careful of integer division for very small nums */
160                 link_percentage = (link_percentage * bw_percent) / 100;
161                 if (p->bwg_percent > 0 && link_percentage == 0)
162                         link_percentage = 1;
163
164                 /* Save link_percentage for reference */
165                 p->link_percent = (u8)link_percentage;
166
167                 /* Calculate credit refill and save it */
168                 credit_refill = link_percentage * MINIMUM_CREDIT_REFILL;
169                 p->data_credits_refill = (u16)credit_refill;
170
171                 /* Calculate maximum credit for the TC */
172                 credit_max = (link_percentage * MAX_CREDIT) / 100;
173
174                 /*
175                  * Adjustment based on rule checking, if the percentage
176                  * of a TC is too small, the maximum credit may not be
177                  * enough to send out a jumbo frame in data plane arbitration.
178                  */
179                 if (credit_max && (credit_max < MINIMUM_CREDIT_FOR_JUMBO))
180                         credit_max = MINIMUM_CREDIT_FOR_JUMBO;
181
182                 if (direction == DCB_TX_CONFIG) {
183                         /*
184                          * Adjustment based on rule checking, if the
185                          * percentage of a TC is too small, the maximum
186                          * credit may not be enough to send out a TSO
187                          * packet in descriptor plane arbitration.
188                          */
189                         if (credit_max &&
190                             (credit_max < MINIMUM_CREDIT_FOR_TSO))
191                                 credit_max = MINIMUM_CREDIT_FOR_TSO;
192
193                         dcb_config->tc_config[i].desc_credits_max =
194                                 (u16)credit_max;
195                 }
196
197                 p->data_credits_max = (u16)credit_max;
198         }
199
200 out:
201         return ret_val;
202 }
203
204 /**
205  * ixgbe_dcb_get_tc_stats - Returns status of each traffic class
206  * @hw: pointer to hardware structure
207  * @stats: pointer to statistics structure
208  * @tc_count:  Number of elements in bwg_array.
209  *
210  * This function returns the status data for each of the Traffic Classes in use.
211  */
212 s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
213                            u8 tc_count)
214 {
215         s32 ret = 0;
216         if (hw->mac.type == ixgbe_mac_82598EB)
217                 ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count);
218         return ret;
219 }
220
221 /**
222  * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class
223  * hw - pointer to hardware structure
224  * stats - pointer to statistics structure
225  * tc_count -  Number of elements in bwg_array.
226  *
227  * This function returns the CBFC status data for each of the Traffic Classes.
228  */
229 s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
230                             u8 tc_count)
231 {
232         s32 ret = 0;
233         if (hw->mac.type == ixgbe_mac_82598EB)
234                 ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count);
235         return ret;
236 }
237
238 /**
239  * ixgbe_dcb_config_rx_arbiter - Config Rx arbiter
240  * @hw: pointer to hardware structure
241  * @dcb_config: pointer to ixgbe_dcb_config structure
242  *
243  * Configure Rx Data Arbiter and credits for each traffic class.
244  */
245 s32 ixgbe_dcb_config_rx_arbiter(struct ixgbe_hw *hw,
246                                 struct ixgbe_dcb_config *dcb_config)
247 {
248         s32 ret = 0;
249         if (hw->mac.type == ixgbe_mac_82598EB)
250                 ret = ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config);
251         return ret;
252 }
253
254 /**
255  * ixgbe_dcb_config_tx_desc_arbiter - Config Tx Desc arbiter
256  * @hw: pointer to hardware structure
257  * @dcb_config: pointer to ixgbe_dcb_config structure
258  *
259  * Configure Tx Descriptor Arbiter and credits for each traffic class.
260  */
261 s32 ixgbe_dcb_config_tx_desc_arbiter(struct ixgbe_hw *hw,
262                                      struct ixgbe_dcb_config *dcb_config)
263 {
264         s32 ret = 0;
265         if (hw->mac.type == ixgbe_mac_82598EB)
266                 ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config);
267         return ret;
268 }
269
270 /**
271  * ixgbe_dcb_config_tx_data_arbiter - Config Tx data arbiter
272  * @hw: pointer to hardware structure
273  * @dcb_config: pointer to ixgbe_dcb_config structure
274  *
275  * Configure Tx Data Arbiter and credits for each traffic class.
276  */
277 s32 ixgbe_dcb_config_tx_data_arbiter(struct ixgbe_hw *hw,
278                                      struct ixgbe_dcb_config *dcb_config)
279 {
280         s32 ret = 0;
281         if (hw->mac.type == ixgbe_mac_82598EB)
282                 ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config);
283         return ret;
284 }
285
286 /**
287  * ixgbe_dcb_config_pfc - Config priority flow control
288  * @hw: pointer to hardware structure
289  * @dcb_config: pointer to ixgbe_dcb_config structure
290  *
291  * Configure Priority Flow Control for each traffic class.
292  */
293 s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw,
294                          struct ixgbe_dcb_config *dcb_config)
295 {
296         s32 ret = 0;
297         if (hw->mac.type == ixgbe_mac_82598EB)
298                 ret = ixgbe_dcb_config_pfc_82598(hw, dcb_config);
299         return ret;
300 }
301
302 /**
303  * ixgbe_dcb_config_tc_stats - Config traffic class statistics
304  * @hw: pointer to hardware structure
305  *
306  * Configure queue statistics registers, all queues belonging to same traffic
307  * class uses a single set of queue statistics counters.
308  */
309 s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
310 {
311         s32 ret = 0;
312         if (hw->mac.type == ixgbe_mac_82598EB)
313                 ret = ixgbe_dcb_config_tc_stats_82598(hw);
314         return ret;
315 }
316
317 /**
318  * ixgbe_dcb_hw_config - Config and enable DCB
319  * @hw: pointer to hardware structure
320  * @dcb_config: pointer to ixgbe_dcb_config structure
321  *
322  * Configure dcb settings and enable dcb mode.
323  */
324 s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
325                         struct ixgbe_dcb_config *dcb_config)
326 {
327         s32 ret = 0;
328         if (hw->mac.type == ixgbe_mac_82598EB)
329                 ret = ixgbe_dcb_hw_config_82598(hw, dcb_config);
330         return ret;
331 }
332