FD.io VPP  v18.11-rc0-18-g2a3fb1a
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/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 accomodated
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
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  {
227  *rounded_value = ((numerator + (denominator >> 1)) / denominator);
228  break;
229 
231  *rounded_value = (numerator / denominator);
232  if ((*rounded_value * denominator) < numerator)
233  {
234  *rounded_value += 1;
235  }
236  break;
237 
239  *rounded_value = (numerator / denominator);
240  break;
241 
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
255 {
256  u64 numer, denom, rnd_value;
257  u32 cir_hw, eir_hw;
258  int rc = 0;
259 
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,
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,
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,
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,
311  SSE2_QOS_TR_ERR (SSE2_QOS_TP_ERR_85, eir_hw,
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) &&
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 &&
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
354  u16 max_exp_value,
355  u16 max_mant_value,
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
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,
416  if (rc != 0)
417  {
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,
454  if (rc != 0)
455  {
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  */
491  hi_mant = 0;
492  hw->rfc = IPE_RFC_RFC4115;
493  hw->allow_negative = 0;
494  }
495  else
496  {
499  (u16)
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,
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,
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 averate 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 averate 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
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,
687  cfg_burst = SSE2_QOS_POL_MIN_BURST_BYTE;
688  }
689 
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
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,
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  */
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,
751  return (0);
752  }
753 
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,
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
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 
804 
805  if ((cfg->rfc == SSE2_QOS_POLICER_TYPE_1R2C) ||
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  }
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
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 *
861  (void) sse2_qos_pol_round (numer, 1000LL, &rnd_value,
863 
864  return ((u32) rnd_value);
865 }
866 
867 u32
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,
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
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
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 contrained
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
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) ||
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  {
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) ||
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  {
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
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 =
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 
1222  phys->mark_dscp[POLICE_EXCEED] = cfg->exceed_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
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
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  */
1321  }
1322  else if (hw->rfc == IPE_RFC_RFC2697)
1323  {
1325  }
1326  else if (hw->rfc == IPE_RFC_RFC2698)
1327  {
1329  }
1330  else if (hw->rfc == IPE_RFC_RFC4115)
1331  {
1333  }
1334  else if (hw->rfc == IPE_RFC_MEF5CF1)
1335  {
1337  }
1338  else
1339  {
1340  return EINVAL;
1341  }
1342 
1343  temp_rate = (((u64) hw->avg_rate_man << hw->rate_exp) * 8LL *
1345  cfg->rb.kbps.cir_kbps = (u32) temp_rate;
1346 
1347  temp_rate = (((u64) hw->peak_rate_man << hw->rate_exp) * 8LL *
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 
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 */
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
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,
1405 
1406  return ((u32) rnd_value);
1407 }
1408 
1409 u32
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,
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
1434 {
1435  int rc;
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  */
static void sse2_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:642
static void sse2_qos_convert_pol_bucket_to_hw_fmt(policer_read_response_type_st *bkt, sse2_qos_pol_hw_params_st *hw_fmt)
Definition: xlate.c:1279
#define MAX(x, y)
Definition: xlate.c:49
sse2_qos_pol_action_params_st conform_action
Definition: xlate.h:151
#define SSE2_QOS_POL_AVG_RATE_MANT_MAX
Definition: xlate.c:155
#define SSE2_QOS_POL_MIN_BURST_BYTE
Definition: xlate.c:134
unsigned long u64
Definition: types.h:89
#define NULL
Definition: clib.h:55
static int sse2_pol_convert_hw_to_cfg_params(sse2_qos_pol_hw_params_st *hw, sse2_qos_pol_cfg_params_st *cfg)
Definition: xlate.c:1304
#define RATE256
Definition: xlate.c:202
#define SSE2_QOS_DEBUG_ERROR(msg, args...)
Definition: xlate.c:31
#define SSE2_QOS_DEBUG_INFO(msg, args...)
Definition: xlate.c:34
#define SSE2_QOS_POLICER_FIXED_PKT_SIZE
Definition: xlate.c:120
int x86_pol_compute_hw_params(sse2_qos_pol_cfg_params_st *cfg, policer_read_response_type_st *hw)
Definition: xlate.c:1055
u32 sse2_qos_convert_kbps_to_pps(u32 rate_kbps)
Definition: xlate.c:1393
unsigned char u8
Definition: types.h:56
#define SSE2_QOS_TR_INFO(TpParms...)
Definition: xlate.c:42
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:952
double f64
Definition: types.h:142
#define SSE2_QOS_POL_TICKS_PER_SEC
Definition: xlate.c:123
static int sse2_pol_convert_cfg_burst_to_hw(sse2_qos_pol_cfg_params_st *cfg, sse2_qos_pol_hw_params_st *hw)
Definition: xlate.c:702
#define SSE2_QOS_POL_COMM_BKT_LIMIT_MANT_MAX
Definition: xlate.c:171
unsigned int u32
Definition: types.h:88
static int sse2_pol_convert_cfg_rates_to_hw(sse2_qos_pol_cfg_params_st *cfg, sse2_qos_pol_hw_params_st *hw)
Definition: xlate.c:400
struct sse2_qos_pol_cfg_params_st_::@293::@295 pps
#define IPE_RFC_RFC2697
Definition: xlate.c:112
#define RATE_128TO256_UNIT
Definition: xlate.c:207
int sse2_pol_compute_hw_params(sse2_qos_pol_cfg_params_st *cfg, sse2_qos_pol_hw_params_st *hw)
Definition: xlate.c:890
struct sse2_qos_pol_cfg_params_st_::@293::@294 kbps
#define IPE_RFC_RFC4115
Definition: xlate.c:114
#define SSE2_QOS_POL_EXTD_BKT_LIMIT_MANT_MAX
Definition: xlate.c:183
static void sse2_qos_convert_value_to_exp_mant_fmt(u64 value, u16 max_exp_value, u16 max_mant_value, sse2_qos_round_type_en type, u8 *exp, u32 *mant)
Definition: xlate.c:353
unsigned short u16
Definition: types.h:57
#define IPE_RFC_RFC2698
Definition: xlate.c:113
sse2_qos_pol_action_params_st violate_action
Definition: xlate.h:153
#define SSE2_QOS_POL_COMM_BKT_LIMIT_EXP_MAX
Definition: xlate.c:175
static int sse2_qos_pol_round(u64 numerator, u64 denominator, u64 *rounded_value, sse2_qos_round_type_en round_type)
Definition: xlate.c:211
sse2_qos_pol_action_params_st exceed_action
Definition: xlate.h:152
union sse2_qos_pol_cfg_params_st_::@293 rb
#define MAX_RATE_SHIFT
u64 sse2_pol_get_bkt_max(u64 rate_hw, u64 bkt_max)
Definition: xlate.c:585
u32 sse2_qos_convert_burst_bytes_to_ms(u64 burst_bytes, u32 rate_kbps)
Definition: xlate.c:1410
#define SSE2_QOS_POL_RATE_EXP_MAX
Definition: xlate.c:152
u64 sse2_pol_get_bkt_value(u64 rate_hw, u64 byte_value)
Definition: xlate.c:623
#define SSE2_QOS_POL_PEAK_RATE_MAX
Definition: xlate.c:165
#define SSE2_QOS_TR_ERR(TpParms...)
Definition: xlate.c:38
int sse2_pol_logical_2_physical(sse2_qos_pol_cfg_params_st *cfg, policer_read_response_type_st *phys)
Definition: xlate.c:1171
#define SSE2_QOS_POL_ALLOW_NEGATIVE
Definition: xlate.c:141
#define RATE_OVER256_UNIT
Definition: xlate.c:206
#define RATE_64TO128_UNIT
Definition: xlate.c:208
#define SSE2_QOS_POL_DEF_BURST_BYTE
Definition: xlate.c:128
#define RATE64
Definition: xlate.c:204
static int sse2_pol_convert_cfg_to_hw_params(sse2_qos_pol_cfg_params_st *cfg, sse2_qos_pol_hw_params_st *hw)
Definition: xlate.c:793
#define RATE128
Definition: xlate.c:203
int sse2_pol_physical_2_logical(policer_read_response_type_st *phys, sse2_qos_pol_cfg_params_st *cfg)
Definition: xlate.c:1432
#define SSE2_QOS_POL_AVG_RATE_MAX
Definition: xlate.c:157
u32 sse2_qos_convert_burst_ms_to_bytes(u32 burst_ms, u32 rate_kbps)
Definition: xlate.c:868
static u64 get_tsc_hz(void)
Definition: xlate.c:939
sse2_qos_round_type_en
Definition: xlate.h:43
static int sse2_pol_validate_cfg_params(sse2_qos_pol_cfg_params_st *cfg)
Definition: xlate.c:254
u32 sse2_qos_convert_pps_to_kbps(u32 rate_pps)
Definition: xlate.c:852
#define SSE2_QOS_POL_EXTD_BKT_LIMIT_EXP_MAX
Definition: xlate.c:187
#define IPE_RFC_MEF5CF1
Definition: xlate.c:115
#define SSE2_QOS_POL_EXTD_BKT_MAX
Definition: xlate.c:147
#define POLICER_TICKS_PER_PERIOD
Definition: police.h:58
#define SSE2_QOS_POL_COMM_BKT_MAX
Definition: xlate.c:145
#define MIN(x, y)
Definition: xlate.c:45
f64 os_cpu_clock_frequency(void)
Definition: time.c:143