xref: /openbmc/linux/drivers/net/ethernet/microchip/lan966x/lan966x_cbs.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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