0001
0002
0003
0004 #include <net/devlink.h>
0005 #include "ocelot.h"
0006
0007
0008
0009
0010
0011
0012
0013 #define OCELOT_RESOURCE_SZ 256
0014 #define OCELOT_NUM_RESOURCES 4
0015
0016 #define BUF_xxxx_I (0 * OCELOT_RESOURCE_SZ)
0017 #define REF_xxxx_I (1 * OCELOT_RESOURCE_SZ)
0018 #define BUF_xxxx_E (2 * OCELOT_RESOURCE_SZ)
0019 #define REF_xxxx_E (3 * OCELOT_RESOURCE_SZ)
0020
0021
0022
0023
0024
0025
0026
0027 #define xxx_Q_RSRV_x 0
0028 #define xxx_PRIO_SHR_x 216
0029 #define xxx_P_RSRV_x 224
0030 #define xxx_COL_SHR_x 254
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 #define BUF_Q_RSRV_E(port, prio) \
0048 (BUF_xxxx_E + xxx_Q_RSRV_x + OCELOT_NUM_TC * (port) + (prio))
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 #define BUF_P_RSRV_E(port) \
0059 (BUF_xxxx_E + xxx_P_RSRV_x + (port))
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 #define BUF_Q_RSRV_I(port, prio) \
0070 (BUF_xxxx_I + xxx_Q_RSRV_x + OCELOT_NUM_TC * (port) + (prio))
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 #define BUF_P_RSRV_I(port) \
0081 (BUF_xxxx_I + xxx_P_RSRV_x + (port))
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 #define REF_Q_RSRV_E(port, prio) \
0092 (REF_xxxx_E + xxx_Q_RSRV_x + OCELOT_NUM_TC * (port) + (prio))
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 #define REF_P_RSRV_E(port) \
0103 (REF_xxxx_E + xxx_P_RSRV_x + (port))
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 #define REF_Q_RSRV_I(port, prio) \
0114 (REF_xxxx_I + xxx_Q_RSRV_x + OCELOT_NUM_TC * (port) + (prio))
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 #define REF_P_RSRV_I(port) \
0125 (REF_xxxx_I + xxx_P_RSRV_x + (port))
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 #define BUF_PRIO_SHR_E(prio) \
0142 (BUF_xxxx_E + xxx_PRIO_SHR_x + (prio))
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 #define BUF_COL_SHR_E(dp) \
0153 (BUF_xxxx_E + xxx_COL_SHR_x + (1 - (dp)))
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 #define BUF_PRIO_SHR_I(prio) \
0164 (BUF_xxxx_I + xxx_PRIO_SHR_x + (prio))
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174 #define BUF_COL_SHR_I(dp) \
0175 (BUF_xxxx_I + xxx_COL_SHR_x + (1 - (dp)))
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 #define REF_PRIO_SHR_E(prio) \
0186 (REF_xxxx_E + xxx_PRIO_SHR_x + (prio))
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 #define REF_COL_SHR_E(dp) \
0197 (REF_xxxx_E + xxx_COL_SHR_x + (1 - (dp)))
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207 #define REF_PRIO_SHR_I(prio) \
0208 (REF_xxxx_I + xxx_PRIO_SHR_x + (prio))
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 #define REF_COL_SHR_I(dp) \
0219 (REF_xxxx_I + xxx_COL_SHR_x + (1 - (dp)))
0220
0221 static u32 ocelot_wm_read(struct ocelot *ocelot, int index)
0222 {
0223 int wm = ocelot_read_gix(ocelot, QSYS_RES_CFG, index);
0224
0225 return ocelot->ops->wm_dec(wm);
0226 }
0227
0228 static void ocelot_wm_write(struct ocelot *ocelot, int index, u32 val)
0229 {
0230 u32 wm = ocelot->ops->wm_enc(val);
0231
0232 ocelot_write_gix(ocelot, wm, QSYS_RES_CFG, index);
0233 }
0234
0235 static void ocelot_wm_status(struct ocelot *ocelot, int index, u32 *inuse,
0236 u32 *maxuse)
0237 {
0238 int res_stat = ocelot_read_gix(ocelot, QSYS_RES_STAT, index);
0239
0240 return ocelot->ops->wm_stat(res_stat, inuse, maxuse);
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252 static void ocelot_disable_reservation_watermarks(struct ocelot *ocelot,
0253 int port)
0254 {
0255 int prio;
0256
0257 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
0258 ocelot_wm_write(ocelot, BUF_Q_RSRV_I(port, prio), 0);
0259 ocelot_wm_write(ocelot, BUF_Q_RSRV_E(port, prio), 0);
0260 ocelot_wm_write(ocelot, REF_Q_RSRV_I(port, prio), 0);
0261 ocelot_wm_write(ocelot, REF_Q_RSRV_E(port, prio), 0);
0262 }
0263
0264 ocelot_wm_write(ocelot, BUF_P_RSRV_I(port), 0);
0265 ocelot_wm_write(ocelot, BUF_P_RSRV_E(port), 0);
0266 ocelot_wm_write(ocelot, REF_P_RSRV_I(port), 0);
0267 ocelot_wm_write(ocelot, REF_P_RSRV_E(port), 0);
0268 }
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289 static void ocelot_disable_tc_sharing_watermarks(struct ocelot *ocelot)
0290 {
0291 int prio;
0292
0293 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
0294 ocelot_wm_write(ocelot, BUF_PRIO_SHR_I(prio), 0);
0295 ocelot_wm_write(ocelot, BUF_PRIO_SHR_E(prio), 0);
0296 ocelot_wm_write(ocelot, REF_PRIO_SHR_I(prio), 0);
0297 ocelot_wm_write(ocelot, REF_PRIO_SHR_E(prio), 0);
0298 }
0299 }
0300
0301 static void ocelot_get_buf_rsrv(struct ocelot *ocelot, u32 *buf_rsrv_i,
0302 u32 *buf_rsrv_e)
0303 {
0304 int port, prio;
0305
0306 *buf_rsrv_i = 0;
0307 *buf_rsrv_e = 0;
0308
0309 for (port = 0; port <= ocelot->num_phys_ports; port++) {
0310 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
0311 *buf_rsrv_i += ocelot_wm_read(ocelot,
0312 BUF_Q_RSRV_I(port, prio));
0313 *buf_rsrv_e += ocelot_wm_read(ocelot,
0314 BUF_Q_RSRV_E(port, prio));
0315 }
0316
0317 *buf_rsrv_i += ocelot_wm_read(ocelot, BUF_P_RSRV_I(port));
0318 *buf_rsrv_e += ocelot_wm_read(ocelot, BUF_P_RSRV_E(port));
0319 }
0320
0321 *buf_rsrv_i *= OCELOT_BUFFER_CELL_SZ;
0322 *buf_rsrv_e *= OCELOT_BUFFER_CELL_SZ;
0323 }
0324
0325 static void ocelot_get_ref_rsrv(struct ocelot *ocelot, u32 *ref_rsrv_i,
0326 u32 *ref_rsrv_e)
0327 {
0328 int port, prio;
0329
0330 *ref_rsrv_i = 0;
0331 *ref_rsrv_e = 0;
0332
0333 for (port = 0; port <= ocelot->num_phys_ports; port++) {
0334 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
0335 *ref_rsrv_i += ocelot_wm_read(ocelot,
0336 REF_Q_RSRV_I(port, prio));
0337 *ref_rsrv_e += ocelot_wm_read(ocelot,
0338 REF_Q_RSRV_E(port, prio));
0339 }
0340
0341 *ref_rsrv_i += ocelot_wm_read(ocelot, REF_P_RSRV_I(port));
0342 *ref_rsrv_e += ocelot_wm_read(ocelot, REF_P_RSRV_E(port));
0343 }
0344 }
0345
0346
0347
0348
0349 static void ocelot_setup_sharing_watermarks(struct ocelot *ocelot)
0350 {
0351 u32 buf_rsrv_i, buf_rsrv_e;
0352 u32 ref_rsrv_i, ref_rsrv_e;
0353 u32 buf_shr_i, buf_shr_e;
0354 u32 ref_shr_i, ref_shr_e;
0355
0356 ocelot_get_buf_rsrv(ocelot, &buf_rsrv_i, &buf_rsrv_e);
0357 ocelot_get_ref_rsrv(ocelot, &ref_rsrv_i, &ref_rsrv_e);
0358
0359 buf_shr_i = ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_ING] -
0360 buf_rsrv_i;
0361 buf_shr_e = ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_EGR] -
0362 buf_rsrv_e;
0363 ref_shr_i = ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_ING] -
0364 ref_rsrv_i;
0365 ref_shr_e = ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_EGR] -
0366 ref_rsrv_e;
0367
0368 buf_shr_i /= OCELOT_BUFFER_CELL_SZ;
0369 buf_shr_e /= OCELOT_BUFFER_CELL_SZ;
0370
0371 ocelot_wm_write(ocelot, BUF_COL_SHR_I(0), buf_shr_i);
0372 ocelot_wm_write(ocelot, BUF_COL_SHR_E(0), buf_shr_e);
0373 ocelot_wm_write(ocelot, REF_COL_SHR_E(0), ref_shr_e);
0374 ocelot_wm_write(ocelot, REF_COL_SHR_I(0), ref_shr_i);
0375 ocelot_wm_write(ocelot, BUF_COL_SHR_I(1), 0);
0376 ocelot_wm_write(ocelot, BUF_COL_SHR_E(1), 0);
0377 ocelot_wm_write(ocelot, REF_COL_SHR_E(1), 0);
0378 ocelot_wm_write(ocelot, REF_COL_SHR_I(1), 0);
0379 }
0380
0381
0382 static int ocelot_watermark_validate(struct ocelot *ocelot,
0383 struct netlink_ext_ack *extack)
0384 {
0385 u32 buf_rsrv_i, buf_rsrv_e;
0386 u32 ref_rsrv_i, ref_rsrv_e;
0387
0388 ocelot_get_buf_rsrv(ocelot, &buf_rsrv_i, &buf_rsrv_e);
0389 ocelot_get_ref_rsrv(ocelot, &ref_rsrv_i, &ref_rsrv_e);
0390
0391 if (buf_rsrv_i > ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_ING]) {
0392 NL_SET_ERR_MSG_MOD(extack,
0393 "Ingress frame reservations exceed pool size");
0394 return -ERANGE;
0395 }
0396 if (buf_rsrv_e > ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_EGR]) {
0397 NL_SET_ERR_MSG_MOD(extack,
0398 "Egress frame reservations exceed pool size");
0399 return -ERANGE;
0400 }
0401 if (ref_rsrv_i > ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_ING]) {
0402 NL_SET_ERR_MSG_MOD(extack,
0403 "Ingress reference reservations exceed pool size");
0404 return -ERANGE;
0405 }
0406 if (ref_rsrv_e > ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_EGR]) {
0407 NL_SET_ERR_MSG_MOD(extack,
0408 "Egress reference reservations exceed pool size");
0409 return -ERANGE;
0410 }
0411
0412 return 0;
0413 }
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476 static void ocelot_watermark_init(struct ocelot *ocelot)
0477 {
0478 int all_tcs = GENMASK(OCELOT_NUM_TC - 1, 0);
0479 int port;
0480
0481 ocelot_write(ocelot, all_tcs, QSYS_RES_QOS_MODE);
0482
0483 for (port = 0; port <= ocelot->num_phys_ports; port++)
0484 ocelot_disable_reservation_watermarks(ocelot, port);
0485
0486 ocelot_disable_tc_sharing_watermarks(ocelot);
0487 ocelot_setup_sharing_watermarks(ocelot);
0488 }
0489
0490
0491
0492
0493 static const struct devlink_sb_pool_info ocelot_sb_pool[] = {
0494 [OCELOT_SB_BUF] = {
0495 .cell_size = OCELOT_BUFFER_CELL_SZ,
0496 .threshold_type = DEVLINK_SB_THRESHOLD_TYPE_STATIC,
0497 },
0498 [OCELOT_SB_REF] = {
0499 .cell_size = 1,
0500 .threshold_type = DEVLINK_SB_THRESHOLD_TYPE_STATIC,
0501 },
0502 };
0503
0504
0505 int ocelot_sb_pool_get(struct ocelot *ocelot, unsigned int sb_index,
0506 u16 pool_index,
0507 struct devlink_sb_pool_info *pool_info)
0508 {
0509 if (sb_index >= OCELOT_SB_NUM)
0510 return -ENODEV;
0511 if (pool_index >= OCELOT_SB_POOL_NUM)
0512 return -ENODEV;
0513
0514 *pool_info = ocelot_sb_pool[sb_index];
0515 pool_info->size = ocelot->pool_size[sb_index][pool_index];
0516 if (pool_index)
0517 pool_info->pool_type = DEVLINK_SB_POOL_TYPE_INGRESS;
0518 else
0519 pool_info->pool_type = DEVLINK_SB_POOL_TYPE_EGRESS;
0520
0521 return 0;
0522 }
0523 EXPORT_SYMBOL(ocelot_sb_pool_get);
0524
0525
0526
0527
0528
0529
0530 int ocelot_sb_pool_set(struct ocelot *ocelot, unsigned int sb_index,
0531 u16 pool_index, u32 size,
0532 enum devlink_sb_threshold_type threshold_type,
0533 struct netlink_ext_ack *extack)
0534 {
0535 u32 old_pool_size;
0536 int err;
0537
0538 if (sb_index >= OCELOT_SB_NUM) {
0539 NL_SET_ERR_MSG_MOD(extack,
0540 "Invalid sb, use 0 for buffers and 1 for frame references");
0541 return -ENODEV;
0542 }
0543 if (pool_index >= OCELOT_SB_POOL_NUM) {
0544 NL_SET_ERR_MSG_MOD(extack,
0545 "Invalid pool, use 0 for ingress and 1 for egress");
0546 return -ENODEV;
0547 }
0548 if (threshold_type != DEVLINK_SB_THRESHOLD_TYPE_STATIC) {
0549 NL_SET_ERR_MSG_MOD(extack,
0550 "Only static threshold supported");
0551 return -EOPNOTSUPP;
0552 }
0553
0554 old_pool_size = ocelot->pool_size[sb_index][pool_index];
0555 ocelot->pool_size[sb_index][pool_index] = size;
0556
0557 err = ocelot_watermark_validate(ocelot, extack);
0558 if (err) {
0559 ocelot->pool_size[sb_index][pool_index] = old_pool_size;
0560 return err;
0561 }
0562
0563 ocelot_setup_sharing_watermarks(ocelot);
0564
0565 return 0;
0566 }
0567 EXPORT_SYMBOL(ocelot_sb_pool_set);
0568
0569
0570 int ocelot_sb_port_pool_get(struct ocelot *ocelot, int port,
0571 unsigned int sb_index, u16 pool_index,
0572 u32 *p_threshold)
0573 {
0574 int wm_index;
0575
0576 switch (sb_index) {
0577 case OCELOT_SB_BUF:
0578 if (pool_index == OCELOT_SB_POOL_ING)
0579 wm_index = BUF_P_RSRV_I(port);
0580 else
0581 wm_index = BUF_P_RSRV_E(port);
0582 break;
0583 case OCELOT_SB_REF:
0584 if (pool_index == OCELOT_SB_POOL_ING)
0585 wm_index = REF_P_RSRV_I(port);
0586 else
0587 wm_index = REF_P_RSRV_E(port);
0588 break;
0589 default:
0590 return -ENODEV;
0591 }
0592
0593 *p_threshold = ocelot_wm_read(ocelot, wm_index);
0594 *p_threshold *= ocelot_sb_pool[sb_index].cell_size;
0595
0596 return 0;
0597 }
0598 EXPORT_SYMBOL(ocelot_sb_port_pool_get);
0599
0600
0601 int ocelot_sb_port_pool_set(struct ocelot *ocelot, int port,
0602 unsigned int sb_index, u16 pool_index,
0603 u32 threshold, struct netlink_ext_ack *extack)
0604 {
0605 int wm_index, err;
0606 u32 old_thr;
0607
0608 switch (sb_index) {
0609 case OCELOT_SB_BUF:
0610 if (pool_index == OCELOT_SB_POOL_ING)
0611 wm_index = BUF_P_RSRV_I(port);
0612 else
0613 wm_index = BUF_P_RSRV_E(port);
0614 break;
0615 case OCELOT_SB_REF:
0616 if (pool_index == OCELOT_SB_POOL_ING)
0617 wm_index = REF_P_RSRV_I(port);
0618 else
0619 wm_index = REF_P_RSRV_E(port);
0620 break;
0621 default:
0622 NL_SET_ERR_MSG_MOD(extack, "Invalid shared buffer");
0623 return -ENODEV;
0624 }
0625
0626 threshold /= ocelot_sb_pool[sb_index].cell_size;
0627
0628 old_thr = ocelot_wm_read(ocelot, wm_index);
0629 ocelot_wm_write(ocelot, wm_index, threshold);
0630
0631 err = ocelot_watermark_validate(ocelot, extack);
0632 if (err) {
0633 ocelot_wm_write(ocelot, wm_index, old_thr);
0634 return err;
0635 }
0636
0637 ocelot_setup_sharing_watermarks(ocelot);
0638
0639 return 0;
0640 }
0641 EXPORT_SYMBOL(ocelot_sb_port_pool_set);
0642
0643
0644 int ocelot_sb_tc_pool_bind_get(struct ocelot *ocelot, int port,
0645 unsigned int sb_index, u16 tc_index,
0646 enum devlink_sb_pool_type pool_type,
0647 u16 *p_pool_index, u32 *p_threshold)
0648 {
0649 int wm_index;
0650
0651 switch (sb_index) {
0652 case OCELOT_SB_BUF:
0653 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
0654 wm_index = BUF_Q_RSRV_I(port, tc_index);
0655 else
0656 wm_index = BUF_Q_RSRV_E(port, tc_index);
0657 break;
0658 case OCELOT_SB_REF:
0659 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
0660 wm_index = REF_Q_RSRV_I(port, tc_index);
0661 else
0662 wm_index = REF_Q_RSRV_E(port, tc_index);
0663 break;
0664 default:
0665 return -ENODEV;
0666 }
0667
0668 *p_threshold = ocelot_wm_read(ocelot, wm_index);
0669 *p_threshold *= ocelot_sb_pool[sb_index].cell_size;
0670
0671 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
0672 *p_pool_index = 0;
0673 else
0674 *p_pool_index = 1;
0675
0676 return 0;
0677 }
0678 EXPORT_SYMBOL(ocelot_sb_tc_pool_bind_get);
0679
0680
0681 int ocelot_sb_tc_pool_bind_set(struct ocelot *ocelot, int port,
0682 unsigned int sb_index, u16 tc_index,
0683 enum devlink_sb_pool_type pool_type,
0684 u16 pool_index, u32 threshold,
0685 struct netlink_ext_ack *extack)
0686 {
0687 int wm_index, err;
0688 u32 old_thr;
0689
0690
0691 if (pool_index == OCELOT_SB_POOL_ING &&
0692 pool_type != DEVLINK_SB_POOL_TYPE_INGRESS)
0693 return -EINVAL;
0694 if (pool_index == OCELOT_SB_POOL_EGR &&
0695 pool_type != DEVLINK_SB_POOL_TYPE_EGRESS)
0696 return -EINVAL;
0697
0698 switch (sb_index) {
0699 case OCELOT_SB_BUF:
0700 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
0701 wm_index = BUF_Q_RSRV_I(port, tc_index);
0702 else
0703 wm_index = BUF_Q_RSRV_E(port, tc_index);
0704 break;
0705 case OCELOT_SB_REF:
0706 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
0707 wm_index = REF_Q_RSRV_I(port, tc_index);
0708 else
0709 wm_index = REF_Q_RSRV_E(port, tc_index);
0710 break;
0711 default:
0712 NL_SET_ERR_MSG_MOD(extack, "Invalid shared buffer");
0713 return -ENODEV;
0714 }
0715
0716 threshold /= ocelot_sb_pool[sb_index].cell_size;
0717
0718 old_thr = ocelot_wm_read(ocelot, wm_index);
0719 ocelot_wm_write(ocelot, wm_index, threshold);
0720 err = ocelot_watermark_validate(ocelot, extack);
0721 if (err) {
0722 ocelot_wm_write(ocelot, wm_index, old_thr);
0723 return err;
0724 }
0725
0726 ocelot_setup_sharing_watermarks(ocelot);
0727
0728 return 0;
0729 }
0730 EXPORT_SYMBOL(ocelot_sb_tc_pool_bind_set);
0731
0732
0733
0734
0735 int ocelot_sb_occ_snapshot(struct ocelot *ocelot, unsigned int sb_index)
0736 {
0737 return 0;
0738 }
0739 EXPORT_SYMBOL(ocelot_sb_occ_snapshot);
0740
0741
0742
0743
0744 int ocelot_sb_occ_max_clear(struct ocelot *ocelot, unsigned int sb_index)
0745 {
0746 u32 inuse, maxuse;
0747 int port, prio;
0748
0749 switch (sb_index) {
0750 case OCELOT_SB_BUF:
0751 for (port = 0; port <= ocelot->num_phys_ports; port++) {
0752 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
0753 ocelot_wm_status(ocelot, BUF_Q_RSRV_I(port, prio),
0754 &inuse, &maxuse);
0755 ocelot_wm_status(ocelot, BUF_Q_RSRV_E(port, prio),
0756 &inuse, &maxuse);
0757 }
0758 ocelot_wm_status(ocelot, BUF_P_RSRV_I(port),
0759 &inuse, &maxuse);
0760 ocelot_wm_status(ocelot, BUF_P_RSRV_E(port),
0761 &inuse, &maxuse);
0762 }
0763 break;
0764 case OCELOT_SB_REF:
0765 for (port = 0; port <= ocelot->num_phys_ports; port++) {
0766 for (prio = 0; prio < OCELOT_NUM_TC; prio++) {
0767 ocelot_wm_status(ocelot, REF_Q_RSRV_I(port, prio),
0768 &inuse, &maxuse);
0769 ocelot_wm_status(ocelot, REF_Q_RSRV_E(port, prio),
0770 &inuse, &maxuse);
0771 }
0772 ocelot_wm_status(ocelot, REF_P_RSRV_I(port),
0773 &inuse, &maxuse);
0774 ocelot_wm_status(ocelot, REF_P_RSRV_E(port),
0775 &inuse, &maxuse);
0776 }
0777 break;
0778 default:
0779 return -ENODEV;
0780 }
0781
0782 return 0;
0783 }
0784 EXPORT_SYMBOL(ocelot_sb_occ_max_clear);
0785
0786
0787 int ocelot_sb_occ_port_pool_get(struct ocelot *ocelot, int port,
0788 unsigned int sb_index, u16 pool_index,
0789 u32 *p_cur, u32 *p_max)
0790 {
0791 int wm_index;
0792
0793 switch (sb_index) {
0794 case OCELOT_SB_BUF:
0795 if (pool_index == OCELOT_SB_POOL_ING)
0796 wm_index = BUF_P_RSRV_I(port);
0797 else
0798 wm_index = BUF_P_RSRV_E(port);
0799 break;
0800 case OCELOT_SB_REF:
0801 if (pool_index == OCELOT_SB_POOL_ING)
0802 wm_index = REF_P_RSRV_I(port);
0803 else
0804 wm_index = REF_P_RSRV_E(port);
0805 break;
0806 default:
0807 return -ENODEV;
0808 }
0809
0810 ocelot_wm_status(ocelot, wm_index, p_cur, p_max);
0811 *p_cur *= ocelot_sb_pool[sb_index].cell_size;
0812 *p_max *= ocelot_sb_pool[sb_index].cell_size;
0813
0814 return 0;
0815 }
0816 EXPORT_SYMBOL(ocelot_sb_occ_port_pool_get);
0817
0818
0819 int ocelot_sb_occ_tc_port_bind_get(struct ocelot *ocelot, int port,
0820 unsigned int sb_index, u16 tc_index,
0821 enum devlink_sb_pool_type pool_type,
0822 u32 *p_cur, u32 *p_max)
0823 {
0824 int wm_index;
0825
0826 switch (sb_index) {
0827 case OCELOT_SB_BUF:
0828 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
0829 wm_index = BUF_Q_RSRV_I(port, tc_index);
0830 else
0831 wm_index = BUF_Q_RSRV_E(port, tc_index);
0832 break;
0833 case OCELOT_SB_REF:
0834 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
0835 wm_index = REF_Q_RSRV_I(port, tc_index);
0836 else
0837 wm_index = REF_Q_RSRV_E(port, tc_index);
0838 break;
0839 default:
0840 return -ENODEV;
0841 }
0842
0843 ocelot_wm_status(ocelot, wm_index, p_cur, p_max);
0844 *p_cur *= ocelot_sb_pool[sb_index].cell_size;
0845 *p_max *= ocelot_sb_pool[sb_index].cell_size;
0846
0847 return 0;
0848 }
0849 EXPORT_SYMBOL(ocelot_sb_occ_tc_port_bind_get);
0850
0851 int ocelot_devlink_sb_register(struct ocelot *ocelot)
0852 {
0853 int err;
0854
0855 err = devlink_sb_register(ocelot->devlink, OCELOT_SB_BUF,
0856 ocelot->packet_buffer_size, 1, 1,
0857 OCELOT_NUM_TC, OCELOT_NUM_TC);
0858 if (err)
0859 return err;
0860
0861 err = devlink_sb_register(ocelot->devlink, OCELOT_SB_REF,
0862 ocelot->num_frame_refs, 1, 1,
0863 OCELOT_NUM_TC, OCELOT_NUM_TC);
0864 if (err) {
0865 devlink_sb_unregister(ocelot->devlink, OCELOT_SB_BUF);
0866 return err;
0867 }
0868
0869 ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_ING] = ocelot->packet_buffer_size;
0870 ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_EGR] = ocelot->packet_buffer_size;
0871 ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_ING] = ocelot->num_frame_refs;
0872 ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_EGR] = ocelot->num_frame_refs;
0873
0874 ocelot_watermark_init(ocelot);
0875
0876 return 0;
0877 }
0878 EXPORT_SYMBOL(ocelot_devlink_sb_register);
0879
0880 void ocelot_devlink_sb_unregister(struct ocelot *ocelot)
0881 {
0882 devlink_sb_unregister(ocelot->devlink, OCELOT_SB_BUF);
0883 devlink_sb_unregister(ocelot->devlink, OCELOT_SB_REF);
0884 }
0885 EXPORT_SYMBOL(ocelot_devlink_sb_unregister);