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