1*21ce14a8SHoratiu Vultur // SPDX-License-Identifier: GPL-2.0+
2*21ce14a8SHoratiu Vultur
3*21ce14a8SHoratiu Vultur #include "lan966x_main.h"
4*21ce14a8SHoratiu Vultur
lan966x_cbs_add(struct lan966x_port * port,struct tc_cbs_qopt_offload * qopt)5*21ce14a8SHoratiu Vultur int lan966x_cbs_add(struct lan966x_port *port,
6*21ce14a8SHoratiu Vultur struct tc_cbs_qopt_offload *qopt)
7*21ce14a8SHoratiu Vultur {
8*21ce14a8SHoratiu Vultur struct lan966x *lan966x = port->lan966x;
9*21ce14a8SHoratiu Vultur u32 cir, cbs;
10*21ce14a8SHoratiu Vultur u8 se_idx;
11*21ce14a8SHoratiu Vultur
12*21ce14a8SHoratiu Vultur /* Check for invalid values */
13*21ce14a8SHoratiu Vultur if (qopt->idleslope <= 0 ||
14*21ce14a8SHoratiu Vultur qopt->sendslope >= 0 ||
15*21ce14a8SHoratiu Vultur qopt->locredit >= qopt->hicredit)
16*21ce14a8SHoratiu Vultur return -EINVAL;
17*21ce14a8SHoratiu Vultur
18*21ce14a8SHoratiu Vultur se_idx = SE_IDX_QUEUE + port->chip_port * NUM_PRIO_QUEUES + qopt->queue;
19*21ce14a8SHoratiu Vultur cir = qopt->idleslope;
20*21ce14a8SHoratiu Vultur cbs = (qopt->idleslope - qopt->sendslope) *
21*21ce14a8SHoratiu Vultur (qopt->hicredit - qopt->locredit) /
22*21ce14a8SHoratiu Vultur -qopt->sendslope;
23*21ce14a8SHoratiu Vultur
24*21ce14a8SHoratiu Vultur /* Rate unit is 100 kbps */
25*21ce14a8SHoratiu Vultur cir = DIV_ROUND_UP(cir, 100);
26*21ce14a8SHoratiu Vultur /* Avoid using zero rate */
27*21ce14a8SHoratiu Vultur cir = cir ?: 1;
28*21ce14a8SHoratiu Vultur /* Burst unit is 4kB */
29*21ce14a8SHoratiu Vultur cbs = DIV_ROUND_UP(cbs, 4096);
30*21ce14a8SHoratiu Vultur /* Avoid using zero burst */
31*21ce14a8SHoratiu Vultur cbs = cbs ?: 1;
32*21ce14a8SHoratiu Vultur
33*21ce14a8SHoratiu Vultur /* Check that actually the result can be written */
34*21ce14a8SHoratiu Vultur if (cir > GENMASK(15, 0) ||
35*21ce14a8SHoratiu Vultur cbs > GENMASK(6, 0))
36*21ce14a8SHoratiu Vultur return -EINVAL;
37*21ce14a8SHoratiu Vultur
38*21ce14a8SHoratiu Vultur lan_rmw(QSYS_SE_CFG_SE_AVB_ENA_SET(1) |
39*21ce14a8SHoratiu Vultur QSYS_SE_CFG_SE_FRM_MODE_SET(1),
40*21ce14a8SHoratiu Vultur QSYS_SE_CFG_SE_AVB_ENA |
41*21ce14a8SHoratiu Vultur QSYS_SE_CFG_SE_FRM_MODE,
42*21ce14a8SHoratiu Vultur lan966x, QSYS_SE_CFG(se_idx));
43*21ce14a8SHoratiu Vultur
44*21ce14a8SHoratiu Vultur lan_wr(QSYS_CIR_CFG_CIR_RATE_SET(cir) |
45*21ce14a8SHoratiu Vultur QSYS_CIR_CFG_CIR_BURST_SET(cbs),
46*21ce14a8SHoratiu Vultur lan966x, QSYS_CIR_CFG(se_idx));
47*21ce14a8SHoratiu Vultur
48*21ce14a8SHoratiu Vultur return 0;
49*21ce14a8SHoratiu Vultur }
50*21ce14a8SHoratiu Vultur
lan966x_cbs_del(struct lan966x_port * port,struct tc_cbs_qopt_offload * qopt)51*21ce14a8SHoratiu Vultur int lan966x_cbs_del(struct lan966x_port *port,
52*21ce14a8SHoratiu Vultur struct tc_cbs_qopt_offload *qopt)
53*21ce14a8SHoratiu Vultur {
54*21ce14a8SHoratiu Vultur struct lan966x *lan966x = port->lan966x;
55*21ce14a8SHoratiu Vultur u8 se_idx;
56*21ce14a8SHoratiu Vultur
57*21ce14a8SHoratiu Vultur se_idx = SE_IDX_QUEUE + port->chip_port * NUM_PRIO_QUEUES + qopt->queue;
58*21ce14a8SHoratiu Vultur
59*21ce14a8SHoratiu Vultur lan_rmw(QSYS_SE_CFG_SE_AVB_ENA_SET(1) |
60*21ce14a8SHoratiu Vultur QSYS_SE_CFG_SE_FRM_MODE_SET(0),
61*21ce14a8SHoratiu Vultur QSYS_SE_CFG_SE_AVB_ENA |
62*21ce14a8SHoratiu Vultur QSYS_SE_CFG_SE_FRM_MODE,
63*21ce14a8SHoratiu Vultur lan966x, QSYS_SE_CFG(se_idx));
64*21ce14a8SHoratiu Vultur
65*21ce14a8SHoratiu Vultur lan_wr(QSYS_CIR_CFG_CIR_RATE_SET(0) |
66*21ce14a8SHoratiu Vultur QSYS_CIR_CFG_CIR_BURST_SET(0),
67*21ce14a8SHoratiu Vultur lan966x, QSYS_CIR_CFG(se_idx));
68*21ce14a8SHoratiu Vultur
69*21ce14a8SHoratiu Vultur return 0;
70*21ce14a8SHoratiu Vultur }
71