1 /*******************************************************************************
3 Intel 10 Gigabit PCI Express Linux driver
4 Copyright(c) 1999 - 2016 Intel Corporation.
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.
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
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.
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
25 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *******************************************************************************/
31 #include "ixgbe_type.h"
32 #include "ixgbe_dcb.h"
33 #include "ixgbe_dcb_82598.h"
34 #include "ixgbe_dcb_82599.h"
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.
43 static s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill,
44 __u16 *max, int max_frame)
46 int min_percent = 100;
47 int min_credit, multiplier;
50 min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
53 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
54 if (bw[i] < min_percent && bw[i])
58 multiplier = (min_credit / min_percent) + 1;
60 /* Find out the hw credits for each TC */
61 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
62 int val = min(bw[i] * multiplier, MAX_CREDIT_REFILL);
68 max[i] = bw[i] ? (bw[i] * MAX_CREDIT)/100 : min_credit;
74 * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits
75 * @ixgbe_dcb_config: Struct containing DCB settings.
76 * @direction: Configuring either Tx or Rx.
78 * This function calculates the credits allocated to each traffic class.
79 * It should be called only after the rules are checked by
80 * ixgbe_dcb_check_config().
82 s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
83 struct ixgbe_dcb_config *dcb_config,
84 int max_frame, u8 direction)
86 struct tc_bw_alloc *p;
89 int min_percent = 100;
90 /* Initialization values default for Tx settings */
91 u32 credit_refill = 0;
93 u16 link_percentage = 0;
98 return DCB_ERR_CONFIG;
100 min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
103 /* Find smallest link percentage */
104 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
105 p = &dcb_config->tc_config[i].path[direction];
106 bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
107 link_percentage = p->bwg_percent;
109 link_percentage = (link_percentage * bw_percent) / 100;
111 if (link_percentage && link_percentage < min_percent)
112 min_percent = link_percentage;
116 * The ratio between traffic classes will control the bandwidth
117 * percentages seen on the wire. To calculate this ratio we use
118 * a multiplier. It is required that the refill credits must be
119 * larger than the max frame size so here we find the smallest
120 * multiplier that will allow all bandwidth percentages to be
121 * greater than the max frame size.
123 min_multiplier = (min_credit / min_percent) + 1;
125 /* Find out the link percentage for each TC first */
126 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
127 p = &dcb_config->tc_config[i].path[direction];
128 bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
130 link_percentage = p->bwg_percent;
131 /* Must be careful of integer division for very small nums */
132 link_percentage = (link_percentage * bw_percent) / 100;
133 if (p->bwg_percent > 0 && link_percentage == 0)
136 /* Save link_percentage for reference */
137 p->link_percent = (u8)link_percentage;
139 /* Calculate credit refill ratio using multiplier */
140 credit_refill = min(link_percentage * min_multiplier,
143 /* Refill at least minimum credit */
144 if (credit_refill < min_credit)
145 credit_refill = min_credit;
147 p->data_credits_refill = (u16)credit_refill;
149 /* Calculate maximum credit for the TC */
150 credit_max = (link_percentage * MAX_CREDIT) / 100;
153 * Adjustment based on rule checking, if the percentage
154 * of a TC is too small, the maximum credit may not be
155 * enough to send out a jumbo frame in data plane arbitration.
157 if (credit_max < min_credit)
158 credit_max = min_credit;
160 if (direction == DCB_TX_CONFIG) {
162 * Adjustment based on rule checking, if the
163 * percentage of a TC is too small, the maximum
164 * credit may not be enough to send out a TSO
165 * packet in descriptor plane arbitration.
167 if ((hw->mac.type == ixgbe_mac_82598EB) &&
169 (credit_max < MINIMUM_CREDIT_FOR_TSO))
170 credit_max = MINIMUM_CREDIT_FOR_TSO;
172 dcb_config->tc_config[i].desc_credits_max =
176 p->data_credits_max = (u16)credit_max;
182 void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en)
184 struct tc_configuration *tc_config = &cfg->tc_config[0];
187 for (*pfc_en = 0, tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) {
188 if (tc_config[tc].dcb_pfc != pfc_disabled)
193 void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *cfg, int direction,
196 struct tc_configuration *tc_config = &cfg->tc_config[0];
199 for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
200 refill[tc] = tc_config[tc].path[direction].data_credits_refill;
203 void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *cfg, u16 *max)
205 struct tc_configuration *tc_config = &cfg->tc_config[0];
208 for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
209 max[tc] = tc_config[tc].desc_credits_max;
212 void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *cfg, int direction,
215 struct tc_configuration *tc_config = &cfg->tc_config[0];
218 for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
219 bwgid[tc] = tc_config[tc].path[direction].bwg_id;
222 void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *cfg, int direction,
225 struct tc_configuration *tc_config = &cfg->tc_config[0];
228 for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
229 ptype[tc] = tc_config[tc].path[direction].prio_type;
232 u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up)
234 struct tc_configuration *tc_config = &cfg->tc_config[0];
235 u8 prio_mask = BIT(up);
236 u8 tc = cfg->num_tcs.pg_tcs;
238 /* If tc is 0 then DCB is likely not enabled or supported */
243 * Test from maximum TC to 1 and report the first match we find. If
244 * we find no match we can assume that the TC is 0 since the TC must
245 * be set for all user priorities
247 for (tc--; tc; tc--) {
248 if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap)
255 void ixgbe_dcb_unpack_map(struct ixgbe_dcb_config *cfg, int direction, u8 *map)
259 for (up = 0; up < MAX_USER_PRIORITY; up++)
260 map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up);
264 * ixgbe_dcb_hw_config - Config and enable DCB
265 * @hw: pointer to hardware structure
266 * @dcb_config: pointer to ixgbe_dcb_config structure
268 * Configure dcb settings and enable dcb mode.
270 s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
271 struct ixgbe_dcb_config *dcb_config)
274 u8 ptype[MAX_TRAFFIC_CLASS];
275 u8 bwgid[MAX_TRAFFIC_CLASS];
276 u8 prio_tc[MAX_TRAFFIC_CLASS];
277 u16 refill[MAX_TRAFFIC_CLASS];
278 u16 max[MAX_TRAFFIC_CLASS];
280 /* Unpack CEE standard containers */
281 ixgbe_dcb_unpack_pfc(dcb_config, &pfc_en);
282 ixgbe_dcb_unpack_refill(dcb_config, DCB_TX_CONFIG, refill);
283 ixgbe_dcb_unpack_max(dcb_config, max);
284 ixgbe_dcb_unpack_bwgid(dcb_config, DCB_TX_CONFIG, bwgid);
285 ixgbe_dcb_unpack_prio(dcb_config, DCB_TX_CONFIG, ptype);
286 ixgbe_dcb_unpack_map(dcb_config, DCB_TX_CONFIG, prio_tc);
288 switch (hw->mac.type) {
289 case ixgbe_mac_82598EB:
290 return ixgbe_dcb_hw_config_82598(hw, pfc_en, refill, max,
292 case ixgbe_mac_82599EB:
295 case ixgbe_mac_X550EM_x:
296 case ixgbe_mac_x550em_a:
297 return ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max,
298 bwgid, ptype, prio_tc);
305 /* Helper routines to abstract HW specifics from DCB netlink ops */
306 s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
308 switch (hw->mac.type) {
309 case ixgbe_mac_82598EB:
310 return ixgbe_dcb_config_pfc_82598(hw, pfc_en);
311 case ixgbe_mac_82599EB:
314 case ixgbe_mac_X550EM_x:
315 case ixgbe_mac_x550em_a:
316 return ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc);
323 s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max_frame)
325 __u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS];
326 __u8 prio_type[IEEE_8021QAZ_MAX_TCS];
329 /* naively give each TC a bwg to map onto CEE hardware */
330 __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7};
332 /* Map TSA onto CEE prio type */
333 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
334 switch (ets->tc_tsa[i]) {
335 case IEEE_8021QAZ_TSA_STRICT:
338 case IEEE_8021QAZ_TSA_ETS:
342 /* Hardware only supports priority strict or
343 * ETS transmission selection algorithms if
344 * we receive some other value from dcbnl
351 ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame);
352 return ixgbe_dcb_hw_ets_config(hw, refill, max,
353 bwg_id, prio_type, ets->prio_tc);
356 s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
357 u16 *refill, u16 *max, u8 *bwg_id,
358 u8 *prio_type, u8 *prio_tc)
360 switch (hw->mac.type) {
361 case ixgbe_mac_82598EB:
362 ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max,
364 ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
366 ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
369 case ixgbe_mac_82599EB:
372 case ixgbe_mac_X550EM_x:
373 case ixgbe_mac_x550em_a:
374 ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max,
375 bwg_id, prio_type, prio_tc);
376 ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
378 ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
387 static void ixgbe_dcb_read_rtrup2tc_82599(struct ixgbe_hw *hw, u8 *map)
391 reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC);
392 for (i = 0; i < MAX_USER_PRIORITY; i++)
393 map[i] = IXGBE_RTRUP2TC_UP_MASK &
394 (reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT));
397 void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map)
399 switch (hw->mac.type) {
400 case ixgbe_mac_82599EB:
403 case ixgbe_mac_X550EM_x:
404 case ixgbe_mac_x550em_a:
405 ixgbe_dcb_read_rtrup2tc_82599(hw, map);