FD.io VPP  v16.06
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  ((uint64_t)SSE2_QOS_POL_COMM_BKT_LIMIT_MANT_MAX << \
179  (uint64_t)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  ((uint64_t)SSE2_QOS_POL_EXTD_BKT_LIMIT_MANT_MAX << \
191  (uint64_t)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 cerrno
211 sse2_qos_pol_round (uint64_t numerator,
212  uint64_t denominator,
213  uint64_t *rounded_value,
214  sse2_qos_round_type_en round_type)
215 {
216  cerrno rc = EOK;
217 
218  if (denominator == 0) {
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) {
226  *rounded_value = ((numerator + (denominator >> 1)) / denominator);
227  break;
228 
230  *rounded_value = (numerator / denominator);
231  if ((*rounded_value * denominator) < numerator) {
232  *rounded_value += 1;
233  }
234  break;
235 
237  *rounded_value = (numerator / denominator);
238  break;
239 
241  default:
242  SSE2_QOS_DEBUG_ERROR("Illegal round type");
243  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_60, round_type);
244  rc = EINVAL;
245  break;
246  }
247  return(rc);
248 }
249 
250 
251 static cerrno
253 {
254  uint64_t numer, denom, rnd_value;
255  uint32_t cir_hw, eir_hw;
256  cerrno rc = EOK;
257 
259  (cfg->rb.kbps.eir_kbps < cfg->rb.kbps.cir_kbps)) {
260  SSE2_QOS_DEBUG_ERROR("CIR (%u kbps) is greater than PIR (%u kbps)",
261  cfg->rb.kbps.cir_kbps, cfg->rb.kbps.eir_kbps);
262  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_39, cfg->rb.kbps.cir_kbps,
263  cfg->rb.kbps.eir_kbps);
264  return(EINVAL);
265  }
266 
267  /*
268  * convert rates to bytes-per-tick
269  */
270  numer = (uint64_t)(cfg->rb.kbps.cir_kbps);
271  denom = (uint64_t)(8 * SSE2_QOS_POL_TICKS_PER_SEC) / 1000;
272  rc = sse2_qos_pol_round(numer, denom, &rnd_value,
274  if (CERR_IS_NOTOK(rc)) {
275  SSE2_QOS_DEBUG_ERROR("Unable to convert CIR to bytes/tick format");
276  // Error traced
277  return(rc);
278  }
279  cir_hw = (uint32_t)rnd_value;
280 
281  numer = (uint64_t)(cfg->rb.kbps.eir_kbps);
282  rc = sse2_qos_pol_round(numer, denom, &rnd_value,
284  if (CERR_IS_NOTOK(rc)) {
285  SSE2_QOS_DEBUG_ERROR("Unable to convert EIR to bytes/tick format");
286  // Error traced
287  return(rc);
288  }
289  eir_hw = (uint32_t)rnd_value;
290 
291  if (cir_hw > SSE2_QOS_POL_AVG_RATE_MAX) {
292  SSE2_QOS_DEBUG_ERROR("hw cir (%u bytes/tick) is greater than the "
293  "max supported value (%u)", cir_hw,
295  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_84, cir_hw,
297  return(EINVAL);
298  }
299 
300  if (eir_hw > SSE2_QOS_POL_PEAK_RATE_MAX) {
301  SSE2_QOS_DEBUG_ERROR("hw eir (%u bytes/tick) is greater than the "
302  "max supported value (%u). Capping it to the max. "
303  "supported value", eir_hw, SSE2_QOS_POL_PEAK_RATE_MAX);
304  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_85,
306  return(EINVAL);
307  }
308  /*
309  * CIR = 0, with bc != 0 is not allowed
310  */
311  if ((cfg->rb.kbps.cir_kbps == 0) && cfg->rb.kbps.cb_bytes) {
312  SSE2_QOS_DEBUG_ERROR("CIR = 0 with bc != 0");
313  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_55);
314  return(EINVAL);
315  }
316 
317  if ((cfg->rb.kbps.eir_kbps == 0) &&
319  SSE2_QOS_DEBUG_ERROR("EIR = 0 for a 2R3C policer (rfc: %u)", cfg->rfc);
320  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_23, cfg->rb.kbps.eir_kbps, cfg->rfc);
321  return(EINVAL);
322  }
323 
324  if (cfg->rb.kbps.eir_kbps &&
326  SSE2_QOS_DEBUG_ERROR("EIR: %u kbps for a 1-rate policer (rfc: %u)",
327  cfg->rb.kbps.eir_kbps, cfg->rfc);
328  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_23, cfg->rb.kbps.eir_kbps, cfg->rfc);
329  return(EINVAL);
330  }
331 
332  if ((cfg->rfc == SSE2_QOS_POLICER_TYPE_1R2C) && cfg->rb.kbps.eb_bytes) {
333  SSE2_QOS_DEBUG_ERROR("For a 1R1B policer, EB burst cannot be > 0");
334  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_56);
335  return(EINVAL);
336  }
337 
338  return(EOK);
339 }
340 
341 static void
343  uint16_t max_exp_value,
344  uint16_t max_mant_value,
346  uint8_t *exp,
347  uint32_t *mant)
348 {
349  uint64_t rnd_value;
350  uint64_t temp_mant;
351  uint8_t temp_exp;
352 
353  /*
354  * Select the lowest possible exp, and the largest possible mant
355  */
356  temp_exp = 0;
357  temp_mant = value;
358  while (temp_exp <= max_exp_value) {
359  if (temp_mant <= max_mant_value) {
360  break;
361  }
362 
363  temp_exp++;
364  rnd_value = 0;
365  (void)sse2_qos_pol_round((uint64_t)value, (uint64_t)(1 << temp_exp),
366  &rnd_value, type);
367  temp_mant = rnd_value;
368  }
369 
370  if (temp_exp > max_exp_value) {
371  /*
372  * CAP mant to its max value, and decrement exp
373  */
374  temp_exp--;
375  temp_mant = max_mant_value;
376  }
377 
378  *exp = temp_exp;
379  *mant = (uint32_t)temp_mant;
380 
381  SSE2_QOS_DEBUG_INFO("value: 0x%llx, mant: %u, exp: %u", value, *mant, *exp);
382  return;
383 }
384 
385 static cerrno
388 {
389  cerrno rc = EOK;
390  uint32_t cir_hw, eir_hw, hi_mant, hi_rate, cir_rnded, eir_rnded, eir_kbps;
391  uint64_t numer, denom, rnd_value;
392  uint8_t exp;
393 
394  /*
395  * convert rates to bytes-per-tick (tick is 1ms)
396  * For rate conversion, the denominator is gonna be the same
397  */
398  denom = (uint64_t)((SSE2_QOS_POL_TICKS_PER_SEC * 8) / 1000);
399  numer = (uint64_t)(cfg->rb.kbps.cir_kbps);
400  rc = sse2_qos_pol_round(numer, denom, &rnd_value,
402  if (CERR_IS_NOTOK(rc)) {
403  SSE2_QOS_DEBUG_ERROR("Rounding error, rate: %d kbps, rounding_type: %d",
404  cfg->rb.kbps.cir_kbps, cfg->rnd_type);
405  // Error is traced
406  return(rc);
407  }
408  cir_hw = (uint32_t)rnd_value;
409 
410  if (cfg->rb.kbps.cir_kbps && (cir_hw == 0)) {
411  /*
412  * After rounding, cir_hw = 0. Bump it up
413  */
414  cir_hw = 1;
415  }
416 
417  if (cfg->rfc == SSE2_QOS_POLICER_TYPE_1R2C) {
418  eir_kbps = 0;
419  } else if (cfg->rfc == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697) {
420  eir_kbps = cfg->rb.kbps.cir_kbps;
421  } else if (cfg->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115) {
422  eir_kbps = cfg->rb.kbps.eir_kbps - cfg->rb.kbps.cir_kbps;
423  } else {
424  eir_kbps = cfg->rb.kbps.eir_kbps;
425  }
426 
427  numer = (uint64_t)eir_kbps;
428  rc = sse2_qos_pol_round(numer, denom, &rnd_value,
430  if (CERR_IS_NOTOK(rc)) {
431  SSE2_QOS_DEBUG_ERROR("Rounding error, rate: %d kbps, rounding_type: %d",
432  eir_kbps, cfg->rnd_type);
433  // Error is traced
434  return(rc);
435  }
436  eir_hw = (uint32_t)rnd_value;
437 
438  if (eir_kbps && (eir_hw == 0)) {
439  /*
440  * After rounding, eir_hw = 0. Bump it up
441  */
442  eir_hw = 1;
443  }
444 
445  SSE2_QOS_DEBUG_INFO("cir_hw: %u bytes/tick, eir_hw: %u bytes/tick", cir_hw,
446  eir_hw);
447 
448  if (cir_hw > eir_hw) {
449  hi_rate = cir_hw;
450  } else {
451  hi_rate = eir_hw;
452  }
453 
454  if ((cir_hw == 0) && (eir_hw == 0)) {
455  /*
456  * Both the rates are 0. Use exp = 15, and set the RFC to 4115. Also
457  * set AN = 0
458  */
460  hi_mant = 0;
461  hw->rfc = IPE_RFC_RFC4115;
462  hw->allow_negative = 0;
463  } else {
468  &exp, &hi_mant);
469  }
470 
471  denom = (1 << exp);
472  if (hi_rate == eir_hw) {
473  hw->peak_rate_man = (uint16_t)hi_mant;
474  rc = sse2_qos_pol_round((uint64_t)cir_hw, denom, &rnd_value,
476  hw->avg_rate_man = (uint16_t)rnd_value;
477  } else {
478  hw->avg_rate_man = (uint16_t)hi_mant;
479  rc = sse2_qos_pol_round((uint64_t)eir_hw, denom, &rnd_value,
481  hw->peak_rate_man = (uint16_t)rnd_value;
482  }
483  if (CERR_IS_NOTOK(rc)) {
484  SSE2_QOS_DEBUG_ERROR("Rounding error");
485  // Error is traced
486  return(rc);
487  }
488  hw->rate_exp = exp;
489 
490  if ((hw->avg_rate_man == 0) && (cfg->rb.kbps.cir_kbps)) {
491  /*
492  * cir was reduced to 0 during rounding. Bump it up
493  */
494  hw->avg_rate_man = 1;
495  SSE2_QOS_DEBUG_INFO("CIR = 0 during rounding. Bump it up to %u "
496  "bytes/tick", (hw->avg_rate_man << hw->rate_exp));
497  }
498 
499  if ((hw->peak_rate_man == 0) && eir_kbps) {
500  /*
501  * eir was reduced to 0 during rounding. Bump it up
502  */
503  hw->peak_rate_man = 1;
504  SSE2_QOS_DEBUG_INFO("EIR = 0 during rounding. Bump it up to %u "
505  "bytes/tick", (hw->peak_rate_man << hw->rate_exp));
506  }
507 
508  cir_rnded = (hw->avg_rate_man << hw->rate_exp);
509  eir_rnded = (hw->peak_rate_man << hw->rate_exp);
510 
511  SSE2_QOS_DEBUG_INFO("Configured(rounded) values, cir: %u "
512  "kbps (mant: %u, exp: %u, rate: %u bytes/tick)",
513  cfg->rb.kbps.cir_kbps, hw->avg_rate_man,
514  hw->rate_exp, cir_rnded);
515 
516  SSE2_QOS_DEBUG_INFO("Configured(rounded) values, eir: %u "
517  "kbps (mant: %u, exp: %u, rate: %u bytes/tick)",
518  cfg->rb.kbps.eir_kbps, hw->peak_rate_man,
519  hw->rate_exp, eir_rnded);
520 
521  return(rc);
522 }
523 
524 /*****
525  * NAME
526  * sse2_pol_get_bkt_max
527  *
528  * PARAMETERS
529  * rate_hw - either the averate rate or peak rate
530  * bkt_max - bit width in the current bucket or extended bucket
531  *
532  * RETURNS
533  * uint64_t - maximum token bytes for the current or extended bucket
534  *
535  * DESCRIPTION
536  * The current bucket or extended bucket fields are in units of either
537  * 1,2,4,8 bytes based on the average or peak rate respective to current
538  * or extended bucket.
539  *
540  * To get the actual maximum number of bytes that can be stored in the
541  * field, the value must be multiplied by the units of either 1,2,4,8
542  * bytes based on the rate.
543  *****/
544 uint64_t
545 sse2_pol_get_bkt_max (uint64_t rate_hw, uint64_t bkt_max)
546 {
547  if (rate_hw <= RATE64) {
548  return (bkt_max - 1);
549  } else if (rate_hw <= RATE128) {
550  return ((bkt_max * RATE_64TO128_UNIT) - RATE_64TO128_UNIT);
551  } else if (rate_hw <= RATE256) {
552  return ((bkt_max * RATE_128TO256_UNIT) - RATE_128TO256_UNIT);
553  }
554  /* rate must be over 256 */
555  return ((bkt_max * RATE_OVER256_UNIT) - RATE_OVER256_UNIT);
556 }
557 
558 /*****
559  * NAME
560  * sse2_pol_get_bkt_value
561  *
562  * PARAMETERS
563  * rate_hw - either the averate rate or peak rate
564  * byte_value - bytes for this token bucket
565  *
566  * RETURNS
567  * uint64_t - unit value for the current or extended bucket field
568  *
569  * DESCRIPTION
570  * The current bucket or extended bucket fields are in units of either
571  * 1,2,4,8 bytes based on the average or peak rate respective to current
572  * or extended bucket.
573  *
574  * To get the units that can be stored in the field, the byte value must
575  * be divided by the units of either 1,2,4,8 bytes based on the rate.
576  *****/
577 uint64_t
578 sse2_pol_get_bkt_value (uint64_t rate_hw, uint64_t byte_value)
579 {
580  if (rate_hw <= RATE64) {
581  return (byte_value);
582  } else if (rate_hw <= RATE128) {
583  return (byte_value / RATE_64TO128_UNIT);
584  } else if (rate_hw <= RATE256) {
585  return (byte_value / RATE_128TO256_UNIT);
586  }
587  /* rate must be over 256 */
588  return (byte_value / RATE_OVER256_UNIT);
589 }
590 
591 static void
592 sse2_pol_rnd_burst_byte_fmt (uint64_t cfg_burst,
593  uint16_t max_exp_value,
594  uint16_t max_mant_value,
595  uint32_t max_bkt_value,
596  uint32_t rate_hw,
597  uint8_t *exp,
598  uint32_t *mant,
599  uint32_t *bkt_value)
600 {
601  uint64_t bkt_max=max_bkt_value;
602  uint64_t bkt_limit_max;
603  uint64_t rnd_burst;
604  uint64_t temp_bkt_value;
605 
606  bkt_limit_max = ((uint64_t)max_mant_value<<(uint64_t)max_exp_value);
607  bkt_max = sse2_pol_get_bkt_max(rate_hw, bkt_max);
608  bkt_max=MIN(bkt_max, bkt_limit_max);
609  if (!cfg_burst) {
610  /*
611  * If configured burst = 0, compute the burst to be 100ms at a given
612  * rate. Note that for rate_hw = 0, exp = mant = 0.
613  */
614  cfg_burst = (uint64_t)rate_hw * (uint64_t)SSE2_QOS_POL_DEF_BURST_BYTE;
615  }
616 
617  if (cfg_burst > bkt_max) {
618  SSE2_QOS_DEBUG_ERROR("burst 0x%llx bytes is greater than the max. "
619  "supported value 0x%llx bytes. Capping it to the "
620  "max", cfg_burst, bkt_max);
621  SSE2_QOS_TR_INFO(SSE2_QOS_TP_INFO_38,
622  (uint)cfg_burst, (uint)bkt_max);
623  cfg_burst = bkt_max;
624  }
625 
626  if (cfg_burst < SSE2_QOS_POL_MIN_BURST_BYTE) {
627  /*
628  * Bump up the burst value ONLY if the cfg_burst is non-zero AND
629  * less than the min. supported value
630  */
631  SSE2_QOS_DEBUG_INFO("burst 0x%llx bytes is less than the min "
632  "supported value %u bytes. Rounding it up to "
633  "the min", cfg_burst, SSE2_QOS_POL_MIN_BURST_BYTE);
634  SSE2_QOS_TR_INFO(SSE2_QOS_TP_INFO_39, (uint)cfg_burst,
636  cfg_burst = SSE2_QOS_POL_MIN_BURST_BYTE;
637  }
638 
640  max_exp_value,
641  max_mant_value,
643  exp,
644  mant);
645 
646  /* Bucket value is based on rate. */
647  rnd_burst = ((uint64_t)(*mant) << (uint64_t)(*exp));
648  temp_bkt_value = sse2_pol_get_bkt_value(rate_hw, rnd_burst);
649  *bkt_value = (uint32_t)temp_bkt_value;
650 }
651 
652 static cerrno
655 {
656  uint8_t temp_exp;
657  uint32_t temp_mant, rate_hw;
658  uint64_t eb_bytes;
659  uint32_t bkt_value;
660 
661  /*
662  * compute Committed Burst
663  */
664  SSE2_QOS_DEBUG_INFO("Compute commit burst ...");
665  rate_hw = (hw->avg_rate_man) << (hw->rate_exp);
666  sse2_pol_rnd_burst_byte_fmt(cfg->rb.kbps.cb_bytes,
670  rate_hw, &temp_exp, &temp_mant, &bkt_value);
671  SSE2_QOS_DEBUG_INFO("Committed burst, burst_limit: 0x%llx mant : %u, "
672  "exp: %u, rnded: 0x%llx cb:%u bytes",
673  cfg->rb.kbps.cb_bytes, temp_mant, temp_exp,
674  ((uint64_t)temp_mant << (uint64_t)temp_exp), bkt_value);
675 
676  hw->comm_bkt_limit_exp = temp_exp;
677  hw->comm_bkt_limit_man = (uint8_t)temp_mant;
678  hw->comm_bkt = bkt_value;
679 
680  /*
681  * compute Exceed Burst
682  */
683  SSE2_QOS_DEBUG_INFO("Compute exceed burst ...");
684 
685  if (cfg->rfc == SSE2_QOS_POLICER_TYPE_1R2C) {
686  /*
687  * For 1R2C, hw uses 2R3C (RFC-4115). As such, the Exceed Bucket
688  * params are set to 0. Recommendation is to use EB_exp = max_exp (=15)
689  * and EB_mant = 0
690  */
692  hw->extd_bkt_limit_man = 0;
693  SSE2_QOS_DEBUG_INFO("Excess burst, burst: 0x%llx mant: %u, "
694  "exp: %u, rnded: 0x%llx bytes",
695  cfg->rb.kbps.eb_bytes, hw->extd_bkt_limit_man,
696  hw->extd_bkt_limit_exp,
697  ((uint64_t)hw->extd_bkt_limit_man <<
698  (uint64_t)hw->extd_bkt_limit_exp));
699  SSE2_QOS_TR_INFO(SSE2_QOS_TP_INFO_20, (uint)cfg->rb.kbps.eb_bytes,
701  return(EOK);
702  }
703 
705  eb_bytes = cfg->rb.kbps.cb_bytes + cfg->rb.kbps.eb_bytes;
706  } else if (cfg->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115) {
707  eb_bytes = cfg->rb.kbps.eb_bytes - cfg->rb.kbps.cb_bytes;
708  } else {
709  eb_bytes = cfg->rb.kbps.eb_bytes;
710  }
711 
712  rate_hw = (hw->peak_rate_man) << (hw->rate_exp);
713  sse2_pol_rnd_burst_byte_fmt(eb_bytes,
717  rate_hw, &temp_exp, &temp_mant, &bkt_value);
718 
719  SSE2_QOS_DEBUG_INFO("Excess burst, burst_limit: 0x%llx mant: %u, "
720  "exp: %u, rnded: 0x%llx eb:%u bytes",
721  cfg->rb.kbps.eb_bytes, temp_mant, temp_exp,
722  ((uint64_t)temp_mant << (uint64_t)temp_exp), bkt_value);
723 
724  hw->extd_bkt_limit_exp = (uint8_t)temp_exp;
725  hw->extd_bkt_limit_man = (uint8_t)temp_mant;
726  hw->extd_bkt = bkt_value;
727 
728  return(EOK);
729 }
730 
731 
732 /*
733  * Input: configured parameter values in 'cfg'.
734  * Output: h/w programmable parameter values in 'hw'.
735  * Return: success or failure code.
736  */
737 static cerrno
740 {
741  cerrno rc = EOK;
742 
743  /*
744  * clear the hw_params
745  */
746  memset(hw, 0, sizeof(sse2_qos_pol_hw_params_st));
747 
749 
750  if ((cfg->rfc == SSE2_QOS_POLICER_TYPE_1R2C) ||
752  hw->rfc = IPE_RFC_RFC4115;
753  } else if (cfg->rfc == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697) {
754  hw->rfc = IPE_RFC_RFC2697;
755  } else if (cfg->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698) {
756  hw->rfc = IPE_RFC_RFC2698;
757  } else if (cfg->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1) {
758  hw->rfc = IPE_RFC_MEF5CF1;
759  } else {
760  SSE2_QOS_DEBUG_ERROR("Invalid RFC type %d\n", cfg->rfc);
761  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_61, cfg->rfc);
762  return(EINVAL);
763  }
764 
765  rc = sse2_pol_convert_cfg_rates_to_hw(cfg, hw);
766  if (CERR_IS_NOTOK(rc)) {
767  SSE2_QOS_DEBUG_ERROR("Unable to convert config rates to hw. Error: %d",
768  rc);
769  // Error is traced
770  return(rc);
771  }
772 
773  rc = sse2_pol_convert_cfg_burst_to_hw(cfg, hw);
774  if (CERR_IS_NOTOK(rc)) {
775  SSE2_QOS_DEBUG_ERROR("Unable to convert config burst to hw. Error: %d",
776  rc);
777  // Error is traced
778  return(rc);
779  }
780 
781  return OK_pushHW;
782 }
783 
784 
785 uint32_t
787 {
788  // sse2_qos_ship_inc_counter(SSE2_QOS_SHIP_COUNTER_TYPE_API_CNT,
789  // SSE2_QOS_SHIP_CNT_POL_CONV_PPS_TO_KBPS);
790 
791  uint64_t numer, rnd_value = 0;
792 
793  numer = (uint64_t)((uint64_t)rate_pps *
794  (uint64_t)SSE2_QOS_POLICER_FIXED_PKT_SIZE * 8LL);
795  (void)sse2_qos_pol_round(numer, 1000LL, &rnd_value,
797 
798  return ((uint32_t)rnd_value);
799 }
800 
801 uint32_t
803  uint32_t rate_kbps)
804 {
805  uint64_t numer, rnd_value = 0;
806 
807  //sse2_qos_ship_inc_counter(SSE2_QOS_SHIP_COUNTER_TYPE_API_CNT,
808  // SSE2_QOS_SHIP_CNT_POL_CONV_BURST_MS_TO_BYTES);
809 
810  numer = (uint64_t)((uint64_t)burst_ms * (uint64_t)rate_kbps);
811 
812  (void)sse2_qos_pol_round(numer, 8LL, &rnd_value,
814 
815  return ((uint32_t)rnd_value);
816 }
817 
818 
819 /*
820  * Input: configured parameters in 'cfg'.
821  * Output: h/w parameters are returned in 'hw',
822  * Return: Status, success or failure code.
823  */
827 {
828  cerrno rc = EOK;
829 
830  if (!cfg || !hw) {
831  SSE2_QOS_DEBUG_ERROR("Illegal parameters");
832  return(Not_OK);
833  }
834 
835  /*
836  * Validate the police config params being presented to RM
837  */
839  if (CERR_IS_NOTOK(rc)) {
840  SSE2_QOS_DEBUG_ERROR("Config parameter validation failed. Error: %d",
841  rc);
842  // Error is traced
843  return(Not_OK);
844  }
845 
846  /*
847  * first round configured values to h/w supported values. This func
848  * also determines whether 'tick' or 'byte' format
849  */
850  rc = sse2_pol_convert_cfg_to_hw_params(cfg, hw);
851  if (CERR_IS_NOTOK(rc)) {
852  SSE2_QOS_DEBUG_ERROR("Unable to convert config params to hw params. "
853  "Error: %d", rc);
854  SSE2_QOS_TR_ERR(SSE2_QOS_TP_ERR_53, rc);
855  return(Not_OK);
856  }
857 
858  return OK_pushHW;
859 }
860 
861 
862 #if defined (INTERNAL_SS) || defined (X86)
863 
864 // For initializing the x86 policer format
865 
866 /*
867  * Return the number of hardware TSC timer ticks per second for the dataplane.
868  * This is approximately, but not exactly, the clock speed.
869  */
870 static uint64_t get_tsc_hz(void)
871 {
872  f64 cpu_freq;
873 
874  cpu_freq = os_cpu_clock_frequency();
875  return (uint64_t) cpu_freq;
876 }
877 
878 /*
879  * Convert rates into bytes_per_period and scale.
880  * Return 0 if ok or 1 if error.
881  */
882 static int
883 compute_policer_params (uint64_t hz, // CPU speed in clocks per second
884  uint64_t cir_rate, // in bytes per second
885  uint64_t pir_rate, // in bytes per second
886  uint32_t *current_limit, // in bytes, output may scale the input
887  uint32_t *extended_limit, // in bytes, output may scale the input
888  uint32_t *cir_bytes_per_period,
889  uint32_t *pir_bytes_per_period,
890  uint32_t *scale)
891 {
892  double period;
893  double internal_cir_bytes_per_period;
894  double internal_pir_bytes_per_period;
895  uint32_t max;
896  uint32_t scale_shift;
897  uint32_t scale_amount;
898  uint32_t __attribute__((unused)) orig_current_limit = *current_limit;
899 
900  // Compute period. For 1Ghz-to-8Ghz CPUs, the period will be in
901  // the range of 16 to 116 usec.
902  period = ((double) hz) / ((double) POLICER_TICKS_PER_PERIOD);
903 
904  // Determine bytes per period for each rate
905  internal_cir_bytes_per_period = (double)cir_rate / period;
906  internal_pir_bytes_per_period = (double)pir_rate / period;
907 
908  // Scale if possible. Scaling helps rate accuracy, but is contrained
909  // by the scaled rates and limits fitting in 32-bits.
910  // In addition, we need to insure the scaled rate is no larger than
911  // 2^22 tokens per period. This allows the dataplane to ignore overflow
912  // in the tokens-per-period multiplication since it could only
913  // happen if the policer were idle for more than a year.
914  // This is not really a constraint because 100Gbps at 1Ghz is only
915  // 1.6M tokens per period.
916 #define MAX_RATE_SHIFT 10
917  max = MAX(*current_limit, *extended_limit);
918  max = MAX(max, (uint32_t)internal_cir_bytes_per_period << MAX_RATE_SHIFT);
919  max = MAX(max, (uint32_t)internal_pir_bytes_per_period << MAX_RATE_SHIFT);
920  scale_shift = __builtin_clz(max);
921 
922  scale_amount = 1 << scale_shift;
923  *scale = scale_shift;
924 
925  // Scale the limits
926  *current_limit = *current_limit << scale_shift;
927  *extended_limit = *extended_limit << scale_shift;
928 
929  // Scale the rates
930  internal_cir_bytes_per_period = internal_cir_bytes_per_period * ((double)scale_amount);
931  internal_pir_bytes_per_period = internal_pir_bytes_per_period * ((double)scale_amount);
932 
933  // Make sure the new rates are reasonable
934  // Only needed for very low rates with large bursts
935  if (internal_cir_bytes_per_period < 1.0) {
936  internal_cir_bytes_per_period = 1.0;
937  }
938  if (internal_pir_bytes_per_period < 1.0) {
939  internal_pir_bytes_per_period = 1.0;
940  }
941 
942  *cir_bytes_per_period = (uint32_t)internal_cir_bytes_per_period;
943  *pir_bytes_per_period = (uint32_t)internal_pir_bytes_per_period;
944 
945 // #define PRINT_X86_POLICE_PARAMS
946 #ifdef PRINT_X86_POLICE_PARAMS
947  {
948  uint64_t effective_BPS;
949 
950  // This value actually slightly conservative because it doesn't take into account
951  // the partial period at the end of a second. This really matters only for very low
952  // rates.
953  effective_BPS = (((uint64_t) (*cir_bytes_per_period * (uint64_t)period)) >> *scale );
954 
955  printf("hz=%llu, cir_rate=%llu, limit=%u => "
956  "periods-per-sec=%d usec-per-period=%d => "
957  "scale=%d cir_BPP=%u, scaled_limit=%u => "
958  "effective BPS=%llu, accuracy=%f\n",
959  // input values
960  (unsigned long long)hz,
961  (unsigned long long)cir_rate,
962  orig_current_limit,
963  // computed values
964  (uint32_t)(period), // periods per second
965  (uint32_t)(1000.0 * 1000.0 / period), // in usec
966  *scale,
967  *cir_bytes_per_period,
968  *current_limit,
969  // accuracy
970  (unsigned long long)effective_BPS,
971  (double)cir_rate / (double)effective_BPS);
972  }
973 #endif
974 
975  return 0; // ok
976 }
977 
978 
979 /*
980  * Input: configured parameters in 'cfg'.
981  * Output: h/w parameters are returned in 'hw',
982  * Return: Status, success or failure code.
983  */
987 {
988  const int BYTES_PER_KBIT = (1000 / 8);
989  uint64_t hz;
990  uint32_t cap;
991 
992  if (!cfg || !hw) {
993  SSE2_QOS_DEBUG_ERROR("Illegal parameters");
994  return(Not_OK);
995  }
996 
997  hz = get_tsc_hz();
998  hw->last_update_time = 0;
999 
1000  // Cap the bursts to 32-bits. This allows up to almost one second of
1001  // burst on a 40GE interface, which should be fine for x86.
1002  cap = (cfg->rb.kbps.cb_bytes > 0xFFFFFFFF) ? 0xFFFFFFFF : cfg->rb.kbps.cb_bytes;
1003  hw->current_limit = cap;
1004  cap = (cfg->rb.kbps.eb_bytes > 0xFFFFFFFF) ? 0xFFFFFFFF : cfg->rb.kbps.eb_bytes;
1005  hw->extended_limit = cap;
1006 
1007  if ((cfg->rb.kbps.cir_kbps == 0) && (cfg->rb.kbps.cb_bytes == 0) && (cfg->rb.kbps.eb_bytes == 0)) {
1008  // This is a uninitialized, always-violate policer
1009  hw->single_rate = 1;
1010  hw->cir_tokens_per_period = 0;
1011  return OK_pushHW;
1012  }
1013 
1014  if ((cfg->rfc == SSE2_QOS_POLICER_TYPE_1R2C) ||
1016  // Single-rate policer
1017 
1018  hw->single_rate = 1;
1019 
1020  if ((cfg->rfc == SSE2_QOS_POLICER_TYPE_1R2C) && cfg->rb.kbps.eb_bytes) {
1021  SSE2_QOS_DEBUG_ERROR("Policer parameter validation failed -- 1R2C.");
1022  return(Not_OK);
1023  }
1024 
1025  if ((cfg->rb.kbps.cir_kbps == 0) ||
1026  (cfg->rb.kbps.eir_kbps != 0) ||
1027  ((cfg->rb.kbps.cb_bytes == 0) && (cfg->rb.kbps.eb_bytes == 0))) {
1028  SSE2_QOS_DEBUG_ERROR("Policer parameter validation failed -- 1R.");
1029  return(Not_OK);
1030  }
1031 
1032  if (compute_policer_params(hz,
1033  (uint64_t)cfg->rb.kbps.cir_kbps * BYTES_PER_KBIT,
1034  0,
1035  &hw->current_limit,
1036  &hw->extended_limit,
1037  &hw->cir_tokens_per_period,
1038  &hw->pir_tokens_per_period,
1039  &hw->scale)) {
1040  SSE2_QOS_DEBUG_ERROR("Policer parameter computation failed.");
1041  return(Not_OK);
1042  }
1043 
1044  } else if ((cfg->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698) ||
1046  // Two-rate policer
1047 
1049  hw->color_aware = 1;
1050  }
1051 
1052  if ((cfg->rb.kbps.cir_kbps == 0) || (cfg->rb.kbps.eir_kbps == 0) || (cfg->rb.kbps.eir_kbps < cfg->rb.kbps.cir_kbps) ||
1053  (cfg->rb.kbps.cb_bytes == 0) || (cfg->rb.kbps.eb_bytes == 0)) {
1054  SSE2_QOS_DEBUG_ERROR("Config parameter validation failed.");
1055  return(Not_OK);
1056  }
1057 
1058  if (compute_policer_params(hz,
1059  (uint64_t)cfg->rb.kbps.cir_kbps * BYTES_PER_KBIT,
1060  (uint64_t)cfg->rb.kbps.eir_kbps * BYTES_PER_KBIT,
1061  &hw->current_limit,
1062  &hw->extended_limit,
1063  &hw->cir_tokens_per_period,
1064  &hw->pir_tokens_per_period,
1065  &hw->scale)) {
1066  SSE2_QOS_DEBUG_ERROR("Policer parameter computation failed.");
1067  return(Not_OK);
1068  }
1069 
1070  } else {
1071  SSE2_QOS_DEBUG_ERROR("Config parameter validation failed. RFC not supported");
1072  return(Not_OK);
1073  }
1074 
1075  hw->current_bucket = hw->current_limit;
1076  hw->extended_bucket = hw->extended_limit;
1077 
1078  return OK_pushHW;
1079 }
1080 #endif
1081 
1082 
1083 /*
1084  * Input: configured parameters in 'cfg'.
1085  * Output: physical structure is returned in 'phys',
1086  * Return: Status, success or failure code.
1087  */
1091 {
1092  trans_layer_rc rc;
1094  sse2_qos_pol_cfg_params_st kbps_cfg;
1095 
1096  memset(phys, 0, sizeof(policer_read_response_type_st));
1097  memset(&kbps_cfg, 0, sizeof(sse2_qos_pol_cfg_params_st));
1098 
1099  if (!cfg) {
1100  SSE2_QOS_DEBUG_ERROR("Illegal parameters");
1101  return(Not_OK);
1102  }
1103 
1104  switch (cfg->rate_type) {
1105  case SSE2_QOS_RATE_KBPS:
1106  /* copy all the data into kbps_cfg */
1107  kbps_cfg.rb.kbps.cir_kbps = cfg->rb.kbps.cir_kbps;
1108  kbps_cfg.rb.kbps.eir_kbps = cfg->rb.kbps.eir_kbps;
1109  kbps_cfg.rb.kbps.cb_bytes = cfg->rb.kbps.cb_bytes;
1110  kbps_cfg.rb.kbps.eb_bytes = cfg->rb.kbps.eb_bytes;
1111  break;
1112  case SSE2_QOS_RATE_PPS:
1113  kbps_cfg.rb.kbps.cir_kbps =
1114  sse2_qos_convert_pps_to_kbps(cfg->rb.pps.cir_pps);
1115  kbps_cfg.rb.kbps.eir_kbps =
1116  sse2_qos_convert_pps_to_kbps(cfg->rb.pps.eir_pps);
1117  kbps_cfg.rb.kbps.cb_bytes = sse2_qos_convert_burst_ms_to_bytes(
1118  (uint32_t) cfg->rb.pps.cb_ms, kbps_cfg.rb.kbps.cir_kbps);
1119  kbps_cfg.rb.kbps.eb_bytes = sse2_qos_convert_burst_ms_to_bytes(
1120  (uint32_t) cfg->rb.pps.eb_ms, kbps_cfg.rb.kbps.eir_kbps);
1121  break;
1122  default:
1123  SSE2_QOS_DEBUG_ERROR("Illegal rate type");
1124  return(Not_OK);
1125  }
1126 
1127  /* rate type is now converted to kbps */
1128  kbps_cfg.rate_type = SSE2_QOS_RATE_KBPS;
1129  kbps_cfg.rnd_type = cfg->rnd_type;
1130  kbps_cfg.rfc = cfg->rfc;
1131 
1132 #if !defined (INTERNAL_SS) && !defined (X86)
1133  // convert logical into hw params which involves qos calculations
1134  rc = sse2_pol_compute_hw_params(&kbps_cfg, &pol_hw);
1135  if (rc == Not_OK) {
1136  SSE2_QOS_DEBUG_ERROR("Unable to compute hw param. Error: %d", rc);
1137  return (rc);
1138  }
1139 
1140  // convert hw params into the physical
1141  phys->rfc = pol_hw.rfc;
1142  phys->an = pol_hw.allow_negative;
1143  phys->rexp = pol_hw.rate_exp;
1144  phys->arm = pol_hw.avg_rate_man;
1145  phys->prm = pol_hw.peak_rate_man;
1146  phys->cble = pol_hw.comm_bkt_limit_exp;
1147  phys->cblm = pol_hw.comm_bkt_limit_man;
1148  phys->eble = pol_hw.extd_bkt_limit_exp;
1149  phys->eblm = pol_hw.extd_bkt_limit_man;
1150  phys->cb = pol_hw.comm_bkt;
1151  phys->eb = pol_hw.extd_bkt;
1152 
1153  /* for debugging purposes, the bucket token values can be overwritten */
1154  if (cfg->overwrite_bucket) {
1155  phys->cb = cfg->current_bucket;
1156  phys->eb = cfg->extended_bucket;
1157  }
1158 #else
1159  // convert logical into hw params which involves qos calculations
1160  rc = x86_pol_compute_hw_params(&kbps_cfg, phys);
1161  if (rc == Not_OK) {
1162  SSE2_QOS_DEBUG_ERROR("Unable to compute hw param. Error: %d", rc);
1163  return (rc);
1164  }
1165 
1166  /* for debugging purposes, the bucket token values can be overwritten */
1167  if (cfg->overwrite_bucket) {
1168  phys->current_bucket = cfg->current_bucket;
1169  phys->extended_bucket = cfg->extended_bucket;
1170  }
1171 
1172  // Touch to avoid compiler warning for X86
1173  pol_hw.allow_negative = pol_hw.allow_negative;
1174 
1175 #endif // if !defined (INTERNAL_SS) && !defined (X86)
1176 
1177  return OK_pushHW;
1178 }
1179 
1180 
1181 static void
1184  sse2_qos_pol_hw_params_st *hw_fmt)
1185 {
1186  memset(hw_fmt, 0, sizeof(sse2_qos_pol_hw_params_st));
1187 #if !defined (INTERNAL_SS) && !defined (X86)
1188  hw_fmt->rfc = (uint8_t)bkt->rfc;
1189  hw_fmt->allow_negative = (uint8_t)bkt->an;
1190  hw_fmt->rate_exp = (uint8_t)bkt->rexp;
1191  hw_fmt->avg_rate_man = (uint16_t)bkt->arm;
1192  hw_fmt->peak_rate_man = (uint16_t)bkt->prm;
1193  hw_fmt->comm_bkt_limit_man = (uint8_t)bkt->cblm;
1194  hw_fmt->comm_bkt_limit_exp = (uint8_t)bkt->cble;
1195  hw_fmt->extd_bkt_limit_man = (uint8_t)bkt->eblm;
1196  hw_fmt->extd_bkt_limit_exp = (uint8_t)bkt->eble;
1197  hw_fmt->extd_bkt = bkt->eb;
1198  hw_fmt->comm_bkt = bkt->cb;
1199 #endif // if !defined (INTERNAL_SS) && !defined (X86)
1200 }
1201 
1202 /*
1203  * Input: h/w programmable parameter values in 'hw'
1204  * Output: configured parameter values in 'cfg'
1205  * Return: Status, success or failure code.
1206  */
1207 static cerrno
1210 {
1211  uint64_t temp_rate;
1212 
1213  if ((hw == NULL) || (cfg == NULL)) {
1214  return EINVAL;
1215  }
1216 
1217  if ((hw->rfc == IPE_RFC_RFC4115) &&
1218  !(hw->peak_rate_man << hw->rate_exp) &&
1219  !(hw->extd_bkt_limit_man)) {
1220  /*
1221  * For a 1R2C, we set EIR = 0, EB = 0
1222  */
1224  } else if (hw->rfc == IPE_RFC_RFC2697) {
1226  } else if (hw->rfc == IPE_RFC_RFC2698) {
1228  } else if (hw->rfc == IPE_RFC_RFC4115) {
1230  } else if (hw->rfc == IPE_RFC_MEF5CF1) {
1232  } else {
1233  return EINVAL;
1234  }
1235 
1236  temp_rate = ((hw->avg_rate_man << hw->rate_exp) * 8LL *
1238  cfg->rb.kbps.cir_kbps = (uint32_t)temp_rate;
1239 
1240  temp_rate = ((hw->peak_rate_man << hw->rate_exp) * 8LL *
1241  SSE2_QOS_POL_TICKS_PER_SEC)/1000;
1242  cfg->rb.kbps.eir_kbps = (uint32_t)temp_rate;
1243 
1244  cfg->rb.kbps.cb_bytes = ((uint64_t)hw->comm_bkt_limit_man <<
1245  (uint64_t)hw->comm_bkt_limit_exp);
1246  cfg->rb.kbps.eb_bytes = ((uint64_t)hw->extd_bkt_limit_man <<
1247  (uint64_t)hw->extd_bkt_limit_exp);
1248 
1250  /*
1251  * For 1R3C in the hardware, EB = sum(CB, EB). Also, EIR = CIR. Restore
1252  * values such that the configured params don't reflect this adjustment
1253  */
1254  cfg->rb.kbps.eb_bytes = (cfg->rb.kbps.eb_bytes -
1255  cfg->rb.kbps.cb_bytes);
1256  cfg->rb.kbps.eir_kbps = 0;
1257  } else if (cfg->rfc == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115) {
1258  /*
1259  * For 4115 in the hardware is excess rate and burst, but EA provides
1260  * peak-rate, so adjust it to be eir
1261  */
1262  cfg->rb.kbps.eir_kbps += cfg->rb.kbps.cir_kbps;
1263  cfg->rb.kbps.eb_bytes += cfg->rb.kbps.cb_bytes;
1264  }
1265  /* h/w conversion to cfg is in kbps */
1267  cfg->overwrite_bucket = 0;
1268  cfg->current_bucket = hw->comm_bkt;
1269  cfg->extended_bucket = hw->extd_bkt;
1270 
1271  SSE2_QOS_DEBUG_INFO("configured params, cir: %u kbps, eir: %u kbps, cb "
1272  "burst: 0x%llx bytes, eb burst: 0x%llx bytes",
1273  cfg->rb.kbps.cir_kbps, cfg->rb.kbps.eir_kbps,
1274  cfg->rb.kbps.cb_bytes, cfg->rb.kbps.eb_bytes);
1275  SSE2_QOS_TR_INFO(SSE2_QOS_TP_INFO_22, cfg->rb.kbps.cir_kbps,
1276  cfg->rb.kbps.eir_kbps,
1277  (uint)cfg->rb.kbps.cb_bytes, (uint)cfg->rb.kbps.eb_bytes);
1278 
1279  return EOK;
1280 }
1281 
1282 uint32_t
1284 {
1285  uint64_t numer, denom, rnd_value = 0;
1286 
1287  // sse_qosrm_ship_inc_counter(SSE2_QOS_SHIP_COUNTER_TYPE_API_CNT,
1288  // SSE2_QOS_SHIP_CNT_POL_CONV_KBPS_TO_PPS);
1289 
1290  numer = (uint64_t)((uint64_t)rate_kbps * 1000LL);
1291  denom = (uint64_t)((uint64_t)SSE2_QOS_POLICER_FIXED_PKT_SIZE * 8LL);
1292 
1293  (void)sse2_qos_pol_round(numer, denom, &rnd_value,
1295 
1296  return((uint32_t)rnd_value);
1297 }
1298 
1299 uint32_t
1301  uint32_t rate_kbps)
1302 {
1303  uint64_t numer, denom, rnd_value = 0;
1304 
1305  //sse_qosrm_ship_inc_counter(SSE2_QOS_SHIP_COUNTER_TYPE_API_CNT,
1306  // SSE2_QOS_SHIP_CNT_POL_CONV_BYTES_TO_BURST_MS);
1307 
1308  numer = burst_bytes * 8LL;
1309  denom = (uint64_t)rate_kbps;
1310 
1311  (void)sse2_qos_pol_round(numer, denom, &rnd_value,
1313 
1314  return((uint32_t)rnd_value);
1315 }
1316 
1317 /*
1318  * Input: physical structure in 'phys', rate_type in cfg
1319  * Output: configured parameters in 'cfg'.
1320  * Return: Status, success or failure code.
1321  */
1325 {
1326  cerrno rc;
1328  sse2_qos_pol_cfg_params_st kbps_cfg;
1329 
1330  memset(&pol_hw, 0, sizeof(sse2_qos_pol_hw_params_st));
1331  memset(&kbps_cfg, 0, sizeof(sse2_qos_pol_cfg_params_st));
1332 
1333  if (!phys) {
1334  SSE2_QOS_DEBUG_ERROR("Illegal parameters");
1335  return(Not_OK);
1336  }
1337 
1338  sse2_qos_convert_pol_bucket_to_hw_fmt (phys, &pol_hw);
1339 
1340  rc = sse2_pol_convert_hw_to_cfg_params(&pol_hw, &kbps_cfg);
1341  if (CERR_IS_NOTOK(rc)) {
1342  SSE2_QOS_DEBUG_ERROR("Unable to convert hw params to config params. "
1343  "Error: %d", rc);
1344  return(Not_OK);
1345  }
1346 
1347  /* check what rate type is required */
1348  switch (cfg->rate_type) {
1349  case SSE2_QOS_RATE_KBPS:
1350  /* copy all the data into kbps_cfg */
1351  cfg->rb.kbps.cir_kbps = kbps_cfg.rb.kbps.cir_kbps;
1352  cfg->rb.kbps.eir_kbps = kbps_cfg.rb.kbps.eir_kbps;
1353  cfg->rb.kbps.cb_bytes = kbps_cfg.rb.kbps.cb_bytes;
1354  cfg->rb.kbps.eb_bytes = kbps_cfg.rb.kbps.eb_bytes;
1355  break;
1356  case SSE2_QOS_RATE_PPS:
1357  cfg->rb.pps.cir_pps =
1358  sse2_qos_convert_kbps_to_pps(kbps_cfg.rb.kbps.cir_kbps);
1359  cfg->rb.pps.eir_pps =
1360  sse2_qos_convert_kbps_to_pps(kbps_cfg.rb.kbps.eir_kbps);
1362  kbps_cfg.rb.kbps.cb_bytes, kbps_cfg.rb.kbps.cir_kbps);
1364  kbps_cfg.rb.kbps.eb_bytes, kbps_cfg.rb.kbps.eir_kbps);
1365  break;
1366  default:
1367  SSE2_QOS_DEBUG_ERROR("Illegal rate type");
1368  return(Not_OK);
1369  }
1370 
1371  /* cfg->rate_type remains what it was */
1372  cfg->rnd_type = kbps_cfg.rnd_type;
1373  cfg->rfc = kbps_cfg.rfc;
1374  cfg->overwrite_bucket = kbps_cfg.overwrite_bucket;
1375  cfg->current_bucket = kbps_cfg.current_bucket;
1376  cfg->extended_bucket = kbps_cfg.extended_bucket;
1377 
1378  return OK_pushHW;
1379 }
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:1182
uint32_t sse2_qos_convert_pps_to_kbps(uint32_t rate_pps)
Definition: xlate.c:786
#define MAX(x, y)
Definition: xlate.c:49
#define SSE2_QOS_POL_AVG_RATE_MANT_MAX
Definition: xlate.c:155
#define SSE2_QOS_POL_MIN_BURST_BYTE
Definition: xlate.c:134
static void(BVT(clib_bihash)*h, BVT(clib_bihash_value)*v)
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
unsigned int uint32_t
Definition: fix_types.h:29
uint32_t sse2_qos_convert_burst_ms_to_bytes(uint32_t burst_ms, uint32_t rate_kbps)
Definition: xlate.c:802
#define NULL
Definition: clib.h:55
uint8_t comm_bkt_limit_man
Definition: xlate.h:128
#define RATE256
Definition: xlate.c:202
#define SSE2_QOS_DEBUG_ERROR(msg, args...)
Definition: xlate.c:31
trans_layer_rc sse2_pol_logical_2_physical(sse2_qos_pol_cfg_params_st *cfg, policer_read_response_type_st *phys)
Definition: xlate.c:1089
#define SSE2_QOS_DEBUG_INFO(msg, args...)
Definition: xlate.c:34
uint64_t sse2_pol_get_bkt_value(uint64_t rate_hw, uint64_t byte_value)
Definition: xlate.c:578
union sse2_qos_pol_cfg_params_st_::@153 rb
#define SSE2_QOS_POLICER_FIXED_PKT_SIZE
Definition: xlate.c:120
#define trans_layer_rc
Definition: fix_types.h:20
uint32_t sse2_qos_convert_kbps_to_pps(uint32_t rate_kbps)
Definition: xlate.c:1283
#define SSE2_QOS_TR_INFO(TpParms...)
Definition: xlate.c:42
#define SSE2_QOS_POL_TICKS_PER_SEC
Definition: xlate.c:123
static int compute_policer_params(uint64_t hz, uint64_t cir_rate, uint64_t pir_rate, uint32_t *current_limit, uint32_t *extended_limit, uint32_t *cir_bytes_per_period, uint32_t *pir_bytes_per_period, uint32_t *scale)
Definition: xlate.c:883
#define EOK
Definition: fix_types.h:21
uint8_t extd_bkt_limit_exp
Definition: xlate.h:129
#define SSE2_QOS_POL_COMM_BKT_LIMIT_MANT_MAX
Definition: xlate.c:171
uint32_t sse2_qos_convert_burst_bytes_to_ms(uint64_t burst_bytes, uint32_t rate_kbps)
Definition: xlate.c:1300
#define IPE_RFC_RFC2697
Definition: xlate.c:112
#define RATE_128TO256_UNIT
Definition: xlate.c:207
static cerrno sse2_qos_pol_round(uint64_t numerator, uint64_t denominator, uint64_t *rounded_value, sse2_qos_round_type_en round_type)
Definition: xlate.c:211
unsigned char uint8_t
Definition: fix_types.h:27
uint8_t comm_bkt_limit_exp
Definition: xlate.h:127
#define IPE_RFC_RFC4115
Definition: xlate.c:114
#define cerrno
Definition: fix_types.h:19
#define SSE2_QOS_POL_EXTD_BKT_LIMIT_MANT_MAX
Definition: xlate.c:183
trans_layer_rc x86_pol_compute_hw_params(sse2_qos_pol_cfg_params_st *cfg, policer_read_response_type_st *hw)
Definition: xlate.c:985
static void sse2_pol_rnd_burst_byte_fmt(uint64_t cfg_burst, uint16_t max_exp_value, uint16_t max_mant_value, uint32_t max_bkt_value, uint32_t rate_hw, uint8_t *exp, uint32_t *mant, uint32_t *bkt_value)
Definition: xlate.c:592
#define IPE_RFC_RFC2698
Definition: xlate.c:113
unsigned short int uint16_t
Definition: fix_types.h:28
struct sse2_qos_pol_cfg_params_st_::@153::@154 kbps
#define SSE2_QOS_POL_COMM_BKT_LIMIT_EXP_MAX
Definition: xlate.c:175
#define CERR_IS_NOTOK(a)
Definition: fix_types.h:22
#define OK_pushHW
Definition: fix_types.h:24
#define MAX_RATE_SHIFT
struct sse2_qos_pol_cfg_params_st_::@153::@155 pps
#define Not_OK
Definition: fix_types.h:25
#define SSE2_QOS_POL_RATE_EXP_MAX
Definition: xlate.c:152
#define SSE2_QOS_POL_PEAK_RATE_MAX
Definition: xlate.c:165
#define SSE2_QOS_TR_ERR(TpParms...)
Definition: xlate.c:38
#define SSE2_QOS_POL_ALLOW_NEGATIVE
Definition: xlate.c:141
uint8_t extd_bkt_limit_man
Definition: xlate.h:130
#define RATE_OVER256_UNIT
Definition: xlate.c:206
#define RATE_64TO128_UNIT
Definition: xlate.c:208
static void sse2_qos_convert_value_to_exp_mant_fmt(uint64_t value, uint16_t max_exp_value, uint16_t max_mant_value, sse2_qos_round_type_en type, uint8_t *exp, uint32_t *mant)
Definition: xlate.c:342
static cerrno sse2_pol_convert_cfg_burst_to_hw(sse2_qos_pol_cfg_params_st *cfg, sse2_qos_pol_hw_params_st *hw)
Definition: xlate.c:653
#define SSE2_QOS_POL_DEF_BURST_BYTE
Definition: xlate.c:128
uint32_t cir_tokens_per_period
Definition: police.h:72
#define RATE64
Definition: xlate.c:204
#define RATE128
Definition: xlate.c:203
#define SSE2_QOS_POL_AVG_RATE_MAX
Definition: xlate.c:157
static cerrno sse2_pol_convert_hw_to_cfg_params(sse2_qos_pol_hw_params_st *hw, sse2_qos_pol_cfg_params_st *cfg)
Definition: xlate.c:1208
double f64
Definition: types.h:140
sse2_qos_round_type_en
Definition: xlate.h:43
#define SSE2_QOS_POL_EXTD_BKT_LIMIT_EXP_MAX
Definition: xlate.c:187
uint64_t sse2_pol_get_bkt_max(uint64_t rate_hw, uint64_t bkt_max)
Definition: xlate.c:545
static cerrno sse2_pol_convert_cfg_to_hw_params(sse2_qos_pol_cfg_params_st *cfg, sse2_qos_pol_hw_params_st *hw)
Definition: xlate.c:738
#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:57
uint32_t pir_tokens_per_period
Definition: police.h:73
static cerrno sse2_pol_validate_cfg_params(sse2_qos_pol_cfg_params_st *cfg)
Definition: xlate.c:252
static cerrno sse2_pol_convert_cfg_rates_to_hw(sse2_qos_pol_cfg_params_st *cfg, sse2_qos_pol_hw_params_st *hw)
Definition: xlate.c:386
static uint64_t get_tsc_hz(void)
Definition: xlate.c:870
trans_layer_rc sse2_pol_compute_hw_params(sse2_qos_pol_cfg_params_st *cfg, sse2_qos_pol_hw_params_st *hw)
Definition: xlate.c:825
#define SSE2_QOS_POL_COMM_BKT_MAX
Definition: xlate.c:145
trans_layer_rc sse2_pol_physical_2_logical(policer_read_response_type_st *phys, sse2_qos_pol_cfg_params_st *cfg)
Definition: xlate.c:1323
#define MIN(x, y)
Definition: xlate.c:45
f64 os_cpu_clock_frequency(void)
Definition: time.c:138