@@ -179,3 +179,326 @@ void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx)
179179 sq -> head ++ ;
180180 sq -> head &= (sq -> sqe_cnt - 1 );
181181}
182+
183+ int cn10k_free_all_ipolicers (struct otx2_nic * pfvf )
184+ {
185+ struct nix_bandprof_free_req * req ;
186+ int rc ;
187+
188+ if (is_dev_otx2 (pfvf -> pdev ))
189+ return 0 ;
190+
191+ mutex_lock (& pfvf -> mbox .lock );
192+
193+ req = otx2_mbox_alloc_msg_nix_bandprof_free (& pfvf -> mbox );
194+ if (!req ) {
195+ rc = - ENOMEM ;
196+ goto out ;
197+ }
198+
199+ /* Free all bandwidth profiles allocated */
200+ req -> free_all = true;
201+
202+ rc = otx2_sync_mbox_msg (& pfvf -> mbox );
203+ out :
204+ mutex_unlock (& pfvf -> mbox .lock );
205+ return rc ;
206+ }
207+
208+ int cn10k_alloc_leaf_profile (struct otx2_nic * pfvf , u16 * leaf )
209+ {
210+ struct nix_bandprof_alloc_req * req ;
211+ struct nix_bandprof_alloc_rsp * rsp ;
212+ int rc ;
213+
214+ req = otx2_mbox_alloc_msg_nix_bandprof_alloc (& pfvf -> mbox );
215+ if (!req )
216+ return - ENOMEM ;
217+
218+ req -> prof_count [BAND_PROF_LEAF_LAYER ] = 1 ;
219+
220+ rc = otx2_sync_mbox_msg (& pfvf -> mbox );
221+ if (rc )
222+ goto out ;
223+
224+ rsp = (struct nix_bandprof_alloc_rsp * )
225+ otx2_mbox_get_rsp (& pfvf -> mbox .mbox , 0 , & req -> hdr );
226+ if (!rsp -> prof_count [BAND_PROF_LEAF_LAYER ]) {
227+ rc = - EIO ;
228+ goto out ;
229+ }
230+
231+ * leaf = rsp -> prof_idx [BAND_PROF_LEAF_LAYER ][0 ];
232+ out :
233+ if (rc ) {
234+ dev_warn (pfvf -> dev ,
235+ "Failed to allocate ingress bandwidth policer\n" );
236+ }
237+
238+ return rc ;
239+ }
240+
241+ int cn10k_alloc_matchall_ipolicer (struct otx2_nic * pfvf )
242+ {
243+ struct otx2_hw * hw = & pfvf -> hw ;
244+ int ret ;
245+
246+ mutex_lock (& pfvf -> mbox .lock );
247+
248+ ret = cn10k_alloc_leaf_profile (pfvf , & hw -> matchall_ipolicer );
249+
250+ mutex_unlock (& pfvf -> mbox .lock );
251+
252+ return ret ;
253+ }
254+
255+ #define POLICER_TIMESTAMP 1 /* 1 second */
256+ #define MAX_RATE_EXP 22 /* Valid rate exponent range: 0 - 22 */
257+
258+ static void cn10k_get_ingress_burst_cfg (u32 burst , u32 * burst_exp ,
259+ u32 * burst_mantissa )
260+ {
261+ int tmp ;
262+
263+ /* Burst is calculated as
264+ * (1+[BURST_MANTISSA]/256)*2^[BURST_EXPONENT]
265+ * This is the upper limit on number tokens (bytes) that
266+ * can be accumulated in the bucket.
267+ */
268+ * burst_exp = ilog2 (burst );
269+ if (burst < 256 ) {
270+ /* No float: can't express mantissa in this case */
271+ * burst_mantissa = 0 ;
272+ return ;
273+ }
274+
275+ if (* burst_exp > MAX_RATE_EXP )
276+ * burst_exp = MAX_RATE_EXP ;
277+
278+ /* Calculate mantissa
279+ * Find remaining bytes 'burst - 2^burst_exp'
280+ * mantissa = (remaining bytes) / 2^ (burst_exp - 8)
281+ */
282+ tmp = burst - rounddown_pow_of_two (burst );
283+ * burst_mantissa = tmp / (1UL << (* burst_exp - 8 ));
284+ }
285+
286+ static void cn10k_get_ingress_rate_cfg (u64 rate , u32 * rate_exp ,
287+ u32 * rate_mantissa , u32 * rdiv )
288+ {
289+ u32 div = 0 ;
290+ u32 exp = 0 ;
291+ u64 tmp ;
292+
293+ /* Figure out mantissa, exponent and divider from given max pkt rate
294+ *
295+ * To achieve desired rate HW adds
296+ * (1+[RATE_MANTISSA]/256)*2^[RATE_EXPONENT] tokens (bytes) at every
297+ * policer timeunit * 2^rdiv ie 2 * 2^rdiv usecs, to the token bucket.
298+ * Here policer timeunit is 2 usecs and rate is in bits per sec.
299+ * Since floating point cannot be used below algorithm uses 1000000
300+ * scale factor to support rates upto 100Gbps.
301+ */
302+ tmp = rate * 32 * 2 ;
303+ if (tmp < 256000000 ) {
304+ while (tmp < 256000000 ) {
305+ tmp = tmp * 2 ;
306+ div ++ ;
307+ }
308+ } else {
309+ for (exp = 0 ; tmp >= 512000000 && exp <= MAX_RATE_EXP ; exp ++ )
310+ tmp = tmp / 2 ;
311+
312+ if (exp > MAX_RATE_EXP )
313+ exp = MAX_RATE_EXP ;
314+ }
315+
316+ * rate_mantissa = (tmp - 256000000 ) / 1000000 ;
317+ * rate_exp = exp ;
318+ * rdiv = div ;
319+ }
320+
321+ int cn10k_map_unmap_rq_policer (struct otx2_nic * pfvf , int rq_idx ,
322+ u16 policer , bool map )
323+ {
324+ struct nix_cn10k_aq_enq_req * aq ;
325+
326+ aq = otx2_mbox_alloc_msg_nix_cn10k_aq_enq (& pfvf -> mbox );
327+ if (!aq )
328+ return - ENOMEM ;
329+
330+ /* Enable policing and set the bandwidth profile (policer) index */
331+ if (map )
332+ aq -> rq .policer_ena = 1 ;
333+ else
334+ aq -> rq .policer_ena = 0 ;
335+ aq -> rq_mask .policer_ena = 1 ;
336+
337+ aq -> rq .band_prof_id = policer ;
338+ aq -> rq_mask .band_prof_id = GENMASK (9 , 0 );
339+
340+ /* Fill AQ info */
341+ aq -> qidx = rq_idx ;
342+ aq -> ctype = NIX_AQ_CTYPE_RQ ;
343+ aq -> op = NIX_AQ_INSTOP_WRITE ;
344+
345+ return otx2_sync_mbox_msg (& pfvf -> mbox );
346+ }
347+
348+ int cn10k_free_leaf_profile (struct otx2_nic * pfvf , u16 leaf )
349+ {
350+ struct nix_bandprof_free_req * req ;
351+
352+ req = otx2_mbox_alloc_msg_nix_bandprof_free (& pfvf -> mbox );
353+ if (!req )
354+ return - ENOMEM ;
355+
356+ req -> prof_count [BAND_PROF_LEAF_LAYER ] = 1 ;
357+ req -> prof_idx [BAND_PROF_LEAF_LAYER ][0 ] = leaf ;
358+
359+ return otx2_sync_mbox_msg (& pfvf -> mbox );
360+ }
361+
362+ int cn10k_free_matchall_ipolicer (struct otx2_nic * pfvf )
363+ {
364+ struct otx2_hw * hw = & pfvf -> hw ;
365+ int qidx , rc ;
366+
367+ mutex_lock (& pfvf -> mbox .lock );
368+
369+ /* Remove RQ's policer mapping */
370+ for (qidx = 0 ; qidx < hw -> rx_queues ; qidx ++ )
371+ cn10k_map_unmap_rq_policer (pfvf , qidx ,
372+ hw -> matchall_ipolicer , false);
373+
374+ rc = cn10k_free_leaf_profile (pfvf , hw -> matchall_ipolicer );
375+
376+ mutex_unlock (& pfvf -> mbox .lock );
377+ return rc ;
378+ }
379+
380+ int cn10k_set_ipolicer_rate (struct otx2_nic * pfvf , u16 profile ,
381+ u32 burst , u64 rate , bool pps )
382+ {
383+ struct nix_cn10k_aq_enq_req * aq ;
384+ u32 burst_exp , burst_mantissa ;
385+ u32 rate_exp , rate_mantissa ;
386+ u32 rdiv ;
387+
388+ /* Get exponent and mantissa values for the desired rate */
389+ cn10k_get_ingress_burst_cfg (burst , & burst_exp , & burst_mantissa );
390+ cn10k_get_ingress_rate_cfg (rate , & rate_exp , & rate_mantissa , & rdiv );
391+
392+ /* Init bandwidth profile */
393+ aq = otx2_mbox_alloc_msg_nix_cn10k_aq_enq (& pfvf -> mbox );
394+ if (!aq )
395+ return - ENOMEM ;
396+
397+ /* Set initial color mode to blind */
398+ aq -> prof .icolor = 0x03 ;
399+ aq -> prof_mask .icolor = 0x03 ;
400+
401+ /* Set rate and burst values */
402+ aq -> prof .cir_exponent = rate_exp ;
403+ aq -> prof_mask .cir_exponent = 0x1F ;
404+
405+ aq -> prof .cir_mantissa = rate_mantissa ;
406+ aq -> prof_mask .cir_mantissa = 0xFF ;
407+
408+ aq -> prof .cbs_exponent = burst_exp ;
409+ aq -> prof_mask .cbs_exponent = 0x1F ;
410+
411+ aq -> prof .cbs_mantissa = burst_mantissa ;
412+ aq -> prof_mask .cbs_mantissa = 0xFF ;
413+
414+ aq -> prof .rdiv = rdiv ;
415+ aq -> prof_mask .rdiv = 0xF ;
416+
417+ if (pps ) {
418+ /* The amount of decremented tokens is calculated according to
419+ * the following equation:
420+ * max([ LMODE ? 0 : (packet_length - LXPTR)] +
421+ * ([ADJUST_MANTISSA]/256 - 1) * 2^[ADJUST_EXPONENT],
422+ * 1/256)
423+ * if LMODE is 1 then rate limiting will be based on
424+ * PPS otherwise bps.
425+ * The aim of the ADJUST value is to specify a token cost per
426+ * packet in contrary to the packet length that specifies a
427+ * cost per byte. To rate limit based on PPS adjust mantissa
428+ * is set as 384 and exponent as 1 so that number of tokens
429+ * decremented becomes 1 i.e, 1 token per packeet.
430+ */
431+ aq -> prof .adjust_exponent = 1 ;
432+ aq -> prof_mask .adjust_exponent = 0x1F ;
433+
434+ aq -> prof .adjust_mantissa = 384 ;
435+ aq -> prof_mask .adjust_mantissa = 0x1FF ;
436+
437+ aq -> prof .lmode = 0x1 ;
438+ aq -> prof_mask .lmode = 0x1 ;
439+ }
440+
441+ /* Two rate three color marker
442+ * With PEIR/EIR set to zero, color will be either green or red
443+ */
444+ aq -> prof .meter_algo = 2 ;
445+ aq -> prof_mask .meter_algo = 0x3 ;
446+
447+ aq -> prof .rc_action = NIX_RX_BAND_PROF_ACTIONRESULT_DROP ;
448+ aq -> prof_mask .rc_action = 0x3 ;
449+
450+ aq -> prof .yc_action = NIX_RX_BAND_PROF_ACTIONRESULT_PASS ;
451+ aq -> prof_mask .yc_action = 0x3 ;
452+
453+ aq -> prof .gc_action = NIX_RX_BAND_PROF_ACTIONRESULT_PASS ;
454+ aq -> prof_mask .gc_action = 0x3 ;
455+
456+ /* Setting exponent value as 24 and mantissa as 0 configures
457+ * the bucket with zero values making bucket unused. Peak
458+ * information rate and Excess information rate buckets are
459+ * unused here.
460+ */
461+ aq -> prof .peir_exponent = 24 ;
462+ aq -> prof_mask .peir_exponent = 0x1F ;
463+
464+ aq -> prof .peir_mantissa = 0 ;
465+ aq -> prof_mask .peir_mantissa = 0xFF ;
466+
467+ aq -> prof .pebs_exponent = 24 ;
468+ aq -> prof_mask .pebs_exponent = 0x1F ;
469+
470+ aq -> prof .pebs_mantissa = 0 ;
471+ aq -> prof_mask .pebs_mantissa = 0xFF ;
472+
473+ /* Fill AQ info */
474+ aq -> qidx = profile ;
475+ aq -> ctype = NIX_AQ_CTYPE_BANDPROF ;
476+ aq -> op = NIX_AQ_INSTOP_WRITE ;
477+
478+ return otx2_sync_mbox_msg (& pfvf -> mbox );
479+ }
480+
481+ int cn10k_set_matchall_ipolicer_rate (struct otx2_nic * pfvf ,
482+ u32 burst , u64 rate )
483+ {
484+ struct otx2_hw * hw = & pfvf -> hw ;
485+ int qidx , rc ;
486+
487+ mutex_lock (& pfvf -> mbox .lock );
488+
489+ rc = cn10k_set_ipolicer_rate (pfvf , hw -> matchall_ipolicer , burst ,
490+ rate , false);
491+ if (rc )
492+ goto out ;
493+
494+ for (qidx = 0 ; qidx < hw -> rx_queues ; qidx ++ ) {
495+ rc = cn10k_map_unmap_rq_policer (pfvf , qidx ,
496+ hw -> matchall_ipolicer , true);
497+ if (rc )
498+ break ;
499+ }
500+
501+ out :
502+ mutex_unlock (& pfvf -> mbox .lock );
503+ return rc ;
504+ }
0 commit comments