1
2
3
4#include <net/devlink.h>
5#include "ocelot.h"
6
7
8
9
10
11
12
13#define OCELOT_RESOURCE_SZ 256
14#define OCELOT_NUM_RESOURCES 4
15
16#define BUF_xxxx_I (0 * OCELOT_RESOURCE_SZ)
17#define REF_xxxx_I (1 * OCELOT_RESOURCE_SZ)
18#define BUF_xxxx_E (2 * OCELOT_RESOURCE_SZ)
19#define REF_xxxx_E (3 * OCELOT_RESOURCE_SZ)
20
21
22
23
24
25
26
27#define xxx_Q_RSRV_x 0
28#define xxx_PRIO_SHR_x 216
29#define xxx_P_RSRV_x 224
30#define xxx_COL_SHR_x 254
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47#define BUF_Q_RSRV_E(port, prio) \
48 (BUF_xxxx_E + xxx_Q_RSRV_x + OCELOT_NUM_TC * (port) + (prio))
49
50
51
52
53
54
55
56
57
58#define BUF_P_RSRV_E(port) \
59 (BUF_xxxx_E + xxx_P_RSRV_x + (port))
60
61
62
63
64
65
66
67
68
69#define BUF_Q_RSRV_I(port, prio) \
70 (BUF_xxxx_I + xxx_Q_RSRV_x + OCELOT_NUM_TC * (port) + (prio))
71
72
73
74
75
76
77
78
79
80#define BUF_P_RSRV_I(port) \
81 (BUF_xxxx_I + xxx_P_RSRV_x + (port))
82
83
84
85
86
87
88
89
90
91#define REF_Q_RSRV_E(port, prio) \
92 (REF_xxxx_E + xxx_Q_RSRV_x + OCELOT_NUM_TC * (port) + (prio))
93
94
95
96
97
98
99
100
101
102#define REF_P_RSRV_E(port) \
103 (REF_xxxx_E + xxx_P_RSRV_x + (port))
104
105
106
107
108
109
110
111
112
113#define REF_Q_RSRV_I(port, prio) \
114 (REF_xxxx_I + xxx_Q_RSRV_x + OCELOT_NUM_TC * (port) + (prio))
115
116
117
118
119
120
121
122
123
124#define REF_P_RSRV_I(port) \
125 (REF_xxxx_I + xxx_P_RSRV_x + (port))
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141#define BUF_PRIO_SHR_E(prio) \
142 (BUF_xxxx_E + xxx_PRIO_SHR_x + (prio))
143
144
145
146
147
148
149
150
151
152#define BUF_COL_SHR_E(dp) \
153 (BUF_xxxx_E + xxx_COL_SHR_x + (1 - (dp)))
154
155
156
157
158
159
160
161
162
163#define BUF_PRIO_SHR_I(prio) \
164 (BUF_xxxx_I + xxx_PRIO_SHR_x + (prio))
165
166
167
168
169
170
171
172
173
174#define BUF_COL_SHR_I(dp) \
175 (BUF_xxxx_I + xxx_COL_SHR_x + (1 - (dp)))
176
177
178
179
180
181
182
183
184
185#define REF_PRIO_SHR_E(prio) \
186 (REF_xxxx_E + xxx_PRIO_SHR_x + (prio))
187
188
189
190
191
192
193
194
195
196#define REF_COL_SHR_E(dp) \
197 (REF_xxxx_E + xxx_COL_SHR_x + (1 - (dp)))
198
199
200
201
202
203
204
205
206
207#define REF_PRIO_SHR_I(prio) \
208 (REF_xxxx_I + xxx_PRIO_SHR_x + (prio))
209
210
211
212
213
214
215
216
217
218#define REF_COL_SHR_I(dp) \
219 (REF_xxxx_I + xxx_COL_SHR_x + (1 - (dp)))
220
221static u32 ocelot_wm_read(struct ocelot *ocelot, int index)
222{
223 int wm = ocelot_read_gix(ocelot, QSYS_RES_CFG, index);
224
225 return ocelot->ops->wm_dec(wm);
226}
227
228static void ocelot_wm_write(struct ocelot *ocelot, int index, u32 val)
229{
230 u32 wm = ocelot->ops->wm_enc(val);
231
232 ocelot_write_gix(ocelot, wm, QSYS_RES_CFG, index);
233}
234
235static void ocelot_wm_status(struct ocelot *ocelot, int index, u32 *inuse,
236 u32 *maxuse)
237{
238 int res_stat = ocelot_read_gix(ocelot, QSYS_RES_STAT, index);
239
240 return ocelot->ops->wm_stat(res_stat, inuse, maxuse);
241}
242
243
244
245
246
247
248
249
250
251
252static void ocelot_disable_reservation_watermarks(struct ocelot *ocelot,
253 int port)
254{
255 int prio;
256
257 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
258 ocelot_wm_write(ocelot, BUF_Q_RSRV_I(port, prio), 0);
259 ocelot_wm_write(ocelot, BUF_Q_RSRV_E(port, prio), 0);
260 ocelot_wm_write(ocelot, REF_Q_RSRV_I(port, prio), 0);
261 ocelot_wm_write(ocelot, REF_Q_RSRV_E(port, prio), 0);
262 }
263
264 ocelot_wm_write(ocelot, BUF_P_RSRV_I(port), 0);
265 ocelot_wm_write(ocelot, BUF_P_RSRV_E(port), 0);
266 ocelot_wm_write(ocelot, REF_P_RSRV_I(port), 0);
267 ocelot_wm_write(ocelot, REF_P_RSRV_E(port), 0);
268}
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289static void ocelot_disable_tc_sharing_watermarks(struct ocelot *ocelot)
290{
291 int prio;
292
293 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
294 ocelot_wm_write(ocelot, BUF_PRIO_SHR_I(prio), 0);
295 ocelot_wm_write(ocelot, BUF_PRIO_SHR_E(prio), 0);
296 ocelot_wm_write(ocelot, REF_PRIO_SHR_I(prio), 0);
297 ocelot_wm_write(ocelot, REF_PRIO_SHR_E(prio), 0);
298 }
299}
300
301static void ocelot_get_buf_rsrv(struct ocelot *ocelot, u32 *buf_rsrv_i,
302 u32 *buf_rsrv_e)
303{
304 int port, prio;
305
306 *buf_rsrv_i = 0;
307 *buf_rsrv_e = 0;
308
309 for (port = 0; port <= ocelot->num_phys_ports; port++) {
310 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
311 *buf_rsrv_i += ocelot_wm_read(ocelot,
312 BUF_Q_RSRV_I(port, prio));
313 *buf_rsrv_e += ocelot_wm_read(ocelot,
314 BUF_Q_RSRV_E(port, prio));
315 }
316
317 *buf_rsrv_i += ocelot_wm_read(ocelot, BUF_P_RSRV_I(port));
318 *buf_rsrv_e += ocelot_wm_read(ocelot, BUF_P_RSRV_E(port));
319 }
320
321 *buf_rsrv_i *= OCELOT_BUFFER_CELL_SZ;
322 *buf_rsrv_e *= OCELOT_BUFFER_CELL_SZ;
323}
324
325static void ocelot_get_ref_rsrv(struct ocelot *ocelot, u32 *ref_rsrv_i,
326 u32 *ref_rsrv_e)
327{
328 int port, prio;
329
330 *ref_rsrv_i = 0;
331 *ref_rsrv_e = 0;
332
333 for (port = 0; port <= ocelot->num_phys_ports; port++) {
334 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
335 *ref_rsrv_i += ocelot_wm_read(ocelot,
336 REF_Q_RSRV_I(port, prio));
337 *ref_rsrv_e += ocelot_wm_read(ocelot,
338 REF_Q_RSRV_E(port, prio));
339 }
340
341 *ref_rsrv_i += ocelot_wm_read(ocelot, REF_P_RSRV_I(port));
342 *ref_rsrv_e += ocelot_wm_read(ocelot, REF_P_RSRV_E(port));
343 }
344}
345
346
347
348
349static void ocelot_setup_sharing_watermarks(struct ocelot *ocelot)
350{
351 u32 buf_rsrv_i, buf_rsrv_e;
352 u32 ref_rsrv_i, ref_rsrv_e;
353 u32 buf_shr_i, buf_shr_e;
354 u32 ref_shr_i, ref_shr_e;
355
356 ocelot_get_buf_rsrv(ocelot, &buf_rsrv_i, &buf_rsrv_e);
357 ocelot_get_ref_rsrv(ocelot, &ref_rsrv_i, &ref_rsrv_e);
358
359 buf_shr_i = ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_ING] -
360 buf_rsrv_i;
361 buf_shr_e = ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_EGR] -
362 buf_rsrv_e;
363 ref_shr_i = ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_ING] -
364 ref_rsrv_i;
365 ref_shr_e = ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_EGR] -
366 ref_rsrv_e;
367
368 buf_shr_i /= OCELOT_BUFFER_CELL_SZ;
369 buf_shr_e /= OCELOT_BUFFER_CELL_SZ;
370
371 ocelot_wm_write(ocelot, BUF_COL_SHR_I(0), buf_shr_i);
372 ocelot_wm_write(ocelot, BUF_COL_SHR_E(0), buf_shr_e);
373 ocelot_wm_write(ocelot, REF_COL_SHR_E(0), ref_shr_e);
374 ocelot_wm_write(ocelot, REF_COL_SHR_I(0), ref_shr_i);
375 ocelot_wm_write(ocelot, BUF_COL_SHR_I(1), 0);
376 ocelot_wm_write(ocelot, BUF_COL_SHR_E(1), 0);
377 ocelot_wm_write(ocelot, REF_COL_SHR_E(1), 0);
378 ocelot_wm_write(ocelot, REF_COL_SHR_I(1), 0);
379}
380
381
382static int ocelot_watermark_validate(struct ocelot *ocelot,
383 struct netlink_ext_ack *extack)
384{
385 u32 buf_rsrv_i, buf_rsrv_e;
386 u32 ref_rsrv_i, ref_rsrv_e;
387
388 ocelot_get_buf_rsrv(ocelot, &buf_rsrv_i, &buf_rsrv_e);
389 ocelot_get_ref_rsrv(ocelot, &ref_rsrv_i, &ref_rsrv_e);
390
391 if (buf_rsrv_i > ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_ING]) {
392 NL_SET_ERR_MSG_MOD(extack,
393 "Ingress frame reservations exceed pool size");
394 return -ERANGE;
395 }
396 if (buf_rsrv_e > ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_EGR]) {
397 NL_SET_ERR_MSG_MOD(extack,
398 "Egress frame reservations exceed pool size");
399 return -ERANGE;
400 }
401 if (ref_rsrv_i > ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_ING]) {
402 NL_SET_ERR_MSG_MOD(extack,
403 "Ingress reference reservations exceed pool size");
404 return -ERANGE;
405 }
406 if (ref_rsrv_e > ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_EGR]) {
407 NL_SET_ERR_MSG_MOD(extack,
408 "Egress reference reservations exceed pool size");
409 return -ERANGE;
410 }
411
412 return 0;
413}
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476static void ocelot_watermark_init(struct ocelot *ocelot)
477{
478 int all_tcs = GENMASK(OCELOT_NUM_TC - 1, 0);
479 int port;
480
481 ocelot_write(ocelot, all_tcs, QSYS_RES_QOS_MODE);
482
483 for (port = 0; port <= ocelot->num_phys_ports; port++)
484 ocelot_disable_reservation_watermarks(ocelot, port);
485
486 ocelot_disable_tc_sharing_watermarks(ocelot);
487 ocelot_setup_sharing_watermarks(ocelot);
488}
489
490
491
492
493static const struct devlink_sb_pool_info ocelot_sb_pool[] = {
494 [OCELOT_SB_BUF] = {
495 .cell_size = OCELOT_BUFFER_CELL_SZ,
496 .threshold_type = DEVLINK_SB_THRESHOLD_TYPE_STATIC,
497 },
498 [OCELOT_SB_REF] = {
499 .cell_size = 1,
500 .threshold_type = DEVLINK_SB_THRESHOLD_TYPE_STATIC,
501 },
502};
503
504
505int ocelot_sb_pool_get(struct ocelot *ocelot, unsigned int sb_index,
506 u16 pool_index,
507 struct devlink_sb_pool_info *pool_info)
508{
509 if (sb_index >= OCELOT_SB_NUM)
510 return -ENODEV;
511 if (pool_index >= OCELOT_SB_POOL_NUM)
512 return -ENODEV;
513
514 *pool_info = ocelot_sb_pool[sb_index];
515 pool_info->size = ocelot->pool_size[sb_index][pool_index];
516 if (pool_index)
517 pool_info->pool_type = DEVLINK_SB_POOL_TYPE_INGRESS;
518 else
519 pool_info->pool_type = DEVLINK_SB_POOL_TYPE_EGRESS;
520
521 return 0;
522}
523EXPORT_SYMBOL(ocelot_sb_pool_get);
524
525
526
527
528
529
530int ocelot_sb_pool_set(struct ocelot *ocelot, unsigned int sb_index,
531 u16 pool_index, u32 size,
532 enum devlink_sb_threshold_type threshold_type,
533 struct netlink_ext_ack *extack)
534{
535 u32 old_pool_size;
536 int err;
537
538 if (sb_index >= OCELOT_SB_NUM) {
539 NL_SET_ERR_MSG_MOD(extack,
540 "Invalid sb, use 0 for buffers and 1 for frame references");
541 return -ENODEV;
542 }
543 if (pool_index >= OCELOT_SB_POOL_NUM) {
544 NL_SET_ERR_MSG_MOD(extack,
545 "Invalid pool, use 0 for ingress and 1 for egress");
546 return -ENODEV;
547 }
548 if (threshold_type != DEVLINK_SB_THRESHOLD_TYPE_STATIC) {
549 NL_SET_ERR_MSG_MOD(extack,
550 "Only static threshold supported");
551 return -EOPNOTSUPP;
552 }
553
554 old_pool_size = ocelot->pool_size[sb_index][pool_index];
555 ocelot->pool_size[sb_index][pool_index] = size;
556
557 err = ocelot_watermark_validate(ocelot, extack);
558 if (err) {
559 ocelot->pool_size[sb_index][pool_index] = old_pool_size;
560 return err;
561 }
562
563 ocelot_setup_sharing_watermarks(ocelot);
564
565 return 0;
566}
567EXPORT_SYMBOL(ocelot_sb_pool_set);
568
569
570int ocelot_sb_port_pool_get(struct ocelot *ocelot, int port,
571 unsigned int sb_index, u16 pool_index,
572 u32 *p_threshold)
573{
574 int wm_index;
575
576 switch (sb_index) {
577 case OCELOT_SB_BUF:
578 if (pool_index == OCELOT_SB_POOL_ING)
579 wm_index = BUF_P_RSRV_I(port);
580 else
581 wm_index = BUF_P_RSRV_E(port);
582 break;
583 case OCELOT_SB_REF:
584 if (pool_index == OCELOT_SB_POOL_ING)
585 wm_index = REF_P_RSRV_I(port);
586 else
587 wm_index = REF_P_RSRV_E(port);
588 break;
589 default:
590 return -ENODEV;
591 }
592
593 *p_threshold = ocelot_wm_read(ocelot, wm_index);
594 *p_threshold *= ocelot_sb_pool[sb_index].cell_size;
595
596 return 0;
597}
598EXPORT_SYMBOL(ocelot_sb_port_pool_get);
599
600
601int ocelot_sb_port_pool_set(struct ocelot *ocelot, int port,
602 unsigned int sb_index, u16 pool_index,
603 u32 threshold, struct netlink_ext_ack *extack)
604{
605 int wm_index, err;
606 u32 old_thr;
607
608 switch (sb_index) {
609 case OCELOT_SB_BUF:
610 if (pool_index == OCELOT_SB_POOL_ING)
611 wm_index = BUF_P_RSRV_I(port);
612 else
613 wm_index = BUF_P_RSRV_E(port);
614 break;
615 case OCELOT_SB_REF:
616 if (pool_index == OCELOT_SB_POOL_ING)
617 wm_index = REF_P_RSRV_I(port);
618 else
619 wm_index = REF_P_RSRV_E(port);
620 break;
621 default:
622 NL_SET_ERR_MSG_MOD(extack, "Invalid shared buffer");
623 return -ENODEV;
624 }
625
626 threshold /= ocelot_sb_pool[sb_index].cell_size;
627
628 old_thr = ocelot_wm_read(ocelot, wm_index);
629 ocelot_wm_write(ocelot, wm_index, threshold);
630
631 err = ocelot_watermark_validate(ocelot, extack);
632 if (err) {
633 ocelot_wm_write(ocelot, wm_index, old_thr);
634 return err;
635 }
636
637 ocelot_setup_sharing_watermarks(ocelot);
638
639 return 0;
640}
641EXPORT_SYMBOL(ocelot_sb_port_pool_set);
642
643
644int ocelot_sb_tc_pool_bind_get(struct ocelot *ocelot, int port,
645 unsigned int sb_index, u16 tc_index,
646 enum devlink_sb_pool_type pool_type,
647 u16 *p_pool_index, u32 *p_threshold)
648{
649 int wm_index;
650
651 switch (sb_index) {
652 case OCELOT_SB_BUF:
653 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
654 wm_index = BUF_Q_RSRV_I(port, tc_index);
655 else
656 wm_index = BUF_Q_RSRV_E(port, tc_index);
657 break;
658 case OCELOT_SB_REF:
659 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
660 wm_index = REF_Q_RSRV_I(port, tc_index);
661 else
662 wm_index = REF_Q_RSRV_E(port, tc_index);
663 break;
664 default:
665 return -ENODEV;
666 }
667
668 *p_threshold = ocelot_wm_read(ocelot, wm_index);
669 *p_threshold *= ocelot_sb_pool[sb_index].cell_size;
670
671 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
672 *p_pool_index = 0;
673 else
674 *p_pool_index = 1;
675
676 return 0;
677}
678EXPORT_SYMBOL(ocelot_sb_tc_pool_bind_get);
679
680
681int ocelot_sb_tc_pool_bind_set(struct ocelot *ocelot, int port,
682 unsigned int sb_index, u16 tc_index,
683 enum devlink_sb_pool_type pool_type,
684 u16 pool_index, u32 threshold,
685 struct netlink_ext_ack *extack)
686{
687 int wm_index, err;
688 u32 old_thr;
689
690
691 if (pool_index == OCELOT_SB_POOL_ING &&
692 pool_type != DEVLINK_SB_POOL_TYPE_INGRESS)
693 return -EINVAL;
694 if (pool_index == OCELOT_SB_POOL_EGR &&
695 pool_type != DEVLINK_SB_POOL_TYPE_EGRESS)
696 return -EINVAL;
697
698 switch (sb_index) {
699 case OCELOT_SB_BUF:
700 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
701 wm_index = BUF_Q_RSRV_I(port, tc_index);
702 else
703 wm_index = BUF_Q_RSRV_E(port, tc_index);
704 break;
705 case OCELOT_SB_REF:
706 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
707 wm_index = REF_Q_RSRV_I(port, tc_index);
708 else
709 wm_index = REF_Q_RSRV_E(port, tc_index);
710 break;
711 default:
712 NL_SET_ERR_MSG_MOD(extack, "Invalid shared buffer");
713 return -ENODEV;
714 }
715
716 threshold /= ocelot_sb_pool[sb_index].cell_size;
717
718 old_thr = ocelot_wm_read(ocelot, wm_index);
719 ocelot_wm_write(ocelot, wm_index, threshold);
720 err = ocelot_watermark_validate(ocelot, extack);
721 if (err) {
722 ocelot_wm_write(ocelot, wm_index, old_thr);
723 return err;
724 }
725
726 ocelot_setup_sharing_watermarks(ocelot);
727
728 return 0;
729}
730EXPORT_SYMBOL(ocelot_sb_tc_pool_bind_set);
731
732
733
734
735int ocelot_sb_occ_snapshot(struct ocelot *ocelot, unsigned int sb_index)
736{
737 return 0;
738}
739EXPORT_SYMBOL(ocelot_sb_occ_snapshot);
740
741
742
743
744int ocelot_sb_occ_max_clear(struct ocelot *ocelot, unsigned int sb_index)
745{
746 u32 inuse, maxuse;
747 int port, prio;
748
749 switch (sb_index) {
750 case OCELOT_SB_BUF:
751 for (port = 0; port <= ocelot->num_phys_ports; port++) {
752 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
753 ocelot_wm_status(ocelot, BUF_Q_RSRV_I(port, prio),
754 &inuse, &maxuse);
755 ocelot_wm_status(ocelot, BUF_Q_RSRV_E(port, prio),
756 &inuse, &maxuse);
757 }
758 ocelot_wm_status(ocelot, BUF_P_RSRV_I(port),
759 &inuse, &maxuse);
760 ocelot_wm_status(ocelot, BUF_P_RSRV_E(port),
761 &inuse, &maxuse);
762 }
763 break;
764 case OCELOT_SB_REF:
765 for (port = 0; port <= ocelot->num_phys_ports; port++) {
766 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
767 ocelot_wm_status(ocelot, REF_Q_RSRV_I(port, prio),
768 &inuse, &maxuse);
769 ocelot_wm_status(ocelot, REF_Q_RSRV_E(port, prio),
770 &inuse, &maxuse);
771 }
772 ocelot_wm_status(ocelot, REF_P_RSRV_I(port),
773 &inuse, &maxuse);
774 ocelot_wm_status(ocelot, REF_P_RSRV_E(port),
775 &inuse, &maxuse);
776 }
777 break;
778 default:
779 return -ENODEV;
780 }
781
782 return 0;
783}
784EXPORT_SYMBOL(ocelot_sb_occ_max_clear);
785
786
787int ocelot_sb_occ_port_pool_get(struct ocelot *ocelot, int port,
788 unsigned int sb_index, u16 pool_index,
789 u32 *p_cur, u32 *p_max)
790{
791 int wm_index;
792
793 switch (sb_index) {
794 case OCELOT_SB_BUF:
795 if (pool_index == OCELOT_SB_POOL_ING)
796 wm_index = BUF_P_RSRV_I(port);
797 else
798 wm_index = BUF_P_RSRV_E(port);
799 break;
800 case OCELOT_SB_REF:
801 if (pool_index == OCELOT_SB_POOL_ING)
802 wm_index = REF_P_RSRV_I(port);
803 else
804 wm_index = REF_P_RSRV_E(port);
805 break;
806 default:
807 return -ENODEV;
808 }
809
810 ocelot_wm_status(ocelot, wm_index, p_cur, p_max);
811 *p_cur *= ocelot_sb_pool[sb_index].cell_size;
812 *p_max *= ocelot_sb_pool[sb_index].cell_size;
813
814 return 0;
815}
816EXPORT_SYMBOL(ocelot_sb_occ_port_pool_get);
817
818
819int ocelot_sb_occ_tc_port_bind_get(struct ocelot *ocelot, int port,
820 unsigned int sb_index, u16 tc_index,
821 enum devlink_sb_pool_type pool_type,
822 u32 *p_cur, u32 *p_max)
823{
824 int wm_index;
825
826 switch (sb_index) {
827 case OCELOT_SB_BUF:
828 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
829 wm_index = BUF_Q_RSRV_I(port, tc_index);
830 else
831 wm_index = BUF_Q_RSRV_E(port, tc_index);
832 break;
833 case OCELOT_SB_REF:
834 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
835 wm_index = REF_Q_RSRV_I(port, tc_index);
836 else
837 wm_index = REF_Q_RSRV_E(port, tc_index);
838 break;
839 default:
840 return -ENODEV;
841 }
842
843 ocelot_wm_status(ocelot, wm_index, p_cur, p_max);
844 *p_cur *= ocelot_sb_pool[sb_index].cell_size;
845 *p_max *= ocelot_sb_pool[sb_index].cell_size;
846
847 return 0;
848}
849EXPORT_SYMBOL(ocelot_sb_occ_tc_port_bind_get);
850
851int ocelot_devlink_sb_register(struct ocelot *ocelot)
852{
853 int err;
854
855 err = devlink_sb_register(ocelot->devlink, OCELOT_SB_BUF,
856 ocelot->packet_buffer_size, 1, 1,
857 OCELOT_NUM_TC, OCELOT_NUM_TC);
858 if (err)
859 return err;
860
861 err = devlink_sb_register(ocelot->devlink, OCELOT_SB_REF,
862 ocelot->num_frame_refs, 1, 1,
863 OCELOT_NUM_TC, OCELOT_NUM_TC);
864 if (err) {
865 devlink_sb_unregister(ocelot->devlink, OCELOT_SB_BUF);
866 return err;
867 }
868
869 ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_ING] = ocelot->packet_buffer_size;
870 ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_EGR] = ocelot->packet_buffer_size;
871 ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_ING] = ocelot->num_frame_refs;
872 ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_EGR] = ocelot->num_frame_refs;
873
874 ocelot_watermark_init(ocelot);
875
876 return 0;
877}
878EXPORT_SYMBOL(ocelot_devlink_sb_register);
879
880void ocelot_devlink_sb_unregister(struct ocelot *ocelot)
881{
882 devlink_sb_unregister(ocelot->devlink, OCELOT_SB_BUF);
883 devlink_sb_unregister(ocelot->devlink, OCELOT_SB_REF);
884}
885EXPORT_SYMBOL(ocelot_devlink_sb_unregister);
886