1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2020
5 #include "txgbe_type.h"
8 #include "txgbe_dcb_hw.h"
11 * txgbe_dcb_calculate_tc_credits_cee - Calculates traffic class credits
12 * @hw: pointer to hardware structure
13 * @dcb_config: Struct containing DCB settings
14 * @max_frame_size: Maximum frame size
15 * @direction: Configuring either Tx or Rx
17 * This function calculates the credits allocated to each traffic class.
18 * It should be called only after the rules are checked by
19 * txgbe_dcb_check_config_cee().
21 s32 txgbe_dcb_calculate_tc_credits_cee(struct txgbe_hw *hw,
22 struct txgbe_dcb_config *dcb_config,
23 u32 max_frame_size, u8 direction)
25 struct txgbe_dcb_tc_path *p;
26 u32 min_multiplier = 0;
27 u16 min_percent = 100;
29 /* Initialization values default for Tx settings */
31 u32 credit_refill = 0;
33 u16 link_percentage = 0;
37 UNREFERENCED_PARAMETER(hw);
39 if (dcb_config == NULL) {
40 ret_val = TXGBE_ERR_CONFIG;
44 min_credit = ((max_frame_size / 2) + TXGBE_DCB_CREDIT_QUANTUM - 1) /
45 TXGBE_DCB_CREDIT_QUANTUM;
47 /* Find smallest link percentage */
48 for (i = 0; i < TXGBE_DCB_TC_MAX; i++) {
49 p = &dcb_config->tc_config[i].path[direction];
50 bw_percent = dcb_config->bw_percentage[p->bwg_id][direction];
51 link_percentage = p->bwg_percent;
53 link_percentage = (link_percentage * bw_percent) / 100;
55 if (link_percentage && link_percentage < min_percent)
56 min_percent = link_percentage;
60 * The ratio between traffic classes will control the bandwidth
61 * percentages seen on the wire. To calculate this ratio we use
62 * a multiplier. It is required that the refill credits must be
63 * larger than the max frame size so here we find the smallest
64 * multiplier that will allow all bandwidth percentages to be
65 * greater than the max frame size.
67 min_multiplier = (min_credit / min_percent) + 1;
69 /* Find out the link percentage for each TC first */
70 for (i = 0; i < TXGBE_DCB_TC_MAX; i++) {
71 p = &dcb_config->tc_config[i].path[direction];
72 bw_percent = dcb_config->bw_percentage[p->bwg_id][direction];
74 link_percentage = p->bwg_percent;
75 /* Must be careful of integer division for very small nums */
76 link_percentage = (link_percentage * bw_percent) / 100;
77 if (p->bwg_percent > 0 && link_percentage == 0)
80 /* Save link_percentage for reference */
81 p->link_percent = (u8)link_percentage;
83 /* Calculate credit refill ratio using multiplier */
84 credit_refill = min(link_percentage * min_multiplier,
85 (u32)TXGBE_DCB_MAX_CREDIT_REFILL);
87 /* Refill at least minimum credit */
88 if (credit_refill < min_credit)
89 credit_refill = min_credit;
91 p->data_credits_refill = (u16)credit_refill;
93 /* Calculate maximum credit for the TC */
94 credit_max = (link_percentage * TXGBE_DCB_MAX_CREDIT) / 100;
97 * Adjustment based on rule checking, if the percentage
98 * of a TC is too small, the maximum credit may not be
99 * enough to send out a jumbo frame in data plane arbitration.
101 if (credit_max < min_credit)
102 credit_max = min_credit;
104 if (direction == TXGBE_DCB_TX_CONFIG) {
105 dcb_config->tc_config[i].desc_credits_max =
109 p->data_credits_max = (u16)credit_max;
117 * txgbe_dcb_unpack_pfc_cee - Unpack dcb_config PFC info
118 * @cfg: dcb configuration to unpack into hardware consumable fields
119 * @map: user priority to traffic class map
120 * @pfc_up: u8 to store user priority PFC bitmask
122 * This unpacks the dcb configuration PFC info which is stored per
123 * traffic class into a 8bit user priority bitmask that can be
124 * consumed by hardware routines. The priority to tc map must be
125 * updated before calling this routine to use current up-to maps.
127 void txgbe_dcb_unpack_pfc_cee(struct txgbe_dcb_config *cfg, u8 *map, u8 *pfc_up)
129 struct txgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
133 * If the TC for this user priority has PFC enabled then set the
134 * matching bit in 'pfc_up' to reflect that PFC is enabled.
136 for (*pfc_up = 0, up = 0; up < TXGBE_DCB_UP_MAX; up++) {
137 if (tc_config[map[up]].pfc != txgbe_dcb_pfc_disabled)
142 void txgbe_dcb_unpack_refill_cee(struct txgbe_dcb_config *cfg, int direction,
145 struct txgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
148 for (tc = 0; tc < TXGBE_DCB_TC_MAX; tc++)
149 refill[tc] = tc_config[tc].path[direction].data_credits_refill;
152 void txgbe_dcb_unpack_max_cee(struct txgbe_dcb_config *cfg, u16 *max)
154 struct txgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
157 for (tc = 0; tc < TXGBE_DCB_TC_MAX; tc++)
158 max[tc] = tc_config[tc].desc_credits_max;
161 void txgbe_dcb_unpack_bwgid_cee(struct txgbe_dcb_config *cfg, int direction,
164 struct txgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
167 for (tc = 0; tc < TXGBE_DCB_TC_MAX; tc++)
168 bwgid[tc] = tc_config[tc].path[direction].bwg_id;
171 void txgbe_dcb_unpack_tsa_cee(struct txgbe_dcb_config *cfg, int direction,
174 struct txgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
177 for (tc = 0; tc < TXGBE_DCB_TC_MAX; tc++)
178 tsa[tc] = tc_config[tc].path[direction].tsa;
181 u8 txgbe_dcb_get_tc_from_up(struct txgbe_dcb_config *cfg, int direction, u8 up)
183 struct txgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
184 u8 prio_mask = 1 << up;
185 u8 tc = cfg->num_tcs.pg_tcs;
187 /* If tc is 0 then DCB is likely not enabled or supported */
192 * Test from maximum TC to 1 and report the first match we find. If
193 * we find no match we can assume that the TC is 0 since the TC must
194 * be set for all user priorities
196 for (tc--; tc; tc--) {
197 if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap)
204 void txgbe_dcb_unpack_map_cee(struct txgbe_dcb_config *cfg, int direction,
209 for (up = 0; up < TXGBE_DCB_UP_MAX; up++)
210 map[up] = txgbe_dcb_get_tc_from_up(cfg, direction, up);