Lines Matching +full:cpsw +full:- +full:switch
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
6 * Enhanced Scheduler Traffic (EST - P802.1Qbv/D2.2)
12 #include "am65-cpsw-nuss.h"
13 #include "am65-cpsw-qos.h"
14 #include "am65-cpts.h"
58 return port->qos.est_oper || port->qos.est_admin; in am65_cpsw_port_est_enabled()
65 val = readl(common->cpsw_base + AM65_CPSW_REG_CTL); in am65_cpsw_est_enable()
72 writel(val, common->cpsw_base + AM65_CPSW_REG_CTL); in am65_cpsw_est_enable()
73 common->est_enabled = enable; in am65_cpsw_est_enable()
80 val = readl(port->port_base + AM65_CPSW_PN_REG_CTL); in am65_cpsw_port_est_enable()
86 writel(val, port->port_base + AM65_CPSW_PN_REG_CTL); in am65_cpsw_port_est_enable()
96 val = readl(port->port_base + AM65_CPSW_PN_REG_EST_CTL); in am65_cpsw_port_est_assign_buf_num()
102 writel(val, port->port_base + AM65_CPSW_PN_REG_EST_CTL); in am65_cpsw_port_est_assign_buf_num()
105 /* am65_cpsw_port_est_is_swapped() - Indicate if h/w is transitioned
106 * admin -> oper or not
109 * numbers match (est_oper->buf match with est_admin->buf).
112 * and est_oper->buf not match with est_oper->buf).
120 val = readl(port->port_base + AM65_CPSW_PN_REG_FIFO_STATUS); in am65_cpsw_port_est_is_swapped()
123 val = readl(port->port_base + AM65_CPSW_PN_REG_EST_CTL); in am65_cpsw_port_est_is_swapped()
129 /* am65_cpsw_port_est_get_free_buf_num() - Get free buffer number for
132 * Logic as follows:-
135 * as it is in the process of transitioning from admin -> oper. So keep the
146 while (roll--) { in am65_cpsw_port_est_get_free_buf_num()
151 * to touch memory in-flight, by targeting same oper buf. in am65_cpsw_port_est_get_free_buf_num()
155 dev_info(&ndev->dev, in am65_cpsw_port_est_get_free_buf_num()
156 "Prev. EST admin cycle is in transit %d -> %d\n", in am65_cpsw_port_est_get_free_buf_num()
167 if (port->qos.est_oper) in am65_cpsw_admin_to_oper()
168 devm_kfree(&ndev->dev, port->qos.est_oper); in am65_cpsw_admin_to_oper()
170 port->qos.est_oper = port->qos.est_admin; in am65_cpsw_admin_to_oper()
171 port->qos.est_admin = NULL; in am65_cpsw_admin_to_oper()
180 val = readl(port->port_base + AM65_CPSW_PN_REG_EST_CTL); in am65_cpsw_port_est_get_buf_num()
182 writel(val, port->port_base + AM65_CPSW_PN_REG_EST_CTL); in am65_cpsw_port_est_get_buf_num()
184 est_new->buf = am65_cpsw_port_est_get_free_buf_num(ndev); in am65_cpsw_port_est_get_buf_num()
187 if (port->qos.est_oper && port->qos.est_admin && in am65_cpsw_port_est_get_buf_num()
188 est_new->buf == port->qos.est_oper->buf) in am65_cpsw_port_est_get_buf_num()
195 struct am65_cpsw_common *common = port->common; in am65_cpsw_est_set()
201 for (i = 0; i < common->port_num; i++) in am65_cpsw_est_set()
202 common_enable |= am65_cpsw_port_est_enabled(&common->ports[i]); in am65_cpsw_est_set()
209 * of admin -> oper transition, particularly it's supposed to be used in some
217 if (!port->qos.est_admin) in am65_cpsw_est_update_state()
249 fetch_cnt -= AM65_CPSW_FETCH_CNT_MAX; in am65_cpsw_est_set_sched_cmds()
277 for (i = 0; i < taprio->num_entries; i++) { in am65_cpsw_est_calc_cmd_num()
278 if (taprio->entries[i].command != TC_TAPRIO_CMD_SET_GATES) { in am65_cpsw_est_calc_cmd_num()
279 dev_err(&ndev->dev, "Only SET command is supported"); in am65_cpsw_est_calc_cmd_num()
280 return -EINVAL; in am65_cpsw_est_calc_cmd_num()
283 fetch_cnt = am65_est_cmd_ns_to_cnt(taprio->entries[i].interval, in am65_cpsw_est_calc_cmd_num()
305 cmd_num = am65_cpsw_est_calc_cmd_num(ndev, &est_new->taprio, in am65_cpsw_est_check_scheds()
306 port->qos.link_speed); in am65_cpsw_est_check_scheds()
311 dev_err(&ndev->dev, "No fetch RAM"); in am65_cpsw_est_check_scheds()
312 return -ENOMEM; in am65_cpsw_est_check_scheds()
327 ram_addr = port->fetch_ram_base; in am65_cpsw_est_set_sched_list()
329 ram_addr += est_new->buf * ram_size; in am65_cpsw_est_set_sched_list()
332 for (i = 0; i < est_new->taprio.num_entries; i++) { in am65_cpsw_est_set_sched_list()
333 entry = &est_new->taprio.entries[i]; in am65_cpsw_est_set_sched_list()
335 fetch_cnt = am65_est_cmd_ns_to_cnt(entry->interval, in am65_cpsw_est_set_sched_list()
336 port->qos.link_speed); in am65_cpsw_est_set_sched_list()
337 fetch_allow = entry->gate_mask; in am65_cpsw_est_set_sched_list()
339 dev_dbg(&ndev->dev, "fetch_allow > 8 bits: %d\n", in am65_cpsw_est_set_sched_list()
345 if (!fetch_cnt && i < est_new->taprio.num_entries - 1) { in am65_cpsw_est_set_sched_list()
346 dev_info(&ndev->dev, in am65_cpsw_est_set_sched_list()
354 /* end cmd, enabling non-timed queues for potential over cycle time */ in am65_cpsw_est_set_sched_list()
366 struct am65_cpsw_common *common = port->common; in am65_cpsw_timer_set()
367 struct am65_cpts *cpts = common->cpts; in am65_cpsw_timer_set()
370 cfg.ns_period = est_new->taprio.cycle_time; in am65_cpsw_timer_set()
371 cfg.ns_start = est_new->taprio.base_time; in am65_cpsw_timer_set()
373 return am65_cpts_estf_enable(cpts, port->port_id - 1, &cfg); in am65_cpsw_timer_set()
379 struct am65_cpts *cpts = port->common->cpts; in am65_cpsw_timer_stop()
381 am65_cpts_estf_disable(cpts, port->port_id - 1); in am65_cpsw_timer_stop()
389 struct am65_cpts *cpts = port->common->cpts; in am65_cpsw_timer_act()
393 if (!port->qos.est_oper) in am65_cpsw_timer_act()
396 taprio_new = &est_new->taprio; in am65_cpsw_timer_act()
397 taprio_oper = &port->qos.est_oper->taprio; in am65_cpsw_timer_act()
399 if (taprio_new->cycle_time != taprio_oper->cycle_time) in am65_cpsw_timer_act()
403 if (!taprio_new->base_time && taprio_oper) in am65_cpsw_timer_act()
404 taprio_new->base_time = taprio_oper->base_time; in am65_cpsw_timer_act()
406 if (taprio_new->base_time == taprio_oper->base_time) in am65_cpsw_timer_act()
410 diff = taprio_new->base_time - taprio_oper->base_time; in am65_cpsw_timer_act()
411 diff = diff < 0 ? -diff : diff; in am65_cpsw_timer_act()
412 if (diff % taprio_new->cycle_time) in am65_cpsw_timer_act()
416 if (taprio_new->base_time <= cur_time + taprio_new->cycle_time) in am65_cpsw_timer_act()
435 if (port->qos.est_admin) in am65_cpsw_purge_est()
436 devm_kfree(&ndev->dev, port->qos.est_admin); in am65_cpsw_purge_est()
438 if (port->qos.est_oper) in am65_cpsw_purge_est()
439 devm_kfree(&ndev->dev, port->qos.est_oper); in am65_cpsw_purge_est()
441 port->qos.est_oper = NULL; in am65_cpsw_purge_est()
442 port->qos.est_admin = NULL; in am65_cpsw_purge_est()
449 struct am65_cpts *cpts = common->cpts; in am65_cpsw_configure_taprio()
454 if (!est_new->taprio.enable) { in am65_cpsw_configure_taprio()
465 dev_err(&ndev->dev, in am65_cpsw_configure_taprio()
467 return -EINVAL; in am65_cpsw_configure_taprio()
473 if (!est_new->taprio.base_time) in am65_cpsw_configure_taprio()
474 est_new->taprio.base_time = am65_cpts_ns_gettime(cpts); in am65_cpsw_configure_taprio()
478 am65_cpsw_port_est_assign_buf_num(ndev, est_new->buf); in am65_cpsw_configure_taprio()
480 am65_cpsw_est_set(ndev, est_new->taprio.enable); in am65_cpsw_configure_taprio()
485 dev_err(&ndev->dev, "Failed to set cycle time"); in am65_cpsw_configure_taprio()
499 for (i = 0; i < from->num_entries; i++) in am65_cpsw_cp_taprio()
500 to->entries[i] = from->entries[i]; in am65_cpsw_cp_taprio()
510 if (taprio->cycle_time_extension) { in am65_cpsw_set_taprio()
511 dev_err(&ndev->dev, "Failed to set cycle time extension"); in am65_cpsw_set_taprio()
512 return -EOPNOTSUPP; in am65_cpsw_set_taprio()
515 est_new = devm_kzalloc(&ndev->dev, in am65_cpsw_set_taprio()
516 struct_size(est_new, taprio.entries, taprio->num_entries), in am65_cpsw_set_taprio()
519 return -ENOMEM; in am65_cpsw_set_taprio()
521 am65_cpsw_cp_taprio(taprio, &est_new->taprio); in am65_cpsw_set_taprio()
524 if (taprio->enable) { in am65_cpsw_set_taprio()
525 if (port->qos.est_admin) in am65_cpsw_set_taprio()
526 devm_kfree(&ndev->dev, port->qos.est_admin); in am65_cpsw_set_taprio()
528 port->qos.est_admin = est_new; in am65_cpsw_set_taprio()
530 devm_kfree(&ndev->dev, est_new); in am65_cpsw_set_taprio()
534 devm_kfree(&ndev->dev, est_new); in am65_cpsw_set_taprio()
546 port->qos.link_speed = link_speed; in am65_cpsw_est_link_up()
550 if (port->qos.link_down_time) { in am65_cpsw_est_link_up()
552 delta = ktime_us_delta(cur_time, port->qos.link_down_time); in am65_cpsw_est_link_up()
554 dev_err(&ndev->dev, in am65_cpsw_est_link_up()
569 struct am65_cpsw_common *common = port->common; in am65_cpsw_setup_taprio()
572 return -ENODEV; in am65_cpsw_setup_taprio()
575 dev_err(&ndev->dev, "interface is down, link speed unknown\n"); in am65_cpsw_setup_taprio()
576 return -ENETDOWN; in am65_cpsw_setup_taprio()
579 if (common->pf_p0_rx_ptype_rrobin) { in am65_cpsw_setup_taprio()
580 dev_err(&ndev->dev, in am65_cpsw_setup_taprio()
581 "p0-rx-ptype-rrobin flag conflicts with taprio qdisc\n"); in am65_cpsw_setup_taprio()
582 return -EINVAL; in am65_cpsw_setup_taprio()
585 if (port->qos.link_speed == SPEED_UNKNOWN) in am65_cpsw_setup_taprio()
586 return -ENOLINK; in am65_cpsw_setup_taprio()
594 switch (type) { in am65_cpsw_qos_ndo_setup_tc()
598 return -EOPNOTSUPP; in am65_cpsw_qos_ndo_setup_tc()
610 port->qos.link_down_time = 0; in am65_cpsw_qos_link_up()
620 if (!port->qos.link_down_time) in am65_cpsw_qos_link_down()
621 port->qos.link_down_time = ktime_get(); in am65_cpsw_qos_link_down()
623 port->qos.link_speed = SPEED_UNKNOWN; in am65_cpsw_qos_link_down()