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