Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6.git] / drivers / net / ixgbe / ixgbe_dcb.c
1 /*******************************************************************************
2
3   Intel 10 Gigabit PCI Express Linux driver
4   Copyright(c) 1999 - 2011 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 #include "ixgbe_dcb_82599.h"
35
36 /**
37  * ixgbe_ieee_credits - This calculates the ieee traffic class
38  * credits from the configured bandwidth percentages. Credits
39  * are the smallest unit programmable into the underlying
40  * hardware. The IEEE 802.1Qaz specification do not use bandwidth
41  * groups so this is much simplified from the CEE case.
42  */
43 s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, __u16 *max, int max_frame)
44 {
45         int min_percent = 100;
46         int min_credit, multiplier;
47         int i;
48
49         min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
50                         DCB_CREDIT_QUANTUM;
51
52         for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
53                 if (bw[i] < min_percent && bw[i])
54                         min_percent = bw[i];
55         }
56
57         multiplier = (min_credit / min_percent) + 1;
58
59         /* Find out the hw credits for each TC */
60         for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
61                 int val = min(bw[i] * multiplier, MAX_CREDIT_REFILL);
62
63                 if (val < min_credit)
64                         val = min_credit;
65                 refill[i] = val;
66
67                 max[i] = bw[i] ? (bw[i] * MAX_CREDIT)/100 : min_credit;
68         }
69         return 0;
70 }
71
72 /**
73  * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits
74  * @ixgbe_dcb_config: Struct containing DCB settings.
75  * @direction: Configuring either Tx or Rx.
76  *
77  * This function calculates the credits allocated to each traffic class.
78  * It should be called only after the rules are checked by
79  * ixgbe_dcb_check_config().
80  */
81 s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
82                                    struct ixgbe_dcb_config *dcb_config,
83                                    int max_frame, u8 direction)
84 {
85         struct tc_bw_alloc *p;
86         int min_credit;
87         int min_multiplier;
88         int min_percent = 100;
89         s32 ret_val = 0;
90         /* Initialization values default for Tx settings */
91         u32 credit_refill       = 0;
92         u32 credit_max          = 0;
93         u16 link_percentage     = 0;
94         u8  bw_percent          = 0;
95         u8  i;
96
97         if (dcb_config == NULL) {
98                 ret_val = DCB_ERR_CONFIG;
99                 goto out;
100         }
101
102         min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
103                         DCB_CREDIT_QUANTUM;
104
105         /* Find smallest link percentage */
106         for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
107                 p = &dcb_config->tc_config[i].path[direction];
108                 bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
109                 link_percentage = p->bwg_percent;
110
111                 link_percentage = (link_percentage * bw_percent) / 100;
112
113                 if (link_percentage && link_percentage < min_percent)
114                         min_percent = link_percentage;
115         }
116
117         /*
118          * The ratio between traffic classes will control the bandwidth
119          * percentages seen on the wire. To calculate this ratio we use
120          * a multiplier. It is required that the refill credits must be
121          * larger than the max frame size so here we find the smallest
122          * multiplier that will allow all bandwidth percentages to be
123          * greater than the max frame size.
124          */
125         min_multiplier = (min_credit / min_percent) + 1;
126
127         /* Find out the link percentage for each TC first */
128         for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
129                 p = &dcb_config->tc_config[i].path[direction];
130                 bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
131
132                 link_percentage = p->bwg_percent;
133                 /* Must be careful of integer division for very small nums */
134                 link_percentage = (link_percentage * bw_percent) / 100;
135                 if (p->bwg_percent > 0 && link_percentage == 0)
136                         link_percentage = 1;
137
138                 /* Save link_percentage for reference */
139                 p->link_percent = (u8)link_percentage;
140
141                 /* Calculate credit refill ratio using multiplier */
142                 credit_refill = min(link_percentage * min_multiplier,
143                                     MAX_CREDIT_REFILL);
144                 p->data_credits_refill = (u16)credit_refill;
145
146                 /* Calculate maximum credit for the TC */
147                 credit_max = (link_percentage * MAX_CREDIT) / 100;
148
149                 /*
150                  * Adjustment based on rule checking, if the percentage
151                  * of a TC is too small, the maximum credit may not be
152                  * enough to send out a jumbo frame in data plane arbitration.
153                  */
154                 if (credit_max && (credit_max < min_credit))
155                         credit_max = min_credit;
156
157                 if (direction == DCB_TX_CONFIG) {
158                         /*
159                          * Adjustment based on rule checking, if the
160                          * percentage of a TC is too small, the maximum
161                          * credit may not be enough to send out a TSO
162                          * packet in descriptor plane arbitration.
163                          */
164                         if ((hw->mac.type == ixgbe_mac_82598EB) &&
165                             credit_max &&
166                             (credit_max < MINIMUM_CREDIT_FOR_TSO))
167                                 credit_max = MINIMUM_CREDIT_FOR_TSO;
168
169                         dcb_config->tc_config[i].desc_credits_max =
170                                 (u16)credit_max;
171                 }
172
173                 p->data_credits_max = (u16)credit_max;
174         }
175
176 out:
177         return ret_val;
178 }
179
180 void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en)
181 {
182         int i;
183
184         *pfc_en = 0;
185         for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
186                 *pfc_en |= (cfg->tc_config[i].dcb_pfc & 0xF) << i;
187 }
188
189 void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *cfg, int direction,
190                              u16 *refill)
191 {
192         struct tc_bw_alloc *p;
193         int i;
194
195         for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
196                 p = &cfg->tc_config[i].path[direction];
197                 refill[i] = p->data_credits_refill;
198         }
199 }
200
201 void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *cfg, u16 *max)
202 {
203         int i;
204
205         for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
206                 max[i] = cfg->tc_config[i].desc_credits_max;
207 }
208
209 void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *cfg, int direction,
210                             u8 *bwgid)
211 {
212         struct tc_bw_alloc *p;
213         int i;
214
215         for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
216                 p = &cfg->tc_config[i].path[direction];
217                 bwgid[i] = p->bwg_id;
218         }
219 }
220
221 void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *cfg, int direction,
222                             u8 *ptype)
223 {
224         struct tc_bw_alloc *p;
225         int i;
226
227         for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
228                 p = &cfg->tc_config[i].path[direction];
229                 ptype[i] = p->prio_type;
230         }
231 }
232
233 /**
234  * ixgbe_dcb_hw_config - Config and enable DCB
235  * @hw: pointer to hardware structure
236  * @dcb_config: pointer to ixgbe_dcb_config structure
237  *
238  * Configure dcb settings and enable dcb mode.
239  */
240 s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
241                         struct ixgbe_dcb_config *dcb_config)
242 {
243         s32 ret = 0;
244         u8 pfc_en;
245         u8 ptype[MAX_TRAFFIC_CLASS];
246         u8 bwgid[MAX_TRAFFIC_CLASS];
247         u16 refill[MAX_TRAFFIC_CLASS];
248         u16 max[MAX_TRAFFIC_CLASS];
249         /* CEE does not define a priority to tc mapping so map 1:1 */
250         u8 prio_tc[MAX_TRAFFIC_CLASS] = {0, 1, 2, 3, 4, 5, 6, 7};
251
252         /* Unpack CEE standard containers */
253         ixgbe_dcb_unpack_pfc(dcb_config, &pfc_en);
254         ixgbe_dcb_unpack_refill(dcb_config, DCB_TX_CONFIG, refill);
255         ixgbe_dcb_unpack_max(dcb_config, max);
256         ixgbe_dcb_unpack_bwgid(dcb_config, DCB_TX_CONFIG, bwgid);
257         ixgbe_dcb_unpack_prio(dcb_config, DCB_TX_CONFIG, ptype);
258
259         switch (hw->mac.type) {
260         case ixgbe_mac_82598EB:
261                 ret = ixgbe_dcb_hw_config_82598(hw, pfc_en, refill, max,
262                                                 bwgid, ptype);
263                 break;
264         case ixgbe_mac_82599EB:
265         case ixgbe_mac_X540:
266                 ret = ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max,
267                                                 bwgid, ptype, prio_tc);
268                 break;
269         default:
270                 break;
271         }
272         return ret;
273 }
274
275 /* Helper routines to abstract HW specifics from DCB netlink ops */
276 s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en)
277 {
278         int ret = -EINVAL;
279
280         switch (hw->mac.type) {
281         case ixgbe_mac_82598EB:
282                 ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
283                 break;
284         case ixgbe_mac_82599EB:
285         case ixgbe_mac_X540:
286                 ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en);
287                 break;
288         default:
289                 break;
290         }
291         return ret;
292 }
293
294 s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
295                             u16 *refill, u16 *max, u8 *bwg_id,
296                             u8 *prio_type, u8 *prio_tc)
297 {
298         switch (hw->mac.type) {
299         case ixgbe_mac_82598EB:
300                 ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max,
301                                                         prio_type);
302                 ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
303                                                              bwg_id, prio_type);
304                 ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
305                                                              bwg_id, prio_type);
306                 break;
307         case ixgbe_mac_82599EB:
308         case ixgbe_mac_X540:
309                 ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max,
310                                                   bwg_id, prio_type, prio_tc);
311                 ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
312                                                        bwg_id, prio_type);
313                 ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
314                                                        prio_type, prio_tc);
315                 break;
316         default:
317                 break;
318         }
319         return 0;
320 }