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