Lines Matching +full:ocelot +full:- +full:1
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /* Copyright 2020-2021 NXP
5 #include "ocelot.h"
9 * Resource 1: Frame references tracked per source port
17 #define REF_xxxx_I (1 * OCELOT_RESOURCE_SZ)
33 * ----------------------
128 * ------------------
153 (BUF_xxxx_E + xxx_COL_SHR_x + (1 - (dp)))
175 (BUF_xxxx_I + xxx_COL_SHR_x + (1 - (dp)))
197 (REF_xxxx_E + xxx_COL_SHR_x + (1 - (dp)))
219 (REF_xxxx_I + xxx_COL_SHR_x + (1 - (dp)))
221 static u32 ocelot_wm_read(struct ocelot *ocelot, int index) in ocelot_wm_read() argument
223 int wm = ocelot_read_gix(ocelot, QSYS_RES_CFG, index); in ocelot_wm_read()
225 return ocelot->ops->wm_dec(wm); in ocelot_wm_read()
228 static void ocelot_wm_write(struct ocelot *ocelot, int index, u32 val) in ocelot_wm_write() argument
230 u32 wm = ocelot->ops->wm_enc(val); in ocelot_wm_write()
232 ocelot_write_gix(ocelot, wm, QSYS_RES_CFG, index); in ocelot_wm_write()
235 static void ocelot_wm_status(struct ocelot *ocelot, int index, u32 *inuse, in ocelot_wm_status() argument
238 int res_stat = ocelot_read_gix(ocelot, QSYS_RES_STAT, index); in ocelot_wm_status()
240 return ocelot->ops->wm_stat(res_stat, inuse, maxuse); in ocelot_wm_status()
250 * and per port-tc through devlink-sb.
252 static void ocelot_disable_reservation_watermarks(struct ocelot *ocelot, in ocelot_disable_reservation_watermarks() argument
258 ocelot_wm_write(ocelot, BUF_Q_RSRV_I(port, prio), 0); in ocelot_disable_reservation_watermarks()
259 ocelot_wm_write(ocelot, BUF_Q_RSRV_E(port, prio), 0); in ocelot_disable_reservation_watermarks()
260 ocelot_wm_write(ocelot, REF_Q_RSRV_I(port, prio), 0); in ocelot_disable_reservation_watermarks()
261 ocelot_wm_write(ocelot, REF_Q_RSRV_E(port, prio), 0); in ocelot_disable_reservation_watermarks()
264 ocelot_wm_write(ocelot, BUF_P_RSRV_I(port), 0); in ocelot_disable_reservation_watermarks()
265 ocelot_wm_write(ocelot, BUF_P_RSRV_E(port), 0); in ocelot_disable_reservation_watermarks()
266 ocelot_wm_write(ocelot, REF_P_RSRV_I(port), 0); in ocelot_disable_reservation_watermarks()
267 ocelot_wm_write(ocelot, REF_P_RSRV_E(port), 0); in ocelot_disable_reservation_watermarks()
277 * (1) There's a risk that we overcommit the resources if we configure
278 * (a) all 8 per-TC sharing watermarks to the max
279 * (b) all 2 per-color sharing watermarks to the max
281 * (a) all 8 per-TC sharing watermarks to "max / 8"
282 * (b) all 2 per-color sharing watermarks to "max / 2"
285 * sharing watermark for drop priority 0. So frames with drop priority set to 1
287 * the port and port-TC reservations are not exceeded.
289 static void ocelot_disable_tc_sharing_watermarks(struct ocelot *ocelot) in ocelot_disable_tc_sharing_watermarks() argument
294 ocelot_wm_write(ocelot, BUF_PRIO_SHR_I(prio), 0); in ocelot_disable_tc_sharing_watermarks()
295 ocelot_wm_write(ocelot, BUF_PRIO_SHR_E(prio), 0); in ocelot_disable_tc_sharing_watermarks()
296 ocelot_wm_write(ocelot, REF_PRIO_SHR_I(prio), 0); in ocelot_disable_tc_sharing_watermarks()
297 ocelot_wm_write(ocelot, REF_PRIO_SHR_E(prio), 0); in ocelot_disable_tc_sharing_watermarks()
301 static void ocelot_get_buf_rsrv(struct ocelot *ocelot, u32 *buf_rsrv_i, in ocelot_get_buf_rsrv() argument
309 for (port = 0; port <= ocelot->num_phys_ports; port++) { in ocelot_get_buf_rsrv()
311 *buf_rsrv_i += ocelot_wm_read(ocelot, in ocelot_get_buf_rsrv()
313 *buf_rsrv_e += ocelot_wm_read(ocelot, in ocelot_get_buf_rsrv()
317 *buf_rsrv_i += ocelot_wm_read(ocelot, BUF_P_RSRV_I(port)); in ocelot_get_buf_rsrv()
318 *buf_rsrv_e += ocelot_wm_read(ocelot, BUF_P_RSRV_E(port)); in ocelot_get_buf_rsrv()
325 static void ocelot_get_ref_rsrv(struct ocelot *ocelot, u32 *ref_rsrv_i, in ocelot_get_ref_rsrv() argument
333 for (port = 0; port <= ocelot->num_phys_ports; port++) { in ocelot_get_ref_rsrv()
335 *ref_rsrv_i += ocelot_wm_read(ocelot, in ocelot_get_ref_rsrv()
337 *ref_rsrv_e += ocelot_wm_read(ocelot, in ocelot_get_ref_rsrv()
341 *ref_rsrv_i += ocelot_wm_read(ocelot, REF_P_RSRV_I(port)); in ocelot_get_ref_rsrv()
342 *ref_rsrv_e += ocelot_wm_read(ocelot, REF_P_RSRV_E(port)); in ocelot_get_ref_rsrv()
349 static void ocelot_setup_sharing_watermarks(struct ocelot *ocelot) in ocelot_setup_sharing_watermarks() argument
356 ocelot_get_buf_rsrv(ocelot, &buf_rsrv_i, &buf_rsrv_e); in ocelot_setup_sharing_watermarks()
357 ocelot_get_ref_rsrv(ocelot, &ref_rsrv_i, &ref_rsrv_e); in ocelot_setup_sharing_watermarks()
359 buf_shr_i = ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_ING] - in ocelot_setup_sharing_watermarks()
361 buf_shr_e = ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_EGR] - in ocelot_setup_sharing_watermarks()
363 ref_shr_i = ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_ING] - in ocelot_setup_sharing_watermarks()
365 ref_shr_e = ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_EGR] - in ocelot_setup_sharing_watermarks()
371 ocelot_wm_write(ocelot, BUF_COL_SHR_I(0), buf_shr_i); in ocelot_setup_sharing_watermarks()
372 ocelot_wm_write(ocelot, BUF_COL_SHR_E(0), buf_shr_e); in ocelot_setup_sharing_watermarks()
373 ocelot_wm_write(ocelot, REF_COL_SHR_E(0), ref_shr_e); in ocelot_setup_sharing_watermarks()
374 ocelot_wm_write(ocelot, REF_COL_SHR_I(0), ref_shr_i); in ocelot_setup_sharing_watermarks()
375 ocelot_wm_write(ocelot, BUF_COL_SHR_I(1), 0); in ocelot_setup_sharing_watermarks()
376 ocelot_wm_write(ocelot, BUF_COL_SHR_E(1), 0); in ocelot_setup_sharing_watermarks()
377 ocelot_wm_write(ocelot, REF_COL_SHR_E(1), 0); in ocelot_setup_sharing_watermarks()
378 ocelot_wm_write(ocelot, REF_COL_SHR_I(1), 0); in ocelot_setup_sharing_watermarks()
382 static int ocelot_watermark_validate(struct ocelot *ocelot, in ocelot_watermark_validate() argument
388 ocelot_get_buf_rsrv(ocelot, &buf_rsrv_i, &buf_rsrv_e); in ocelot_watermark_validate()
389 ocelot_get_ref_rsrv(ocelot, &ref_rsrv_i, &ref_rsrv_e); in ocelot_watermark_validate()
391 if (buf_rsrv_i > ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_ING]) { in ocelot_watermark_validate()
394 return -ERANGE; in ocelot_watermark_validate()
396 if (buf_rsrv_e > ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_EGR]) { in ocelot_watermark_validate()
399 return -ERANGE; in ocelot_watermark_validate()
401 if (ref_rsrv_i > ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_ING]) { in ocelot_watermark_validate()
404 return -ERANGE; in ocelot_watermark_validate()
406 if (ref_rsrv_e > ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_EGR]) { in ocelot_watermark_validate()
409 return -ERANGE; in ocelot_watermark_validate()
420 * +--------------------+--------------------+--------------------+
428 *(src port, prio) -+ (dst port, prio) -+ (src port, prio) -+ (dst port, prio) -+
433 * (src port) ----+ (dst port) ----+ (src port) ----+ (dst port) -----+
438 * (prio) ------+ (prio) ------+ (prio) ------+ (prio) -------+
443 * (dp) -------+ (dp) -------+ (dp) -------+ (dp) --------+
450 * +-----+----+ +-----+----+ +-----+----+ +-----+-----+
452 * +-------> OR <-------+ +-------> OR <-------+
455 * +----------------> AND <-----------------+
460 * We are modeling each of the 4 parallel lookups as a devlink-sb pool.
464 * The following watermarks are controlled explicitly through devlink-sb:
467 * The following watermarks are controlled implicitly through devlink-sb:
476 static void ocelot_watermark_init(struct ocelot *ocelot) in ocelot_watermark_init() argument
478 int all_tcs = GENMASK(OCELOT_NUM_TC - 1, 0); in ocelot_watermark_init()
481 ocelot_write(ocelot, all_tcs, QSYS_RES_QOS_MODE); in ocelot_watermark_init()
483 for (port = 0; port <= ocelot->num_phys_ports; port++) in ocelot_watermark_init()
484 ocelot_disable_reservation_watermarks(ocelot, port); in ocelot_watermark_init()
486 ocelot_disable_tc_sharing_watermarks(ocelot); in ocelot_watermark_init()
487 ocelot_setup_sharing_watermarks(ocelot); in ocelot_watermark_init()
491 * Bit 8: Unit; 0:1, 1:16
492 * Bit 7-0: Value to be multiplied with unit
530 .cell_size = 1,
536 int ocelot_sb_pool_get(struct ocelot *ocelot, unsigned int sb_index, in ocelot_sb_pool_get() argument
541 return -ENODEV; in ocelot_sb_pool_get()
543 return -ENODEV; in ocelot_sb_pool_get()
546 pool_info->size = ocelot->pool_size[sb_index][pool_index]; in ocelot_sb_pool_get()
548 pool_info->pool_type = DEVLINK_SB_POOL_TYPE_INGRESS; in ocelot_sb_pool_get()
550 pool_info->pool_type = DEVLINK_SB_POOL_TYPE_EGRESS; in ocelot_sb_pool_get()
558 * the values for the port and port-tc reservations, is written into the
561 int ocelot_sb_pool_set(struct ocelot *ocelot, unsigned int sb_index, in ocelot_sb_pool_set() argument
571 "Invalid sb, use 0 for buffers and 1 for frame references"); in ocelot_sb_pool_set()
572 return -ENODEV; in ocelot_sb_pool_set()
576 "Invalid pool, use 0 for ingress and 1 for egress"); in ocelot_sb_pool_set()
577 return -ENODEV; in ocelot_sb_pool_set()
582 return -EOPNOTSUPP; in ocelot_sb_pool_set()
585 old_pool_size = ocelot->pool_size[sb_index][pool_index]; in ocelot_sb_pool_set()
586 ocelot->pool_size[sb_index][pool_index] = size; in ocelot_sb_pool_set()
588 err = ocelot_watermark_validate(ocelot, extack); in ocelot_sb_pool_set()
590 ocelot->pool_size[sb_index][pool_index] = old_pool_size; in ocelot_sb_pool_set()
594 ocelot_setup_sharing_watermarks(ocelot); in ocelot_sb_pool_set()
601 int ocelot_sb_port_pool_get(struct ocelot *ocelot, int port, in ocelot_sb_port_pool_get() argument
621 return -ENODEV; in ocelot_sb_port_pool_get()
624 *p_threshold = ocelot_wm_read(ocelot, wm_index); in ocelot_sb_port_pool_get()
631 /* This configures the P_RSRV per-port reserved resource watermark */
632 int ocelot_sb_port_pool_set(struct ocelot *ocelot, int port, in ocelot_sb_port_pool_set() argument
654 return -ENODEV; in ocelot_sb_port_pool_set()
659 old_thr = ocelot_wm_read(ocelot, wm_index); in ocelot_sb_port_pool_set()
660 ocelot_wm_write(ocelot, wm_index, threshold); in ocelot_sb_port_pool_set()
662 err = ocelot_watermark_validate(ocelot, extack); in ocelot_sb_port_pool_set()
664 ocelot_wm_write(ocelot, wm_index, old_thr); in ocelot_sb_port_pool_set()
668 ocelot_setup_sharing_watermarks(ocelot); in ocelot_sb_port_pool_set()
675 int ocelot_sb_tc_pool_bind_get(struct ocelot *ocelot, int port, in ocelot_sb_tc_pool_bind_get() argument
696 return -ENODEV; in ocelot_sb_tc_pool_bind_get()
699 *p_threshold = ocelot_wm_read(ocelot, wm_index); in ocelot_sb_tc_pool_bind_get()
705 *p_pool_index = 1; in ocelot_sb_tc_pool_bind_get()
711 /* This configures the Q_RSRV per-port-tc reserved resource watermark */
712 int ocelot_sb_tc_pool_bind_set(struct ocelot *ocelot, int port, in ocelot_sb_tc_pool_bind_set() argument
724 return -EINVAL; in ocelot_sb_tc_pool_bind_set()
727 return -EINVAL; in ocelot_sb_tc_pool_bind_set()
744 return -ENODEV; in ocelot_sb_tc_pool_bind_set()
749 old_thr = ocelot_wm_read(ocelot, wm_index); in ocelot_sb_tc_pool_bind_set()
750 ocelot_wm_write(ocelot, wm_index, threshold); in ocelot_sb_tc_pool_bind_set()
751 err = ocelot_watermark_validate(ocelot, extack); in ocelot_sb_tc_pool_bind_set()
753 ocelot_wm_write(ocelot, wm_index, old_thr); in ocelot_sb_tc_pool_bind_set()
757 ocelot_setup_sharing_watermarks(ocelot); in ocelot_sb_tc_pool_bind_set()
766 int ocelot_sb_occ_snapshot(struct ocelot *ocelot, unsigned int sb_index) in ocelot_sb_occ_snapshot() argument
775 int ocelot_sb_occ_max_clear(struct ocelot *ocelot, unsigned int sb_index) in ocelot_sb_occ_max_clear() argument
782 for (port = 0; port <= ocelot->num_phys_ports; port++) { in ocelot_sb_occ_max_clear()
784 ocelot_wm_status(ocelot, BUF_Q_RSRV_I(port, prio), in ocelot_sb_occ_max_clear()
786 ocelot_wm_status(ocelot, BUF_Q_RSRV_E(port, prio), in ocelot_sb_occ_max_clear()
789 ocelot_wm_status(ocelot, BUF_P_RSRV_I(port), in ocelot_sb_occ_max_clear()
791 ocelot_wm_status(ocelot, BUF_P_RSRV_E(port), in ocelot_sb_occ_max_clear()
796 for (port = 0; port <= ocelot->num_phys_ports; port++) { in ocelot_sb_occ_max_clear()
798 ocelot_wm_status(ocelot, REF_Q_RSRV_I(port, prio), in ocelot_sb_occ_max_clear()
800 ocelot_wm_status(ocelot, REF_Q_RSRV_E(port, prio), in ocelot_sb_occ_max_clear()
803 ocelot_wm_status(ocelot, REF_P_RSRV_I(port), in ocelot_sb_occ_max_clear()
805 ocelot_wm_status(ocelot, REF_P_RSRV_E(port), in ocelot_sb_occ_max_clear()
810 return -ENODEV; in ocelot_sb_occ_max_clear()
817 /* This retrieves the watermark occupancy for per-port P_RSRV watermarks */
818 int ocelot_sb_occ_port_pool_get(struct ocelot *ocelot, int port, in ocelot_sb_occ_port_pool_get() argument
838 return -ENODEV; in ocelot_sb_occ_port_pool_get()
841 ocelot_wm_status(ocelot, wm_index, p_cur, p_max); in ocelot_sb_occ_port_pool_get()
849 /* This retrieves the watermark occupancy for per-port-tc Q_RSRV watermarks */
850 int ocelot_sb_occ_tc_port_bind_get(struct ocelot *ocelot, int port, in ocelot_sb_occ_tc_port_bind_get() argument
871 return -ENODEV; in ocelot_sb_occ_tc_port_bind_get()
874 ocelot_wm_status(ocelot, wm_index, p_cur, p_max); in ocelot_sb_occ_tc_port_bind_get()
882 int ocelot_devlink_sb_register(struct ocelot *ocelot) in ocelot_devlink_sb_register() argument
886 err = devlink_sb_register(ocelot->devlink, OCELOT_SB_BUF, in ocelot_devlink_sb_register()
887 ocelot->packet_buffer_size, 1, 1, in ocelot_devlink_sb_register()
892 err = devlink_sb_register(ocelot->devlink, OCELOT_SB_REF, in ocelot_devlink_sb_register()
893 ocelot->num_frame_refs, 1, 1, in ocelot_devlink_sb_register()
896 devlink_sb_unregister(ocelot->devlink, OCELOT_SB_BUF); in ocelot_devlink_sb_register()
900 ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_ING] = ocelot->packet_buffer_size; in ocelot_devlink_sb_register()
901 ocelot->pool_size[OCELOT_SB_BUF][OCELOT_SB_POOL_EGR] = ocelot->packet_buffer_size; in ocelot_devlink_sb_register()
902 ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_ING] = ocelot->num_frame_refs; in ocelot_devlink_sb_register()
903 ocelot->pool_size[OCELOT_SB_REF][OCELOT_SB_POOL_EGR] = ocelot->num_frame_refs; in ocelot_devlink_sb_register()
905 ocelot_watermark_init(ocelot); in ocelot_devlink_sb_register()
911 void ocelot_devlink_sb_unregister(struct ocelot *ocelot) in ocelot_devlink_sb_unregister() argument
913 devlink_sb_unregister(ocelot->devlink, OCELOT_SB_BUF); in ocelot_devlink_sb_unregister()
914 devlink_sb_unregister(ocelot->devlink, OCELOT_SB_REF); in ocelot_devlink_sb_unregister()