]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2001-2018 | |
3 | */ | |
7c673cae FG |
4 | |
5 | ||
6 | #include "ixgbe_type.h" | |
7 | #include "ixgbe_dcb.h" | |
8 | #include "ixgbe_dcb_82598.h" | |
9 | #include "ixgbe_dcb_82599.h" | |
10 | ||
11 | /** | |
12 | * ixgbe_dcb_calculate_tc_credits - This calculates the ieee traffic class | |
13 | * credits from the configured bandwidth percentages. Credits | |
14 | * are the smallest unit programmable into the underlying | |
15 | * hardware. The IEEE 802.1Qaz specification do not use bandwidth | |
16 | * groups so this is much simplified from the CEE case. | |
11fdf7f2 TL |
17 | * @bw: bandwidth index by traffic class |
18 | * @refill: refill credits index by traffic class | |
19 | * @max: max credits by traffic class | |
20 | * @max_frame_size: maximum frame size | |
7c673cae FG |
21 | */ |
22 | s32 ixgbe_dcb_calculate_tc_credits(u8 *bw, u16 *refill, u16 *max, | |
23 | int max_frame_size) | |
24 | { | |
25 | int min_percent = 100; | |
26 | int min_credit, multiplier; | |
27 | int i; | |
28 | ||
29 | min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) / | |
30 | IXGBE_DCB_CREDIT_QUANTUM; | |
31 | ||
32 | for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { | |
33 | if (bw[i] < min_percent && bw[i]) | |
34 | min_percent = bw[i]; | |
35 | } | |
36 | ||
37 | multiplier = (min_credit / min_percent) + 1; | |
38 | ||
39 | /* Find out the hw credits for each TC */ | |
40 | for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { | |
41 | int val = min(bw[i] * multiplier, IXGBE_DCB_MAX_CREDIT_REFILL); | |
42 | ||
43 | if (val < min_credit) | |
44 | val = min_credit; | |
45 | refill[i] = (u16)val; | |
46 | ||
47 | max[i] = bw[i] ? (bw[i]*IXGBE_DCB_MAX_CREDIT)/100 : min_credit; | |
48 | } | |
49 | ||
50 | return 0; | |
51 | } | |
52 | ||
53 | /** | |
54 | * ixgbe_dcb_calculate_tc_credits_cee - Calculates traffic class credits | |
11fdf7f2 TL |
55 | * @hw: pointer to hardware structure |
56 | * @dcb_config: Struct containing DCB settings | |
57 | * @max_frame_size: Maximum frame size | |
58 | * @direction: Configuring either Tx or Rx | |
7c673cae FG |
59 | * |
60 | * This function calculates the credits allocated to each traffic class. | |
61 | * It should be called only after the rules are checked by | |
62 | * ixgbe_dcb_check_config_cee(). | |
63 | */ | |
64 | s32 ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw *hw, | |
65 | struct ixgbe_dcb_config *dcb_config, | |
66 | u32 max_frame_size, u8 direction) | |
67 | { | |
68 | struct ixgbe_dcb_tc_path *p; | |
69 | u32 min_multiplier = 0; | |
70 | u16 min_percent = 100; | |
71 | s32 ret_val = IXGBE_SUCCESS; | |
72 | /* Initialization values default for Tx settings */ | |
73 | u32 min_credit = 0; | |
74 | u32 credit_refill = 0; | |
75 | u32 credit_max = 0; | |
76 | u16 link_percentage = 0; | |
77 | u8 bw_percent = 0; | |
78 | u8 i; | |
79 | ||
80 | if (dcb_config == NULL) { | |
81 | ret_val = IXGBE_ERR_CONFIG; | |
82 | goto out; | |
83 | } | |
84 | ||
85 | min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) / | |
86 | IXGBE_DCB_CREDIT_QUANTUM; | |
87 | ||
88 | /* Find smallest link percentage */ | |
89 | for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { | |
90 | p = &dcb_config->tc_config[i].path[direction]; | |
91 | bw_percent = dcb_config->bw_percentage[direction][p->bwg_id]; | |
92 | link_percentage = p->bwg_percent; | |
93 | ||
94 | link_percentage = (link_percentage * bw_percent) / 100; | |
95 | ||
96 | if (link_percentage && link_percentage < min_percent) | |
97 | min_percent = link_percentage; | |
98 | } | |
99 | ||
100 | /* | |
101 | * The ratio between traffic classes will control the bandwidth | |
102 | * percentages seen on the wire. To calculate this ratio we use | |
103 | * a multiplier. It is required that the refill credits must be | |
104 | * larger than the max frame size so here we find the smallest | |
105 | * multiplier that will allow all bandwidth percentages to be | |
106 | * greater than the max frame size. | |
107 | */ | |
108 | min_multiplier = (min_credit / min_percent) + 1; | |
109 | ||
110 | /* Find out the link percentage for each TC first */ | |
111 | for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { | |
112 | p = &dcb_config->tc_config[i].path[direction]; | |
113 | bw_percent = dcb_config->bw_percentage[direction][p->bwg_id]; | |
114 | ||
115 | link_percentage = p->bwg_percent; | |
116 | /* Must be careful of integer division for very small nums */ | |
117 | link_percentage = (link_percentage * bw_percent) / 100; | |
118 | if (p->bwg_percent > 0 && link_percentage == 0) | |
119 | link_percentage = 1; | |
120 | ||
121 | /* Save link_percentage for reference */ | |
122 | p->link_percent = (u8)link_percentage; | |
123 | ||
124 | /* Calculate credit refill ratio using multiplier */ | |
125 | credit_refill = min(link_percentage * min_multiplier, | |
126 | (u32)IXGBE_DCB_MAX_CREDIT_REFILL); | |
127 | ||
128 | /* Refill at least minimum credit */ | |
129 | if (credit_refill < min_credit) | |
130 | credit_refill = min_credit; | |
131 | ||
132 | p->data_credits_refill = (u16)credit_refill; | |
133 | ||
134 | /* Calculate maximum credit for the TC */ | |
135 | credit_max = (link_percentage * IXGBE_DCB_MAX_CREDIT) / 100; | |
136 | ||
137 | /* | |
138 | * Adjustment based on rule checking, if the percentage | |
139 | * of a TC is too small, the maximum credit may not be | |
140 | * enough to send out a jumbo frame in data plane arbitration. | |
141 | */ | |
142 | if (credit_max < min_credit) | |
143 | credit_max = min_credit; | |
144 | ||
145 | if (direction == IXGBE_DCB_TX_CONFIG) { | |
146 | /* | |
147 | * Adjustment based on rule checking, if the | |
148 | * percentage of a TC is too small, the maximum | |
149 | * credit may not be enough to send out a TSO | |
150 | * packet in descriptor plane arbitration. | |
151 | */ | |
152 | if (credit_max && (credit_max < | |
153 | IXGBE_DCB_MIN_TSO_CREDIT) | |
154 | && (hw->mac.type == ixgbe_mac_82598EB)) | |
155 | credit_max = IXGBE_DCB_MIN_TSO_CREDIT; | |
156 | ||
157 | dcb_config->tc_config[i].desc_credits_max = | |
158 | (u16)credit_max; | |
159 | } | |
160 | ||
161 | p->data_credits_max = (u16)credit_max; | |
162 | } | |
163 | ||
164 | out: | |
165 | return ret_val; | |
166 | } | |
167 | ||
168 | /** | |
169 | * ixgbe_dcb_unpack_pfc_cee - Unpack dcb_config PFC info | |
170 | * @cfg: dcb configuration to unpack into hardware consumable fields | |
171 | * @map: user priority to traffic class map | |
172 | * @pfc_up: u8 to store user priority PFC bitmask | |
173 | * | |
174 | * This unpacks the dcb configuration PFC info which is stored per | |
175 | * traffic class into a 8bit user priority bitmask that can be | |
176 | * consumed by hardware routines. The priority to tc map must be | |
177 | * updated before calling this routine to use current up-to maps. | |
178 | */ | |
179 | void ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config *cfg, u8 *map, u8 *pfc_up) | |
180 | { | |
181 | struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; | |
182 | int up; | |
183 | ||
184 | /* | |
185 | * If the TC for this user priority has PFC enabled then set the | |
186 | * matching bit in 'pfc_up' to reflect that PFC is enabled. | |
187 | */ | |
188 | for (*pfc_up = 0, up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++) { | |
189 | if (tc_config[map[up]].pfc != ixgbe_dcb_pfc_disabled) | |
190 | *pfc_up |= 1 << up; | |
191 | } | |
192 | } | |
193 | ||
194 | void ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config *cfg, int direction, | |
195 | u16 *refill) | |
196 | { | |
197 | struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; | |
198 | int tc; | |
199 | ||
200 | for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) | |
201 | refill[tc] = tc_config[tc].path[direction].data_credits_refill; | |
202 | } | |
203 | ||
204 | void ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config *cfg, u16 *max) | |
205 | { | |
206 | struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; | |
207 | int tc; | |
208 | ||
209 | for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) | |
210 | max[tc] = tc_config[tc].desc_credits_max; | |
211 | } | |
212 | ||
213 | void ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config *cfg, int direction, | |
214 | u8 *bwgid) | |
215 | { | |
216 | struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; | |
217 | int tc; | |
218 | ||
219 | for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) | |
220 | bwgid[tc] = tc_config[tc].path[direction].bwg_id; | |
221 | } | |
222 | ||
223 | void ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config *cfg, int direction, | |
224 | u8 *tsa) | |
225 | { | |
226 | struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; | |
227 | int tc; | |
228 | ||
229 | for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) | |
230 | tsa[tc] = tc_config[tc].path[direction].tsa; | |
231 | } | |
232 | ||
233 | u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up) | |
234 | { | |
235 | struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; | |
236 | u8 prio_mask = 1 << up; | |
237 | u8 tc = cfg->num_tcs.pg_tcs; | |
238 | ||
239 | /* If tc is 0 then DCB is likely not enabled or supported */ | |
240 | if (!tc) | |
241 | goto out; | |
242 | ||
243 | /* | |
244 | * Test from maximum TC to 1 and report the first match we find. If | |
245 | * we find no match we can assume that the TC is 0 since the TC must | |
246 | * be set for all user priorities | |
247 | */ | |
248 | for (tc--; tc; tc--) { | |
249 | if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap) | |
250 | break; | |
251 | } | |
252 | out: | |
253 | return tc; | |
254 | } | |
255 | ||
256 | void ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config *cfg, int direction, | |
257 | u8 *map) | |
258 | { | |
259 | u8 up; | |
260 | ||
261 | for (up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++) | |
262 | map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up); | |
263 | } | |
264 | ||
265 | /** | |
266 | * ixgbe_dcb_config - Struct containing DCB settings. | |
267 | * @dcb_config: Pointer to DCB config structure | |
268 | * | |
269 | * This function checks DCB rules for DCB settings. | |
270 | * The following rules are checked: | |
271 | * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%. | |
272 | * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth | |
273 | * Group must total 100. | |
274 | * 3. A Traffic Class should not be set to both Link Strict Priority | |
275 | * and Group Strict Priority. | |
276 | * 4. Link strict Bandwidth Groups can only have link strict traffic classes | |
277 | * with zero bandwidth. | |
278 | */ | |
279 | s32 ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config *dcb_config) | |
280 | { | |
281 | struct ixgbe_dcb_tc_path *p; | |
282 | s32 ret_val = IXGBE_SUCCESS; | |
283 | u8 i, j, bw = 0, bw_id; | |
284 | u8 bw_sum[2][IXGBE_DCB_MAX_BW_GROUP]; | |
285 | bool link_strict[2][IXGBE_DCB_MAX_BW_GROUP]; | |
286 | ||
287 | memset(bw_sum, 0, sizeof(bw_sum)); | |
288 | memset(link_strict, 0, sizeof(link_strict)); | |
289 | ||
290 | /* First Tx, then Rx */ | |
291 | for (i = 0; i < 2; i++) { | |
292 | /* Check each traffic class for rule violation */ | |
293 | for (j = 0; j < IXGBE_DCB_MAX_TRAFFIC_CLASS; j++) { | |
294 | p = &dcb_config->tc_config[j].path[i]; | |
295 | ||
296 | bw = p->bwg_percent; | |
297 | bw_id = p->bwg_id; | |
298 | ||
299 | if (bw_id >= IXGBE_DCB_MAX_BW_GROUP) { | |
300 | ret_val = IXGBE_ERR_CONFIG; | |
301 | goto err_config; | |
302 | } | |
303 | if (p->tsa == ixgbe_dcb_tsa_strict) { | |
304 | link_strict[i][bw_id] = true; | |
305 | /* Link strict should have zero bandwidth */ | |
306 | if (bw) { | |
307 | ret_val = IXGBE_ERR_CONFIG; | |
308 | goto err_config; | |
309 | } | |
310 | } else if (!bw) { | |
311 | /* | |
312 | * Traffic classes without link strict | |
313 | * should have non-zero bandwidth. | |
314 | */ | |
315 | ret_val = IXGBE_ERR_CONFIG; | |
316 | goto err_config; | |
317 | } | |
318 | bw_sum[i][bw_id] += bw; | |
319 | } | |
320 | ||
321 | bw = 0; | |
322 | ||
323 | /* Check each bandwidth group for rule violation */ | |
324 | for (j = 0; j < IXGBE_DCB_MAX_BW_GROUP; j++) { | |
325 | bw += dcb_config->bw_percentage[i][j]; | |
326 | /* | |
327 | * Sum of bandwidth percentages of all traffic classes | |
328 | * within a Bandwidth Group must total 100 except for | |
329 | * link strict group (zero bandwidth). | |
330 | */ | |
331 | if (link_strict[i][j]) { | |
332 | if (bw_sum[i][j]) { | |
333 | /* | |
334 | * Link strict group should have zero | |
335 | * bandwidth. | |
336 | */ | |
337 | ret_val = IXGBE_ERR_CONFIG; | |
338 | goto err_config; | |
339 | } | |
340 | } else if (bw_sum[i][j] != IXGBE_DCB_BW_PERCENT && | |
341 | bw_sum[i][j] != 0) { | |
342 | ret_val = IXGBE_ERR_CONFIG; | |
343 | goto err_config; | |
344 | } | |
345 | } | |
346 | ||
347 | if (bw != IXGBE_DCB_BW_PERCENT) { | |
348 | ret_val = IXGBE_ERR_CONFIG; | |
349 | goto err_config; | |
350 | } | |
351 | } | |
352 | ||
353 | err_config: | |
354 | ||
355 | return ret_val; | |
356 | } | |
357 | ||
358 | /** | |
359 | * ixgbe_dcb_get_tc_stats - Returns status of each traffic class | |
360 | * @hw: pointer to hardware structure | |
361 | * @stats: pointer to statistics structure | |
362 | * @tc_count: Number of elements in bwg_array. | |
363 | * | |
364 | * This function returns the status data for each of the Traffic Classes in use. | |
365 | */ | |
366 | s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, | |
367 | u8 tc_count) | |
368 | { | |
369 | s32 ret = IXGBE_NOT_IMPLEMENTED; | |
370 | switch (hw->mac.type) { | |
371 | case ixgbe_mac_82598EB: | |
372 | ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count); | |
373 | break; | |
374 | case ixgbe_mac_82599EB: | |
375 | case ixgbe_mac_X540: | |
376 | case ixgbe_mac_X550: | |
377 | case ixgbe_mac_X550EM_x: | |
378 | case ixgbe_mac_X550EM_a: | |
379 | ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count); | |
380 | break; | |
381 | default: | |
382 | break; | |
383 | } | |
384 | return ret; | |
385 | } | |
386 | ||
387 | /** | |
388 | * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class | |
389 | * @hw: pointer to hardware structure | |
390 | * @stats: pointer to statistics structure | |
391 | * @tc_count: Number of elements in bwg_array. | |
392 | * | |
393 | * This function returns the CBFC status data for each of the Traffic Classes. | |
394 | */ | |
395 | s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, | |
396 | u8 tc_count) | |
397 | { | |
398 | s32 ret = IXGBE_NOT_IMPLEMENTED; | |
399 | switch (hw->mac.type) { | |
400 | case ixgbe_mac_82598EB: | |
401 | ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count); | |
402 | break; | |
403 | case ixgbe_mac_82599EB: | |
404 | case ixgbe_mac_X540: | |
405 | case ixgbe_mac_X550: | |
406 | case ixgbe_mac_X550EM_x: | |
407 | case ixgbe_mac_X550EM_a: | |
408 | ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count); | |
409 | break; | |
410 | default: | |
411 | break; | |
412 | } | |
413 | return ret; | |
414 | } | |
415 | ||
416 | /** | |
417 | * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter | |
418 | * @hw: pointer to hardware structure | |
419 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
420 | * | |
421 | * Configure Rx Data Arbiter and credits for each traffic class. | |
422 | */ | |
423 | s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw, | |
424 | struct ixgbe_dcb_config *dcb_config) | |
425 | { | |
426 | s32 ret = IXGBE_NOT_IMPLEMENTED; | |
427 | u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; | |
428 | u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; | |
429 | u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; | |
430 | u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; | |
431 | u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; | |
432 | ||
433 | ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); | |
434 | ixgbe_dcb_unpack_max_cee(dcb_config, max); | |
435 | ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); | |
436 | ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); | |
437 | ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); | |
438 | ||
439 | switch (hw->mac.type) { | |
440 | case ixgbe_mac_82598EB: | |
441 | ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); | |
442 | break; | |
443 | case ixgbe_mac_82599EB: | |
444 | case ixgbe_mac_X540: | |
445 | case ixgbe_mac_X550: | |
446 | case ixgbe_mac_X550EM_x: | |
447 | case ixgbe_mac_X550EM_a: | |
448 | ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid, | |
449 | tsa, map); | |
450 | break; | |
451 | default: | |
452 | break; | |
453 | } | |
454 | return ret; | |
455 | } | |
456 | ||
457 | /** | |
458 | * ixgbe_dcb_config_tx_desc_arbiter_cee - Config Tx Desc arbiter | |
459 | * @hw: pointer to hardware structure | |
460 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
461 | * | |
462 | * Configure Tx Descriptor Arbiter and credits for each traffic class. | |
463 | */ | |
464 | s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw, | |
465 | struct ixgbe_dcb_config *dcb_config) | |
466 | { | |
467 | s32 ret = IXGBE_NOT_IMPLEMENTED; | |
468 | u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
469 | u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
470 | u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
471 | u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
472 | ||
473 | ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); | |
474 | ixgbe_dcb_unpack_max_cee(dcb_config, max); | |
475 | ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); | |
476 | ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); | |
477 | ||
478 | switch (hw->mac.type) { | |
479 | case ixgbe_mac_82598EB: | |
480 | ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, | |
481 | bwgid, tsa); | |
482 | break; | |
483 | case ixgbe_mac_82599EB: | |
484 | case ixgbe_mac_X540: | |
485 | case ixgbe_mac_X550: | |
486 | case ixgbe_mac_X550EM_x: | |
487 | case ixgbe_mac_X550EM_a: | |
488 | ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, | |
489 | bwgid, tsa); | |
490 | break; | |
491 | default: | |
492 | break; | |
493 | } | |
494 | return ret; | |
495 | } | |
496 | ||
497 | /** | |
498 | * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter | |
499 | * @hw: pointer to hardware structure | |
500 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
501 | * | |
502 | * Configure Tx Data Arbiter and credits for each traffic class. | |
503 | */ | |
504 | s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw, | |
505 | struct ixgbe_dcb_config *dcb_config) | |
506 | { | |
507 | s32 ret = IXGBE_NOT_IMPLEMENTED; | |
508 | u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
509 | u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
510 | u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; | |
511 | u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
512 | u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
513 | ||
514 | ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); | |
515 | ixgbe_dcb_unpack_max_cee(dcb_config, max); | |
516 | ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); | |
517 | ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); | |
518 | ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); | |
519 | ||
520 | switch (hw->mac.type) { | |
521 | case ixgbe_mac_82598EB: | |
522 | ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, | |
523 | bwgid, tsa); | |
524 | break; | |
525 | case ixgbe_mac_82599EB: | |
526 | case ixgbe_mac_X540: | |
527 | case ixgbe_mac_X550: | |
528 | case ixgbe_mac_X550EM_x: | |
529 | case ixgbe_mac_X550EM_a: | |
530 | ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, | |
531 | bwgid, tsa, | |
532 | map); | |
533 | break; | |
534 | default: | |
535 | break; | |
536 | } | |
537 | return ret; | |
538 | } | |
539 | ||
540 | /** | |
541 | * ixgbe_dcb_config_pfc_cee - Config priority flow control | |
542 | * @hw: pointer to hardware structure | |
543 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
544 | * | |
545 | * Configure Priority Flow Control for each traffic class. | |
546 | */ | |
547 | s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw, | |
548 | struct ixgbe_dcb_config *dcb_config) | |
549 | { | |
550 | s32 ret = IXGBE_NOT_IMPLEMENTED; | |
551 | u8 pfc_en; | |
552 | u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; | |
553 | ||
554 | ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); | |
555 | ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en); | |
556 | ||
557 | switch (hw->mac.type) { | |
558 | case ixgbe_mac_82598EB: | |
559 | ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en); | |
560 | break; | |
561 | case ixgbe_mac_82599EB: | |
562 | case ixgbe_mac_X540: | |
563 | case ixgbe_mac_X550: | |
564 | case ixgbe_mac_X550EM_x: | |
565 | case ixgbe_mac_X550EM_a: | |
566 | ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); | |
567 | break; | |
568 | default: | |
569 | break; | |
570 | } | |
571 | return ret; | |
572 | } | |
573 | ||
574 | /** | |
575 | * ixgbe_dcb_config_tc_stats - Config traffic class statistics | |
576 | * @hw: pointer to hardware structure | |
577 | * | |
578 | * Configure queue statistics registers, all queues belonging to same traffic | |
579 | * class uses a single set of queue statistics counters. | |
580 | */ | |
581 | s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw) | |
582 | { | |
583 | s32 ret = IXGBE_NOT_IMPLEMENTED; | |
584 | switch (hw->mac.type) { | |
585 | case ixgbe_mac_82598EB: | |
586 | ret = ixgbe_dcb_config_tc_stats_82598(hw); | |
587 | break; | |
588 | case ixgbe_mac_82599EB: | |
589 | case ixgbe_mac_X540: | |
590 | case ixgbe_mac_X550: | |
591 | case ixgbe_mac_X550EM_x: | |
592 | case ixgbe_mac_X550EM_a: | |
593 | ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL); | |
594 | break; | |
595 | default: | |
596 | break; | |
597 | } | |
598 | return ret; | |
599 | } | |
600 | ||
601 | /** | |
602 | * ixgbe_dcb_hw_config_cee - Config and enable DCB | |
603 | * @hw: pointer to hardware structure | |
604 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
605 | * | |
606 | * Configure dcb settings and enable dcb mode. | |
607 | */ | |
608 | s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw, | |
609 | struct ixgbe_dcb_config *dcb_config) | |
610 | { | |
611 | s32 ret = IXGBE_NOT_IMPLEMENTED; | |
612 | u8 pfc_en; | |
613 | u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
614 | u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
615 | u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; | |
616 | u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
617 | u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; | |
618 | ||
619 | /* Unpack CEE standard containers */ | |
620 | ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); | |
621 | ixgbe_dcb_unpack_max_cee(dcb_config, max); | |
622 | ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); | |
623 | ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); | |
624 | ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); | |
625 | ||
626 | switch (hw->mac.type) { | |
627 | case ixgbe_mac_82598EB: | |
628 | ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed, | |
629 | refill, max, bwgid, tsa); | |
630 | break; | |
631 | case ixgbe_mac_82599EB: | |
632 | case ixgbe_mac_X540: | |
633 | case ixgbe_mac_X550: | |
634 | case ixgbe_mac_X550EM_x: | |
635 | case ixgbe_mac_X550EM_a: | |
636 | ixgbe_dcb_config_82599(hw, dcb_config); | |
637 | ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed, | |
638 | refill, max, bwgid, | |
639 | tsa, map); | |
640 | ||
641 | ixgbe_dcb_config_tc_stats_82599(hw, dcb_config); | |
642 | break; | |
643 | default: | |
644 | break; | |
645 | } | |
646 | ||
647 | if (!ret && dcb_config->pfc_mode_enable) { | |
648 | ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en); | |
649 | ret = ixgbe_dcb_config_pfc(hw, pfc_en, map); | |
650 | } | |
651 | ||
652 | return ret; | |
653 | } | |
654 | ||
655 | /* Helper routines to abstract HW specifics from DCB netlink ops */ | |
656 | s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map) | |
657 | { | |
658 | int ret = IXGBE_ERR_PARAM; | |
659 | ||
660 | switch (hw->mac.type) { | |
661 | case ixgbe_mac_82598EB: | |
662 | ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en); | |
663 | break; | |
664 | case ixgbe_mac_82599EB: | |
665 | case ixgbe_mac_X540: | |
666 | case ixgbe_mac_X550: | |
667 | case ixgbe_mac_X550EM_x: | |
668 | case ixgbe_mac_X550EM_a: | |
669 | ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); | |
670 | break; | |
671 | default: | |
672 | break; | |
673 | } | |
674 | return ret; | |
675 | } | |
676 | ||
677 | s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max, | |
678 | u8 *bwg_id, u8 *tsa, u8 *map) | |
679 | { | |
680 | switch (hw->mac.type) { | |
681 | case ixgbe_mac_82598EB: | |
682 | ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); | |
683 | ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id, | |
684 | tsa); | |
685 | ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id, | |
686 | tsa); | |
687 | break; | |
688 | case ixgbe_mac_82599EB: | |
689 | case ixgbe_mac_X540: | |
690 | case ixgbe_mac_X550: | |
691 | case ixgbe_mac_X550EM_x: | |
692 | case ixgbe_mac_X550EM_a: | |
693 | ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, | |
694 | tsa, map); | |
695 | ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id, | |
696 | tsa); | |
697 | ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id, | |
698 | tsa, map); | |
699 | break; | |
700 | default: | |
701 | break; | |
702 | } | |
703 | return 0; | |
704 | } |