hs-test: fixed timed out tests passing in the CI
[vpp.git] / src / vnet / policer / xlate.c
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <string.h>
16 #include <stddef.h>
17 #include <stdio.h>
18 #include <assert.h>
19 #include <math.h>
20 #include <stdint.h>
21
22 #include <vlib/vlib.h>
23 #include <vnet/vnet.h>
24
25 #include <vnet/policer/policer.h>
26
27 /* debugs */
28 #define QOS_DEBUG_ERROR(msg, args...)                                         \
29   vlib_log_err (vnet_policer_main.log_class, msg, ##args);
30
31 #define QOS_DEBUG_INFO(msg, args...)                                          \
32   vlib_log_info (vnet_policer_main.log_class, msg, ##args);
33
34 #ifndef MIN
35 #define MIN(x,y)            (((x)<(y))?(x):(y))
36 #endif
37
38 #ifndef MAX
39 #define MAX(x,y)            (((x)>(y))?(x):(y))
40 #endif
41
42 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AH_OFFSET                   0
43 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AH_MASK                     8
44 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AH_SHIFT                   24
45
46 #define IPE_POLICER_FULL_WRITE_REQUEST_TYPE_OFFSET                    2
47 #define IPE_POLICER_FULL_WRITE_REQUEST_TYPE_MASK                      2
48 #define IPE_POLICER_FULL_WRITE_REQUEST_TYPE_SHIFT                    10
49
50 #define IPE_POLICER_FULL_WRITE_REQUEST_CMD_OFFSET                     3
51 #define IPE_POLICER_FULL_WRITE_REQUEST_CMD_MASK                       2
52 #define IPE_POLICER_FULL_WRITE_REQUEST_CMD_SHIFT                      0
53
54 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AL_OFFSET                   4
55 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AL_MASK                    32
56 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AL_SHIFT                    0
57
58 #define IPE_POLICER_FULL_WRITE_REQUEST_RFC_OFFSET                     8
59 #define IPE_POLICER_FULL_WRITE_REQUEST_RFC_MASK                       2
60 #define IPE_POLICER_FULL_WRITE_REQUEST_RFC_SHIFT                     30
61
62 #define IPE_POLICER_FULL_WRITE_REQUEST_AN_OFFSET                      8
63 #define IPE_POLICER_FULL_WRITE_REQUEST_AN_MASK                        1
64 #define IPE_POLICER_FULL_WRITE_REQUEST_AN_SHIFT                      29
65
66 #define IPE_POLICER_FULL_WRITE_REQUEST_REXP_OFFSET                    8
67 #define IPE_POLICER_FULL_WRITE_REQUEST_REXP_MASK                      4
68 #define IPE_POLICER_FULL_WRITE_REQUEST_REXP_SHIFT                    22
69
70 #define IPE_POLICER_FULL_WRITE_REQUEST_ARM_OFFSET                     9
71 #define IPE_POLICER_FULL_WRITE_REQUEST_ARM_MASK                      11
72 #define IPE_POLICER_FULL_WRITE_REQUEST_ARM_SHIFT                     11
73
74 #define IPE_POLICER_FULL_WRITE_REQUEST_PRM_OFFSET                    10
75 #define IPE_POLICER_FULL_WRITE_REQUEST_PRM_MASK                      11
76 #define IPE_POLICER_FULL_WRITE_REQUEST_PRM_SHIFT                      0
77
78 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLE_OFFSET                   12
79 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLE_MASK                      5
80 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLE_SHIFT                    27
81
82 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLM_OFFSET                   12
83 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLM_MASK                      7
84 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLM_SHIFT                    20
85
86 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLE_OFFSET                   13
87 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLE_MASK                      5
88 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLE_SHIFT                    15
89
90 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLM_OFFSET                   14
91 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLM_MASK                      7
92 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLM_SHIFT                     8
93
94 #define IPE_POLICER_FULL_WRITE_REQUEST_CB_OFFSET                     16
95 #define IPE_POLICER_FULL_WRITE_REQUEST_CB_MASK                       31
96 #define IPE_POLICER_FULL_WRITE_REQUEST_CB_SHIFT                       0
97
98 #define IPE_POLICER_FULL_WRITE_REQUEST_EB_OFFSET                     20
99 #define IPE_POLICER_FULL_WRITE_REQUEST_EB_MASK                       31
100 #define IPE_POLICER_FULL_WRITE_REQUEST_EB_SHIFT                       0
101
102 #define IPE_RFC_RFC2697           0x00000000
103 #define IPE_RFC_RFC2698           0x00000001
104 #define IPE_RFC_RFC4115           0x00000002
105 #define IPE_RFC_MEF5CF1           0x00000003
106
107 /* End of constants copied from sse_ipe_desc_fmt.h */
108
109 /* Misc Policer specific definitions */
110 #define QOS_POLICER_FIXED_PKT_SIZE 256
111
112 #define QOS_POL_TICKS_PER_SEC 1000LL /* 1 tick = 1 ms */
113
114 /*
115  * Default burst, in ms (byte format)
116  */
117 #define QOS_POL_DEF_BURST_BYTE 100
118
119 /*
120  * Minimum burst needs to be such that the largest packet size is accommodated
121  */
122 #define QOS_POL_MIN_BURST_BYTE 9 * 1024
123
124 /*
125  * Flag to indicate if AN is employed or not
126  * 1 - TRUE, 0 - FALSE
127  */
128 #define QOS_POL_ALLOW_NEGATIVE 1
129
130 /* Various Macros to take care of policer calculations */
131
132 #define QOS_POL_COMM_BKT_MAX (1 << IPE_POLICER_FULL_WRITE_REQUEST_CB_MASK)
133 #define QOS_POL_EXTD_BKT_MAX (1 << IPE_POLICER_FULL_WRITE_REQUEST_EB_MASK)
134
135 #define QOS_POL_RATE_EXP_SIZE      (IPE_POLICER_FULL_WRITE_REQUEST_REXP_MASK)
136 #define QOS_POL_RATE_EXP_MAX       ((1 << QOS_POL_RATE_EXP_SIZE) - 1)
137 #define QOS_POL_AVG_RATE_MANT_SIZE (IPE_POLICER_FULL_WRITE_REQUEST_ARM_MASK)
138 #define QOS_POL_AVG_RATE_MANT_MAX  ((1 << QOS_POL_AVG_RATE_MANT_SIZE) - 1)
139 #define QOS_POL_AVG_RATE_MAX                                                  \
140   (QOS_POL_AVG_RATE_MANT_MAX << QOS_POL_RATE_EXP_MAX)
141
142 #define QOS_POL_PEAK_RATE_MANT_SIZE (IPE_POLICER_FULL_WRITE_REQUEST_PRM_MASK)
143 #define QOS_POL_PEAK_RATE_MANT_MAX  ((1 << QOS_POL_PEAK_RATE_MANT_SIZE) - 1)
144 #define QOS_POL_PEAK_RATE_MAX                                                 \
145   (QOS_POL_PEAK_RATE_MANT_MAX << QOS_POL_RATE_EXP_MAX)
146
147 #define QOS_POL_COMM_BKT_LIMIT_MANT_SIZE                                      \
148   (IPE_POLICER_FULL_WRITE_REQUEST_CBLM_MASK)
149 #define QOS_POL_COMM_BKT_LIMIT_MANT_MAX                                       \
150   ((1 << QOS_POL_COMM_BKT_LIMIT_MANT_SIZE) - 1)
151 #define QOS_POL_COMM_BKT_LIMIT_EXP_SIZE                                       \
152   (IPE_POLICER_FULL_WRITE_REQUEST_CBLE_MASK)
153 #define QOS_POL_COMM_BKT_LIMIT_EXP_MAX                                        \
154   ((1 << QOS_POL_COMM_BKT_LIMIT_EXP_SIZE) - 1)
155 #define QOS_POL_COMM_BKT_LIMIT_MAX                                            \
156   ((u64) QOS_POL_COMM_BKT_LIMIT_MANT_MAX                                      \
157    << (u64) QOS_POL_COMM_BKT_LIMIT_EXP_MAX)
158
159 #define QOS_POL_EXTD_BKT_LIMIT_MANT_SIZE                                      \
160   (IPE_POLICER_FULL_WRITE_REQUEST_EBLM_MASK)
161 #define QOS_POL_EXTD_BKT_LIMIT_MANT_MAX                                       \
162   ((1 << QOS_POL_EXTD_BKT_LIMIT_MANT_SIZE) - 1)
163 #define QOS_POL_EXTD_BKT_LIMIT_EXP_SIZE                                       \
164   (IPE_POLICER_FULL_WRITE_REQUEST_EBLE_MASK)
165 #define QOS_POL_EXTD_BKT_LIMIT_EXP_MAX                                        \
166   ((1 << QOS_POL_EXTD_BKT_LIMIT_EXP_SIZE) - 1)
167 #define QOS_POL_EXT_BKT_LIMIT_MAX                                             \
168   ((u64) QOS_POL_EXTD_BKT_LIMIT_MANT_MAX                                      \
169    << (u64) QOS_POL_EXTD_BKT_LIMIT_EXP_MAX)
170
171 /*
172  * Rates determine the units of the bucket
173  *    256.114688 Gbps < Rate                      8 byte units
174  *    128.057344 Gbps < Rate <= 256.114688 Gbps   4 byte units
175  *     64.028672 Gbps < Rate <= 128.057344 Gbps   2 byte units
176  *                      Rate <=  64.028672 Gbps   1 byte units
177  *
178  * The code uses bytes per tick as oppose to Gigabits per second.
179  */
180 #define RATE256 (256114688000LL / 8LL / QOS_POL_TICKS_PER_SEC)
181 #define RATE128 (128057344000LL / 8LL / QOS_POL_TICKS_PER_SEC)
182 #define RATE64  (64028672000LL / 8LL / QOS_POL_TICKS_PER_SEC)
183
184 #define RATE_OVER256_UNIT  8LL
185 #define RATE_128TO256_UNIT 4LL
186 #define RATE_64TO128_UNIT  2LL
187
188 static int
189 qos_pol_round (u64 numerator, u64 denominator, u64 *rounded_value,
190                qos_round_type_en round_type)
191 {
192   int rc = 0;
193
194   if (denominator == 0)
195     {
196       QOS_DEBUG_ERROR ("Illegal denominator");
197       return (EINVAL);
198     }
199
200   switch (round_type)
201     {
202     case QOS_ROUND_TO_CLOSEST:
203       *rounded_value = ((numerator + (denominator >> 1)) / denominator);
204       break;
205
206     case QOS_ROUND_TO_UP:
207       *rounded_value = (numerator / denominator);
208       if ((*rounded_value * denominator) < numerator)
209         {
210           *rounded_value += 1;
211         }
212       break;
213
214     case QOS_ROUND_TO_DOWN:
215       *rounded_value = (numerator / denominator);
216       break;
217
218     case QOS_ROUND_INVALID:
219     default:
220       QOS_DEBUG_ERROR ("Illegal round type");
221       rc = EINVAL;
222       break;
223     }
224   return (rc);
225 }
226
227 static int
228 pol_validate_cfg_params (qos_pol_cfg_params_st *cfg)
229 {
230   u64 numer, denom, rnd_value;
231   u32 cir_hw, eir_hw;
232   int rc = 0;
233
234   if ((cfg->rfc == QOS_POLICER_TYPE_2R3C_RFC_2698) &&
235       (cfg->rb.kbps.eir_kbps < cfg->rb.kbps.cir_kbps))
236     {
237       QOS_DEBUG_ERROR ("CIR (%u kbps) is greater than PIR (%u kbps)",
238                        cfg->rb.kbps.cir_kbps, cfg->rb.kbps.eir_kbps);
239       return (EINVAL);
240     }
241
242   /*
243    * convert rates to bytes-per-tick
244    */
245   numer = (u64) (cfg->rb.kbps.cir_kbps);
246   denom = (u64) (8 * QOS_POL_TICKS_PER_SEC) / 1000;
247   rc = qos_pol_round (numer, denom, &rnd_value, cfg->rnd_type);
248   if (rc != 0)
249     {
250       QOS_DEBUG_ERROR ("Unable to convert CIR to bytes/tick format");
251       return (rc);
252     }
253   cir_hw = (u32) rnd_value;
254
255   numer = (u64) (cfg->rb.kbps.eir_kbps);
256   rc = qos_pol_round (numer, denom, &rnd_value, cfg->rnd_type);
257   if (rc != 0)
258     {
259       QOS_DEBUG_ERROR ("Unable to convert EIR to bytes/tick format");
260       return (rc);
261     }
262   eir_hw = (u32) rnd_value;
263
264   if (cir_hw > QOS_POL_AVG_RATE_MAX)
265     {
266       QOS_DEBUG_ERROR ("hw cir (%u bytes/tick) is greater than the "
267                        "max supported value (%u)",
268                        cir_hw, QOS_POL_AVG_RATE_MAX);
269       return (EINVAL);
270     }
271
272   if (eir_hw > QOS_POL_PEAK_RATE_MAX)
273     {
274       QOS_DEBUG_ERROR ("hw eir (%u bytes/tick) is greater than the "
275                        "max supported value (%u). Capping it to the max. "
276                        "supported value",
277                        eir_hw, QOS_POL_PEAK_RATE_MAX);
278       return (EINVAL);
279     }
280   /*
281    * CIR = 0, with bc != 0 is not allowed
282    */
283   if ((cfg->rb.kbps.cir_kbps == 0) && cfg->rb.kbps.cb_bytes)
284     {
285       QOS_DEBUG_ERROR ("CIR = 0 with bc != 0");
286       return (EINVAL);
287     }
288
289   if ((cfg->rb.kbps.eir_kbps == 0) &&
290       (cfg->rfc > QOS_POLICER_TYPE_1R3C_RFC_2697))
291     {
292       QOS_DEBUG_ERROR ("EIR = 0 for a 2R3C policer (rfc: %u)", cfg->rfc);
293       return (EINVAL);
294     }
295
296   if (cfg->rb.kbps.eir_kbps && (cfg->rfc < QOS_POLICER_TYPE_2R3C_RFC_2698))
297     {
298       QOS_DEBUG_ERROR ("EIR: %u kbps for a 1-rate policer (rfc: %u)",
299                        cfg->rb.kbps.eir_kbps, cfg->rfc);
300       return (EINVAL);
301     }
302
303   if ((cfg->rfc == QOS_POLICER_TYPE_1R2C) && cfg->rb.kbps.eb_bytes)
304     {
305       QOS_DEBUG_ERROR ("For a 1R1B policer, EB burst cannot be > 0");
306       return (EINVAL);
307     }
308
309   return (0);
310 }
311
312 static void
313 qos_convert_value_to_exp_mant_fmt (u64 value, u16 max_exp_value,
314                                    u16 max_mant_value, qos_round_type_en type,
315                                    u8 *exp, u32 *mant)
316 {
317   u64 rnd_value;
318   u64 temp_mant;
319   u8 temp_exp;
320
321   /*
322    * Select the lowest possible exp, and the largest possible mant
323    */
324   temp_exp = 0;
325   temp_mant = value;
326   while (temp_exp <= max_exp_value)
327     {
328       if (temp_mant <= max_mant_value)
329         {
330           break;
331         }
332
333       temp_exp++;
334       rnd_value = 0;
335       (void) qos_pol_round ((u64) value, (u64) (1 << temp_exp), &rnd_value,
336                             type);
337       temp_mant = rnd_value;
338     }
339
340   if (temp_exp > max_exp_value)
341     {
342       /*
343        * CAP mant to its max value, and decrement exp
344        */
345       temp_exp--;
346       temp_mant = max_mant_value;
347     }
348
349   *exp = temp_exp;
350   *mant = (u32) temp_mant;
351
352   QOS_DEBUG_INFO ("value: 0x%llx, mant: %u, exp: %u", value, *mant, *exp);
353   return;
354 }
355
356 static int
357 pol_convert_cfg_rates_to_hw (qos_pol_cfg_params_st *cfg,
358                              qos_pol_hw_params_st *hw)
359 {
360   int rc = 0;
361   u32 cir_hw, eir_hw, hi_mant, hi_rate, cir_rnded, eir_rnded, eir_kbps;
362   u64 numer, denom, rnd_value;
363   u8 exp;
364
365   /*
366    * convert rates to bytes-per-tick (tick is 1ms)
367    * For rate conversion, the denominator is gonna be the same
368    */
369   denom = (u64) ((QOS_POL_TICKS_PER_SEC * 8) / 1000);
370   numer = (u64) (cfg->rb.kbps.cir_kbps);
371   rc = qos_pol_round (numer, denom, &rnd_value, cfg->rnd_type);
372   if (rc != 0)
373     {
374       QOS_DEBUG_ERROR ("Rounding error, rate: %d kbps, rounding_type: %d",
375                        cfg->rb.kbps.cir_kbps, cfg->rnd_type);
376       return (rc);
377     }
378   cir_hw = (u32) rnd_value;
379
380   if (cfg->rb.kbps.cir_kbps && (cir_hw == 0))
381     {
382       /*
383        * After rounding, cir_hw = 0. Bump it up
384        */
385       cir_hw = 1;
386     }
387
388   if (cfg->rfc == QOS_POLICER_TYPE_1R2C)
389     {
390       eir_kbps = 0;
391     }
392   else if (cfg->rfc == QOS_POLICER_TYPE_1R3C_RFC_2697)
393     {
394       eir_kbps = cfg->rb.kbps.cir_kbps;
395     }
396   else if (cfg->rfc == QOS_POLICER_TYPE_2R3C_RFC_4115)
397     {
398       eir_kbps = cfg->rb.kbps.eir_kbps - cfg->rb.kbps.cir_kbps;
399     }
400   else
401     {
402       eir_kbps = cfg->rb.kbps.eir_kbps;
403     }
404
405   numer = (u64) eir_kbps;
406   rc = qos_pol_round (numer, denom, &rnd_value, cfg->rnd_type);
407   if (rc != 0)
408     {
409       QOS_DEBUG_ERROR ("Rounding error, rate: %d kbps, rounding_type: %d",
410                        eir_kbps, cfg->rnd_type);
411       return (rc);
412     }
413   eir_hw = (u32) rnd_value;
414
415   if (eir_kbps && (eir_hw == 0))
416     {
417       /*
418        * After rounding, eir_hw = 0. Bump it up
419        */
420       eir_hw = 1;
421     }
422
423   QOS_DEBUG_INFO ("cir_hw: %u bytes/tick, eir_hw: %u bytes/tick", cir_hw,
424                   eir_hw);
425
426   if (cir_hw > eir_hw)
427     {
428       hi_rate = cir_hw;
429     }
430   else
431     {
432       hi_rate = eir_hw;
433     }
434
435   if ((cir_hw == 0) && (eir_hw == 0))
436     {
437       /*
438        * Both the rates are 0. Use exp = 15, and set the RFC to 4115. Also
439        * set AN = 0
440        */
441       exp = (u8) QOS_POL_RATE_EXP_MAX;
442       hi_mant = 0;
443       hw->rfc = IPE_RFC_RFC4115;
444       hw->allow_negative = 0;
445     }
446   else
447     {
448       qos_convert_value_to_exp_mant_fmt (hi_rate, (u16) QOS_POL_RATE_EXP_MAX,
449                                          (u16) QOS_POL_AVG_RATE_MANT_MAX,
450                                          cfg->rnd_type, &exp, &hi_mant);
451     }
452
453   denom = (1ULL << exp);
454   if (hi_rate == eir_hw)
455     {
456       hw->peak_rate_man = (u16) hi_mant;
457       rc = qos_pol_round ((u64) cir_hw, denom, &rnd_value, cfg->rnd_type);
458       hw->avg_rate_man = (u16) rnd_value;
459     }
460   else
461     {
462       hw->avg_rate_man = (u16) hi_mant;
463       rc = qos_pol_round ((u64) eir_hw, denom, &rnd_value, cfg->rnd_type);
464       hw->peak_rate_man = (u16) rnd_value;
465     }
466   if (rc != 0)
467     {
468       QOS_DEBUG_ERROR ("Rounding error");
469       return (rc);
470     }
471   hw->rate_exp = exp;
472
473   if ((hw->avg_rate_man == 0) && (cfg->rb.kbps.cir_kbps))
474     {
475       /*
476        * cir was reduced to 0 during rounding. Bump it up
477        */
478       hw->avg_rate_man = 1;
479       QOS_DEBUG_INFO ("CIR = 0 during rounding. Bump it up to %u "
480                       "bytes/tick",
481                       (hw->avg_rate_man << hw->rate_exp));
482     }
483
484   if ((hw->peak_rate_man == 0) && eir_kbps)
485     {
486       /*
487        * eir was reduced to 0 during rounding. Bump it up
488        */
489       hw->peak_rate_man = 1;
490       QOS_DEBUG_INFO ("EIR = 0 during rounding. Bump it up to %u "
491                       "bytes/tick",
492                       (hw->peak_rate_man << hw->rate_exp));
493     }
494
495   cir_rnded = (hw->avg_rate_man << hw->rate_exp);
496   eir_rnded = (hw->peak_rate_man << hw->rate_exp);
497
498   QOS_DEBUG_INFO ("Configured(rounded) values, cir: %u "
499                   "kbps (mant: %u, exp: %u, rate: %u bytes/tick)",
500                   cfg->rb.kbps.cir_kbps, hw->avg_rate_man, hw->rate_exp,
501                   cir_rnded);
502
503   QOS_DEBUG_INFO ("Configured(rounded) values, eir: %u "
504                   "kbps (mant: %u, exp: %u, rate: %u bytes/tick)",
505                   cfg->rb.kbps.eir_kbps, hw->peak_rate_man, hw->rate_exp,
506                   eir_rnded);
507
508   return (rc);
509 }
510
511 /*****
512  * NAME
513  *   pol_get_bkt_max
514  *
515  * PARAMETERS
516  *  rate_hw    - either the average rate or peak rate
517  *  bkt_max    - bit width in the current bucket or extended bucket
518  *
519  * RETURNS
520  *  u64   - maximum token bytes for the current or extended bucket
521  *
522  * DESCRIPTION
523  *  The current bucket or extended bucket fields are in units of either
524  *  1,2,4,8 bytes based on the average or peak rate respective to current
525  *  or extended bucket.
526  *
527  *  To get the actual maximum number of bytes that can be stored in the
528  *  field, the value must be multiplied by the units of either 1,2,4,8
529  *  bytes based on the rate.
530  *****/
531 u64
532 pol_get_bkt_max (u64 rate_hw, u64 bkt_max)
533 {
534   if (rate_hw <= RATE64)
535     {
536       return (bkt_max - 1);
537     }
538   else if (rate_hw <= RATE128)
539     {
540       return ((bkt_max * RATE_64TO128_UNIT) - RATE_64TO128_UNIT);
541     }
542   else if (rate_hw <= RATE256)
543     {
544       return ((bkt_max * RATE_128TO256_UNIT) - RATE_128TO256_UNIT);
545     }
546   /* rate must be over 256 */
547   return ((bkt_max * RATE_OVER256_UNIT) - RATE_OVER256_UNIT);
548 }
549
550 /*****
551  * NAME
552  *   pol_get_bkt_value
553  *
554  * PARAMETERS
555  *  rate_hw    - either the average rate or peak rate
556  *  byte_value - bytes for this token bucket
557  *
558  * RETURNS
559  *  u64   - unit value for the current or extended bucket field
560  *
561  * DESCRIPTION
562  *  The current bucket or extended bucket fields are in units of either
563  *  1,2,4,8 bytes based on the average or peak rate respective to current
564  *  or extended bucket.
565  *
566  *  To get the units that can be stored in the field, the byte value must
567  *  be divided by the units of either 1,2,4,8 bytes based on the rate.
568  *****/
569 u64
570 pol_get_bkt_value (u64 rate_hw, u64 byte_value)
571 {
572   if (rate_hw <= RATE64)
573     {
574       return (byte_value);
575     }
576   else if (rate_hw <= RATE128)
577     {
578       return (byte_value / RATE_64TO128_UNIT);
579     }
580   else if (rate_hw <= RATE256)
581     {
582       return (byte_value / RATE_128TO256_UNIT);
583     }
584   /* rate must be over 256 */
585   return (byte_value / RATE_OVER256_UNIT);
586 }
587
588 static void
589 pol_rnd_burst_byte_fmt (u64 cfg_burst, u16 max_exp_value, u16 max_mant_value,
590                         u32 max_bkt_value, u32 rate_hw, u8 *exp, u32 *mant,
591                         u32 *bkt_value)
592 {
593   u64 bkt_max = max_bkt_value;
594   u64 bkt_limit_max;
595   u64 rnd_burst;
596   u64 temp_bkt_value;
597
598   bkt_limit_max = ((u64) max_mant_value << (u64) max_exp_value);
599   bkt_max = pol_get_bkt_max (rate_hw, bkt_max);
600   bkt_max = MIN (bkt_max, bkt_limit_max);
601   if (!cfg_burst)
602     {
603       /*
604        * If configured burst = 0, compute the burst to be 100ms at a given
605        * rate. Note that for rate_hw = 0, exp = mant = 0.
606        */
607       cfg_burst = (u64) rate_hw * (u64) QOS_POL_DEF_BURST_BYTE;
608     }
609
610   if (cfg_burst > bkt_max)
611     {
612       QOS_DEBUG_ERROR ("burst 0x%llx bytes is greater than the max. "
613                        "supported value 0x%llx bytes. Capping it to the "
614                        "max",
615                        cfg_burst, bkt_max);
616       cfg_burst = bkt_max;
617     }
618
619   if (cfg_burst < QOS_POL_MIN_BURST_BYTE)
620     {
621       /*
622        * Bump up the burst value ONLY if the cfg_burst is non-zero AND
623        * less than the min. supported value
624        */
625       QOS_DEBUG_INFO ("burst 0x%llx bytes is less than the min "
626                       "supported value %u bytes. Rounding it up to "
627                       "the min",
628                       cfg_burst, QOS_POL_MIN_BURST_BYTE);
629       cfg_burst = QOS_POL_MIN_BURST_BYTE;
630     }
631
632   qos_convert_value_to_exp_mant_fmt (cfg_burst, max_exp_value, max_mant_value,
633                                      QOS_ROUND_TO_DOWN, exp, mant);
634
635   /* Bucket value is based on rate. */
636   rnd_burst = ((u64) (*mant) << (u64) (*exp));
637   temp_bkt_value = pol_get_bkt_value (rate_hw, rnd_burst);
638   *bkt_value = (u32) temp_bkt_value;
639 }
640
641 static int
642 pol_convert_cfg_burst_to_hw (qos_pol_cfg_params_st *cfg,
643                              qos_pol_hw_params_st *hw)
644 {
645   u8 temp_exp;
646   u32 temp_mant, rate_hw;
647   u64 eb_bytes;
648   u32 bkt_value;
649
650   /*
651    * compute Committed Burst
652    */
653   QOS_DEBUG_INFO ("Compute commit burst ...");
654   rate_hw = (hw->avg_rate_man) << (hw->rate_exp);
655   pol_rnd_burst_byte_fmt (
656     cfg->rb.kbps.cb_bytes, (u16) QOS_POL_COMM_BKT_LIMIT_EXP_MAX,
657     (u16) QOS_POL_COMM_BKT_LIMIT_MANT_MAX, (u32) QOS_POL_COMM_BKT_MAX, rate_hw,
658     &temp_exp, &temp_mant, &bkt_value);
659   QOS_DEBUG_INFO ("Committed burst, burst_limit: 0x%llx mant : %u, "
660                   "exp: %u, rnded: 0x%llx cb:%u bytes",
661                   cfg->rb.kbps.cb_bytes, temp_mant, temp_exp,
662                   ((u64) temp_mant << (u64) temp_exp), bkt_value);
663
664   hw->comm_bkt_limit_exp = temp_exp;
665   hw->comm_bkt_limit_man = (u8) temp_mant;
666   hw->comm_bkt = bkt_value;
667
668   /*
669    * compute Exceed Burst
670    */
671   QOS_DEBUG_INFO ("Compute exceed burst ...");
672
673   if (cfg->rfc == QOS_POLICER_TYPE_1R2C)
674     {
675       /*
676        * For 1R2C, hw uses 2R3C (RFC-4115). As such, the Exceed Bucket
677        * params are set to 0. Recommendation is to use EB_exp = max_exp (=15)
678        * and EB_mant = 0
679        */
680       hw->extd_bkt_limit_exp = (u8) QOS_POL_EXTD_BKT_LIMIT_EXP_MAX;
681       hw->extd_bkt_limit_man = 0;
682       QOS_DEBUG_INFO (
683         "Excess burst, burst: 0x%llx mant: %u, "
684         "exp: %u, rnded: 0x%llx bytes",
685         cfg->rb.kbps.eb_bytes, hw->extd_bkt_limit_man, hw->extd_bkt_limit_exp,
686         ((u64) hw->extd_bkt_limit_man << (u64) hw->extd_bkt_limit_exp));
687       return (0);
688     }
689
690   if (cfg->rfc == QOS_POLICER_TYPE_1R3C_RFC_2697)
691     {
692       eb_bytes = cfg->rb.kbps.cb_bytes + cfg->rb.kbps.eb_bytes;
693     }
694   else if (cfg->rfc == QOS_POLICER_TYPE_2R3C_RFC_4115)
695     {
696       eb_bytes = cfg->rb.kbps.eb_bytes - cfg->rb.kbps.cb_bytes;
697     }
698   else
699     {
700       eb_bytes = cfg->rb.kbps.eb_bytes;
701     }
702
703   rate_hw = (hw->peak_rate_man) << (hw->rate_exp);
704   pol_rnd_burst_byte_fmt (eb_bytes, (u16) QOS_POL_EXTD_BKT_LIMIT_EXP_MAX,
705                           (u16) QOS_POL_EXTD_BKT_LIMIT_MANT_MAX,
706                           (u32) QOS_POL_EXTD_BKT_MAX, rate_hw, &temp_exp,
707                           &temp_mant, &bkt_value);
708
709   QOS_DEBUG_INFO ("Excess burst, burst_limit: 0x%llx mant: %u, "
710                   "exp: %u, rnded: 0x%llx eb:%u bytes",
711                   cfg->rb.kbps.eb_bytes, temp_mant, temp_exp,
712                   ((u64) temp_mant << (u64) temp_exp), bkt_value);
713
714   hw->extd_bkt_limit_exp = (u8) temp_exp;
715   hw->extd_bkt_limit_man = (u8) temp_mant;
716   hw->extd_bkt = bkt_value;
717
718   return (0);
719 }
720
721
722 /*
723  * Input: configured parameter values in 'cfg'.
724  * Output: h/w programmable parameter values in 'hw'.
725  * Return: success or failure code.
726  */
727 static int
728 pol_convert_cfg_to_hw_params (qos_pol_cfg_params_st *cfg,
729                               qos_pol_hw_params_st *hw)
730 {
731   int rc = 0;
732
733   /*
734    * clear the hw_params
735    */
736   clib_memset (hw, 0, sizeof (qos_pol_hw_params_st));
737
738   hw->allow_negative = QOS_POL_ALLOW_NEGATIVE;
739
740   if ((cfg->rfc == QOS_POLICER_TYPE_1R2C) ||
741       (cfg->rfc == QOS_POLICER_TYPE_2R3C_RFC_4115))
742     {
743       hw->rfc = IPE_RFC_RFC4115;
744     }
745   else if (cfg->rfc == QOS_POLICER_TYPE_1R3C_RFC_2697)
746     {
747       hw->rfc = IPE_RFC_RFC2697;
748     }
749   else if (cfg->rfc == QOS_POLICER_TYPE_2R3C_RFC_2698)
750     {
751       hw->rfc = IPE_RFC_RFC2698;
752     }
753   else if (cfg->rfc == QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
754     {
755       hw->rfc = IPE_RFC_MEF5CF1;
756     }
757   else
758     {
759       QOS_DEBUG_ERROR ("Invalid RFC type %d\n", cfg->rfc);
760       return (EINVAL);
761     }
762
763   rc = pol_convert_cfg_rates_to_hw (cfg, hw);
764   if (rc != 0)
765     {
766       QOS_DEBUG_ERROR ("Unable to convert config rates to hw. Error: %d", rc);
767       return (rc);
768     }
769
770   rc = pol_convert_cfg_burst_to_hw (cfg, hw);
771   if (rc != 0)
772     {
773       QOS_DEBUG_ERROR ("Unable to convert config burst to hw. Error: %d", rc);
774       return (rc);
775     }
776
777   return 0;
778 }
779
780 u32
781 qos_convert_pps_to_kbps (u32 rate_pps)
782 {
783   u64 numer, rnd_value = 0;
784
785   numer = (u64) ((u64) rate_pps * (u64) QOS_POLICER_FIXED_PKT_SIZE * 8LL);
786   (void) qos_pol_round (numer, 1000LL, &rnd_value, QOS_ROUND_TO_CLOSEST);
787
788   return ((u32) rnd_value);
789 }
790
791 u32
792 qos_convert_burst_ms_to_bytes (u32 burst_ms, u32 rate_kbps)
793 {
794   u64 numer, rnd_value = 0;
795
796   numer = (u64) ((u64) burst_ms * (u64) rate_kbps);
797
798   (void) qos_pol_round (numer, 8LL, &rnd_value, QOS_ROUND_TO_CLOSEST);
799
800   return ((u32) rnd_value);
801 }
802
803
804 /*
805  * Input: configured parameters in 'cfg'.
806  * Output: h/w parameters are returned in 'hw',
807  * Return: Status, success or failure code.
808  */
809 int
810 pol_compute_hw_params (qos_pol_cfg_params_st *cfg, qos_pol_hw_params_st *hw)
811 {
812   int rc = 0;
813
814   if (!cfg || !hw)
815     {
816       QOS_DEBUG_ERROR ("Illegal parameters");
817       return (-1);
818     }
819
820   /*
821    * Validate the police config params being presented to RM
822    */
823   rc = pol_validate_cfg_params (cfg);
824   if (rc != 0)
825     {
826       QOS_DEBUG_ERROR ("Config parameter validation failed. Error: %d", rc);
827       return (-1);
828     }
829
830   /*
831    * first round configured values to h/w supported values. This func
832    * also determines whether 'tick' or 'byte' format
833    */
834   rc = pol_convert_cfg_to_hw_params (cfg, hw);
835   if (rc != 0)
836     {
837       QOS_DEBUG_ERROR ("Unable to convert config params to hw params. "
838                        "Error: %d",
839                        rc);
840       return (-1);
841     }
842
843   return 0;
844 }
845
846 /*
847  * Return the number of hardware TSC timer ticks per second for the dataplane.
848  * This is approximately, but not exactly, the clock speed.
849  */
850 static u64
851 get_tsc_hz (void)
852 {
853   f64 cpu_freq;
854
855   cpu_freq = os_cpu_clock_frequency ();
856   return (u64) cpu_freq;
857 }
858
859 /*
860  * Convert rates into bytes_per_period and scale.
861  * Return 0 if ok or 1 if error.
862  */
863 static int
864 compute_policer_params (u64 hz,       /* CPU speed in clocks per second */
865                         u64 cir_rate, /* in bytes per second */
866                         u64 pir_rate, /* in bytes per second */
867                         u32 *current_limit,  /* in bytes, output may scale
868                                               * the input
869                                               */
870                         u32 *extended_limit, /* in bytes, output may scale
871                                               * the input
872                                               */
873                         u32 *cir_bytes_per_period, u32 *pir_bytes_per_period,
874                         u32 *scale)
875 {
876   double period;
877   double internal_cir_bytes_per_period;
878   double internal_pir_bytes_per_period;
879   u32 max;
880   u32 scale_shift;
881   u32 scale_amount;
882   u32 __attribute__ ((unused)) orig_current_limit = *current_limit;
883
884   /*
885    * Compute period. For 1Ghz-to-8Ghz CPUs, the period will be in
886    * the range of 16 to 116 usec.
887    */
888   period = ((double) hz) / ((double) POLICER_TICKS_PER_PERIOD);
889
890   /* Determine bytes per period for each rate */
891   internal_cir_bytes_per_period = (double) cir_rate / period;
892   internal_pir_bytes_per_period = (double) pir_rate / period;
893
894   /*
895    * Scale if possible. Scaling helps rate accuracy, but is constrained
896    * by the scaled rates and limits fitting in 32-bits.
897    * In addition, we need to insure the scaled rate is no larger than
898    * 2^22 tokens per period. This allows the dataplane to ignore overflow
899    * in the tokens-per-period multiplication since it could only
900    * happen if the policer were idle for more than a year.
901    * This is not really a constraint because 100Gbps at 1Ghz is only
902    * 1.6M tokens per period.
903    */
904 #define MAX_RATE_SHIFT 10
905   max = MAX (*current_limit, *extended_limit);
906   max = MAX (max, (u32) internal_cir_bytes_per_period << MAX_RATE_SHIFT);
907   max = MAX (max, (u32) internal_pir_bytes_per_period << MAX_RATE_SHIFT);
908   scale_shift = __builtin_clz (max);
909
910   scale_amount = 1 << scale_shift;
911   *scale = scale_shift;
912
913   /* Scale the limits */
914   *current_limit = *current_limit << scale_shift;
915   *extended_limit = *extended_limit << scale_shift;
916
917   /* Scale the rates */
918   internal_cir_bytes_per_period =
919     internal_cir_bytes_per_period * ((double) scale_amount);
920   internal_pir_bytes_per_period =
921     internal_pir_bytes_per_period * ((double) scale_amount);
922
923   /*
924    * Make sure the new rates are reasonable
925    * Only needed for very low rates with large bursts
926    */
927   if (internal_cir_bytes_per_period < 1.0)
928     {
929       internal_cir_bytes_per_period = 1.0;
930     }
931   if (internal_pir_bytes_per_period < 1.0)
932     {
933       internal_pir_bytes_per_period = 1.0;
934     }
935
936   *cir_bytes_per_period = (u32) internal_cir_bytes_per_period;
937   *pir_bytes_per_period = (u32) internal_pir_bytes_per_period;
938
939   return 0;
940 }
941
942
943 /*
944  * Input: configured parameters in 'cfg'.
945  * Output: h/w parameters are returned in 'hw',
946  * Return: Status, success or failure code.
947  */
948 int
949 x86_pol_compute_hw_params (qos_pol_cfg_params_st *cfg, policer_t *hw)
950 {
951   const int BYTES_PER_KBIT = (1000 / 8);
952   u64 hz;
953   u32 cap;
954
955   if (!cfg || !hw)
956     {
957       QOS_DEBUG_ERROR ("Illegal parameters");
958       return (-1);
959     }
960
961   hz = get_tsc_hz ();
962   hw->last_update_time = 0;
963
964   /*
965    * Cap the bursts to 32-bits. This allows up to almost one second of
966    * burst on a 40GE interface, which should be fine for x86.
967    */
968   cap =
969     (cfg->rb.kbps.cb_bytes > 0xFFFFFFFF) ? 0xFFFFFFFF : cfg->rb.kbps.cb_bytes;
970   hw->current_limit = cap;
971   cap =
972     (cfg->rb.kbps.eb_bytes > 0xFFFFFFFF) ? 0xFFFFFFFF : cfg->rb.kbps.eb_bytes;
973   hw->extended_limit = cap;
974
975   if ((cfg->rb.kbps.cir_kbps == 0) && (cfg->rb.kbps.cb_bytes == 0)
976       && (cfg->rb.kbps.eb_bytes == 0))
977     {
978       /* This is a uninitialized, always-violate policer */
979       hw->single_rate = 1;
980       hw->cir_tokens_per_period = 0;
981       return 0;
982     }
983
984   if ((cfg->rfc == QOS_POLICER_TYPE_1R2C) ||
985       (cfg->rfc == QOS_POLICER_TYPE_1R3C_RFC_2697))
986     {
987       /* Single-rate policer */
988       hw->single_rate = 1;
989
990       if ((cfg->rfc == QOS_POLICER_TYPE_1R2C) && cfg->rb.kbps.eb_bytes)
991         {
992           QOS_DEBUG_ERROR ("Policer parameter validation failed -- 1R2C.");
993           return (-1);
994         }
995
996       if ((cfg->rb.kbps.cir_kbps == 0) ||
997           (cfg->rb.kbps.eir_kbps != 0) ||
998           ((cfg->rb.kbps.cb_bytes == 0) && (cfg->rb.kbps.eb_bytes == 0)))
999         {
1000           QOS_DEBUG_ERROR ("Policer parameter validation failed -- 1R.");
1001           return (-1);
1002         }
1003
1004       if (compute_policer_params (hz,
1005                                   (u64) cfg->rb.kbps.cir_kbps *
1006                                   BYTES_PER_KBIT, 0, &hw->current_limit,
1007                                   &hw->extended_limit,
1008                                   &hw->cir_tokens_per_period,
1009                                   &hw->pir_tokens_per_period, &hw->scale))
1010         {
1011           QOS_DEBUG_ERROR ("Policer parameter computation failed.");
1012           return (-1);
1013         }
1014
1015     }
1016   else if ((cfg->rfc == QOS_POLICER_TYPE_2R3C_RFC_2698) ||
1017            (cfg->rfc == QOS_POLICER_TYPE_2R3C_RFC_4115))
1018     {
1019       /* Two-rate policer */
1020       if ((cfg->rb.kbps.cir_kbps == 0) || (cfg->rb.kbps.eir_kbps == 0)
1021           || (cfg->rb.kbps.eir_kbps < cfg->rb.kbps.cir_kbps)
1022           || (cfg->rb.kbps.cb_bytes == 0) || (cfg->rb.kbps.eb_bytes == 0))
1023         {
1024           QOS_DEBUG_ERROR ("Config parameter validation failed.");
1025           return (-1);
1026         }
1027
1028       if (compute_policer_params (hz,
1029                                   (u64) cfg->rb.kbps.cir_kbps *
1030                                   BYTES_PER_KBIT,
1031                                   (u64) cfg->rb.kbps.eir_kbps *
1032                                   BYTES_PER_KBIT, &hw->current_limit,
1033                                   &hw->extended_limit,
1034                                   &hw->cir_tokens_per_period,
1035                                   &hw->pir_tokens_per_period, &hw->scale))
1036         {
1037           QOS_DEBUG_ERROR ("Policer parameter computation failed.");
1038           return (-1);
1039         }
1040
1041     }
1042   else
1043     {
1044       QOS_DEBUG_ERROR (
1045         "Config parameter validation failed. RFC not supported");
1046       return (-1);
1047     }
1048
1049   hw->current_bucket = hw->current_limit;
1050   hw->extended_bucket = hw->extended_limit;
1051
1052   return 0;
1053 }
1054
1055 /*
1056  * Input: configured parameters in 'cfg'.
1057  * Output: physical structure is returned in 'phys',
1058  * Return: Status, success or failure code.
1059  */
1060 int
1061 pol_logical_2_physical (const qos_pol_cfg_params_st *cfg, policer_t *phys)
1062 {
1063   int rc;
1064   qos_pol_cfg_params_st kbps_cfg;
1065
1066   clib_memset (phys, 0, sizeof (policer_t));
1067   clib_memset (&kbps_cfg, 0, sizeof (qos_pol_cfg_params_st));
1068
1069   if (!cfg)
1070     {
1071       QOS_DEBUG_ERROR ("Illegal parameters");
1072       return (-1);
1073     }
1074
1075   switch (cfg->rate_type)
1076     {
1077     case QOS_RATE_KBPS:
1078       /* copy all the data into kbps_cfg */
1079       kbps_cfg.rb.kbps.cir_kbps = cfg->rb.kbps.cir_kbps;
1080       kbps_cfg.rb.kbps.eir_kbps = cfg->rb.kbps.eir_kbps;
1081       kbps_cfg.rb.kbps.cb_bytes = cfg->rb.kbps.cb_bytes;
1082       kbps_cfg.rb.kbps.eb_bytes = cfg->rb.kbps.eb_bytes;
1083       break;
1084     case QOS_RATE_PPS:
1085       kbps_cfg.rb.kbps.cir_kbps =
1086         qos_convert_pps_to_kbps (cfg->rb.pps.cir_pps);
1087       kbps_cfg.rb.kbps.eir_kbps =
1088         qos_convert_pps_to_kbps (cfg->rb.pps.eir_pps);
1089       kbps_cfg.rb.kbps.cb_bytes = qos_convert_burst_ms_to_bytes (
1090         (u32) cfg->rb.pps.cb_ms, kbps_cfg.rb.kbps.cir_kbps);
1091       kbps_cfg.rb.kbps.eb_bytes = qos_convert_burst_ms_to_bytes (
1092         (u32) cfg->rb.pps.eb_ms, kbps_cfg.rb.kbps.eir_kbps);
1093       break;
1094     default:
1095       QOS_DEBUG_ERROR ("Illegal rate type");
1096       return (-1);
1097     }
1098
1099   /* rate type is now converted to kbps */
1100   kbps_cfg.rate_type = QOS_RATE_KBPS;
1101   kbps_cfg.rnd_type = cfg->rnd_type;
1102   kbps_cfg.rfc = cfg->rfc;
1103
1104   phys->action[POLICE_CONFORM] = cfg->conform_action.action_type;
1105   phys->mark_dscp[POLICE_CONFORM] = cfg->conform_action.dscp;
1106   phys->action[POLICE_EXCEED] = cfg->exceed_action.action_type;
1107   phys->mark_dscp[POLICE_EXCEED] = cfg->exceed_action.dscp;
1108   phys->action[POLICE_VIOLATE] = cfg->violate_action.action_type;
1109   phys->mark_dscp[POLICE_VIOLATE] = cfg->violate_action.dscp;
1110
1111   phys->color_aware = cfg->color_aware;
1112
1113   /* convert logical into hw params which involves qos calculations */
1114   rc = x86_pol_compute_hw_params (&kbps_cfg, phys);
1115   if (rc == -1)
1116     {
1117       QOS_DEBUG_ERROR ("Unable to compute hw param. Error: %d", rc);
1118       return (rc);
1119     }
1120
1121   /* for debugging purposes, the bucket token values can be overwritten */
1122   if (cfg->overwrite_bucket)
1123     {
1124       phys->current_bucket = cfg->current_bucket;
1125       phys->extended_bucket = cfg->extended_bucket;
1126     }
1127
1128   return 0;
1129 }
1130
1131 static void
1132 qos_convert_pol_bucket_to_hw_fmt (policer_t *bkt, qos_pol_hw_params_st *hw_fmt)
1133 {
1134   clib_memset (hw_fmt, 0, sizeof (qos_pol_hw_params_st));
1135 }
1136
1137 /*
1138  * Input: h/w programmable parameter values in 'hw'
1139  * Output: configured parameter values in 'cfg'
1140  * Return: Status, success or failure code.
1141  */
1142 static int
1143 pol_convert_hw_to_cfg_params (qos_pol_hw_params_st *hw,
1144                               qos_pol_cfg_params_st *cfg)
1145 {
1146   u64 temp_rate;
1147
1148   if ((hw == NULL) || (cfg == NULL))
1149     {
1150       return EINVAL;
1151     }
1152
1153   if ((hw->rfc == IPE_RFC_RFC4115) &&
1154       (hw->peak_rate_man << hw->rate_exp) == 0 && !(hw->extd_bkt_limit_man))
1155     {
1156       /*
1157        * For a 1R2C, we set EIR = 0, EB = 0
1158        */
1159       cfg->rfc = QOS_POLICER_TYPE_1R2C;
1160     }
1161   else if (hw->rfc == IPE_RFC_RFC2697)
1162     {
1163       cfg->rfc = QOS_POLICER_TYPE_1R3C_RFC_2697;
1164     }
1165   else if (hw->rfc == IPE_RFC_RFC2698)
1166     {
1167       cfg->rfc = QOS_POLICER_TYPE_2R3C_RFC_2698;
1168     }
1169   else if (hw->rfc == IPE_RFC_RFC4115)
1170     {
1171       cfg->rfc = QOS_POLICER_TYPE_2R3C_RFC_4115;
1172     }
1173   else if (hw->rfc == IPE_RFC_MEF5CF1)
1174     {
1175       cfg->rfc = QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
1176     }
1177   else
1178     {
1179       return EINVAL;
1180     }
1181
1182   temp_rate =
1183     (((u64) hw->avg_rate_man << hw->rate_exp) * 8LL * QOS_POL_TICKS_PER_SEC) /
1184     1000;
1185   cfg->rb.kbps.cir_kbps = (u32) temp_rate;
1186
1187   temp_rate =
1188     (((u64) hw->peak_rate_man << hw->rate_exp) * 8LL * QOS_POL_TICKS_PER_SEC) /
1189     1000;
1190   cfg->rb.kbps.eir_kbps = (u32) temp_rate;
1191
1192   cfg->rb.kbps.cb_bytes = ((u64) hw->comm_bkt_limit_man <<
1193                            (u64) hw->comm_bkt_limit_exp);
1194   cfg->rb.kbps.eb_bytes = ((u64) hw->extd_bkt_limit_man <<
1195                            (u64) hw->extd_bkt_limit_exp);
1196
1197   if (cfg->rfc == QOS_POLICER_TYPE_1R3C_RFC_2697)
1198     {
1199       /*
1200        * For 1R3C in the hardware, EB = sum(CB, EB). Also, EIR = CIR. Restore
1201        * values such that the configured params don't reflect this adjustment
1202        */
1203       cfg->rb.kbps.eb_bytes = (cfg->rb.kbps.eb_bytes - cfg->rb.kbps.cb_bytes);
1204       cfg->rb.kbps.eir_kbps = 0;
1205     }
1206   else if (cfg->rfc == QOS_POLICER_TYPE_2R3C_RFC_4115)
1207     {
1208       /*
1209        * For 4115 in the hardware is excess rate and burst, but EA provides
1210        * peak-rate, so adjust it to be eir
1211        */
1212       cfg->rb.kbps.eir_kbps += cfg->rb.kbps.cir_kbps;
1213       cfg->rb.kbps.eb_bytes += cfg->rb.kbps.cb_bytes;
1214     }
1215   /* h/w conversion to cfg is in kbps */
1216   cfg->rate_type = QOS_RATE_KBPS;
1217   cfg->overwrite_bucket = 0;
1218   cfg->current_bucket = hw->comm_bkt;
1219   cfg->extended_bucket = hw->extd_bkt;
1220
1221   QOS_DEBUG_INFO ("configured params, cir: %u kbps, eir: %u kbps, cb "
1222                   "burst: 0x%llx bytes, eb burst: 0x%llx bytes",
1223                   cfg->rb.kbps.cir_kbps, cfg->rb.kbps.eir_kbps,
1224                   cfg->rb.kbps.cb_bytes, cfg->rb.kbps.eb_bytes);
1225
1226   return 0;
1227 }
1228
1229 u32
1230 qos_convert_kbps_to_pps (u32 rate_kbps)
1231 {
1232   u64 numer, denom, rnd_value = 0;
1233
1234   numer = (u64) ((u64) rate_kbps * 1000LL);
1235   denom = (u64) ((u64) QOS_POLICER_FIXED_PKT_SIZE * 8LL);
1236
1237   (void) qos_pol_round (numer, denom, &rnd_value, QOS_ROUND_TO_CLOSEST);
1238
1239   return ((u32) rnd_value);
1240 }
1241
1242 u32
1243 qos_convert_burst_bytes_to_ms (u64 burst_bytes, u32 rate_kbps)
1244 {
1245   u64 numer, denom, rnd_value = 0;
1246
1247   numer = burst_bytes * 8LL;
1248   denom = (u64) rate_kbps;
1249
1250   (void) qos_pol_round (numer, denom, &rnd_value, QOS_ROUND_TO_CLOSEST);
1251
1252   return ((u32) rnd_value);
1253 }
1254
1255 /*
1256  * Input: physical structure in 'phys', rate_type in cfg
1257  * Output: configured parameters in 'cfg'.
1258  * Return: Status, success or failure code.
1259  */
1260 int
1261 pol_physical_2_logical (policer_t *phys, qos_pol_cfg_params_st *cfg)
1262 {
1263   int rc;
1264   qos_pol_hw_params_st pol_hw;
1265   qos_pol_cfg_params_st kbps_cfg;
1266
1267   clib_memset (&pol_hw, 0, sizeof (qos_pol_hw_params_st));
1268   clib_memset (&kbps_cfg, 0, sizeof (qos_pol_cfg_params_st));
1269
1270   if (!phys)
1271     {
1272       QOS_DEBUG_ERROR ("Illegal parameters");
1273       return (-1);
1274     }
1275
1276   qos_convert_pol_bucket_to_hw_fmt (phys, &pol_hw);
1277
1278   rc = pol_convert_hw_to_cfg_params (&pol_hw, &kbps_cfg);
1279   if (rc != 0)
1280     {
1281       QOS_DEBUG_ERROR ("Unable to convert hw params to config params. "
1282                        "Error: %d",
1283                        rc);
1284       return (-1);
1285     }
1286
1287   /* check what rate type is required */
1288   switch (cfg->rate_type)
1289     {
1290     case QOS_RATE_KBPS:
1291       /* copy all the data into kbps_cfg */
1292       cfg->rb.kbps.cir_kbps = kbps_cfg.rb.kbps.cir_kbps;
1293       cfg->rb.kbps.eir_kbps = kbps_cfg.rb.kbps.eir_kbps;
1294       cfg->rb.kbps.cb_bytes = kbps_cfg.rb.kbps.cb_bytes;
1295       cfg->rb.kbps.eb_bytes = kbps_cfg.rb.kbps.eb_bytes;
1296       break;
1297     case QOS_RATE_PPS:
1298       cfg->rb.pps.cir_pps =
1299         qos_convert_kbps_to_pps (kbps_cfg.rb.kbps.cir_kbps);
1300       cfg->rb.pps.eir_pps =
1301         qos_convert_kbps_to_pps (kbps_cfg.rb.kbps.eir_kbps);
1302       cfg->rb.pps.cb_ms = qos_convert_burst_bytes_to_ms (
1303         kbps_cfg.rb.kbps.cb_bytes, kbps_cfg.rb.kbps.cir_kbps);
1304       cfg->rb.pps.eb_ms = qos_convert_burst_bytes_to_ms (
1305         kbps_cfg.rb.kbps.eb_bytes, kbps_cfg.rb.kbps.eir_kbps);
1306       break;
1307     default:
1308       QOS_DEBUG_ERROR ("Illegal rate type");
1309       return (-1);
1310     }
1311
1312   /* cfg->rate_type remains what it was */
1313   cfg->rnd_type = kbps_cfg.rnd_type;
1314   cfg->rfc = kbps_cfg.rfc;
1315   cfg->overwrite_bucket = kbps_cfg.overwrite_bucket;
1316   cfg->current_bucket = kbps_cfg.current_bucket;
1317   cfg->extended_bucket = kbps_cfg.extended_bucket;
1318
1319   return 0;
1320 }
1321
1322 /*
1323  * fd.io coding-style-patch-verification: ON
1324  *
1325  * Local Variables:
1326  * eval: (c-set-style "gnu")
1327  * End:
1328  */