xref: /openbmc/linux/net/bridge/br_mrp_switchdev.c (revision f23f0db3607582636b475eaeb74d32e924f11c41)
1fadd4091SHoratiu Vultur // SPDX-License-Identifier: GPL-2.0-or-later
2fadd4091SHoratiu Vultur 
3fadd4091SHoratiu Vultur #include <net/switchdev.h>
4fadd4091SHoratiu Vultur 
5fadd4091SHoratiu Vultur #include "br_private_mrp.h"
6fadd4091SHoratiu Vultur 
7fadd4091SHoratiu Vultur int br_mrp_switchdev_add(struct net_bridge *br, struct br_mrp *mrp)
8fadd4091SHoratiu Vultur {
9fadd4091SHoratiu Vultur 	struct switchdev_obj_mrp mrp_obj = {
10fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
11fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_MRP,
12fadd4091SHoratiu Vultur 		.p_port = rtnl_dereference(mrp->p_port)->dev,
13fadd4091SHoratiu Vultur 		.s_port = rtnl_dereference(mrp->s_port)->dev,
14fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
154b3a61b0SHoratiu Vultur 		.prio = mrp->prio,
16fadd4091SHoratiu Vultur 	};
17fadd4091SHoratiu Vultur 	int err;
18fadd4091SHoratiu Vultur 
19fadd4091SHoratiu Vultur 	err = switchdev_port_obj_add(br->dev, &mrp_obj.obj, NULL);
20fadd4091SHoratiu Vultur 
21fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
22fadd4091SHoratiu Vultur 		return err;
23fadd4091SHoratiu Vultur 
24fadd4091SHoratiu Vultur 	return 0;
25fadd4091SHoratiu Vultur }
26fadd4091SHoratiu Vultur 
27fadd4091SHoratiu Vultur int br_mrp_switchdev_del(struct net_bridge *br, struct br_mrp *mrp)
28fadd4091SHoratiu Vultur {
29fadd4091SHoratiu Vultur 	struct switchdev_obj_mrp mrp_obj = {
30fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
31fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_MRP,
32fadd4091SHoratiu Vultur 		.p_port = NULL,
33fadd4091SHoratiu Vultur 		.s_port = NULL,
34fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
35fadd4091SHoratiu Vultur 	};
36fadd4091SHoratiu Vultur 	int err;
37fadd4091SHoratiu Vultur 
38fadd4091SHoratiu Vultur 	err = switchdev_port_obj_del(br->dev, &mrp_obj.obj);
39fadd4091SHoratiu Vultur 
40fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
41fadd4091SHoratiu Vultur 		return err;
42fadd4091SHoratiu Vultur 
43fadd4091SHoratiu Vultur 	return 0;
44fadd4091SHoratiu Vultur }
45fadd4091SHoratiu Vultur 
46fadd4091SHoratiu Vultur int br_mrp_switchdev_set_ring_role(struct net_bridge *br,
47fadd4091SHoratiu Vultur 				   struct br_mrp *mrp,
48fadd4091SHoratiu Vultur 				   enum br_mrp_ring_role_type role)
49fadd4091SHoratiu Vultur {
50fadd4091SHoratiu Vultur 	struct switchdev_obj_ring_role_mrp mrp_role = {
51fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
52fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_RING_ROLE_MRP,
53fadd4091SHoratiu Vultur 		.ring_role = role,
54fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
55fadd4091SHoratiu Vultur 	};
56fadd4091SHoratiu Vultur 	int err;
57fadd4091SHoratiu Vultur 
58fadd4091SHoratiu Vultur 	if (role == BR_MRP_RING_ROLE_DISABLED)
59fadd4091SHoratiu Vultur 		err = switchdev_port_obj_del(br->dev, &mrp_role.obj);
60fadd4091SHoratiu Vultur 	else
61fadd4091SHoratiu Vultur 		err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL);
62fadd4091SHoratiu Vultur 
63fadd4091SHoratiu Vultur 	return err;
64fadd4091SHoratiu Vultur }
65fadd4091SHoratiu Vultur 
66fadd4091SHoratiu Vultur int br_mrp_switchdev_send_ring_test(struct net_bridge *br,
67fadd4091SHoratiu Vultur 				    struct br_mrp *mrp, u32 interval,
68c6676e7dSHoratiu Vultur 				    u8 max_miss, u32 period,
69c6676e7dSHoratiu Vultur 				    bool monitor)
70fadd4091SHoratiu Vultur {
71fadd4091SHoratiu Vultur 	struct switchdev_obj_ring_test_mrp test = {
72fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
73fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_RING_TEST_MRP,
74fadd4091SHoratiu Vultur 		.interval = interval,
75fadd4091SHoratiu Vultur 		.max_miss = max_miss,
76fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
77fadd4091SHoratiu Vultur 		.period = period,
78c6676e7dSHoratiu Vultur 		.monitor = monitor,
79fadd4091SHoratiu Vultur 	};
80fadd4091SHoratiu Vultur 	int err;
81fadd4091SHoratiu Vultur 
82fadd4091SHoratiu Vultur 	if (interval == 0)
83fadd4091SHoratiu Vultur 		err = switchdev_port_obj_del(br->dev, &test.obj);
84fadd4091SHoratiu Vultur 	else
85fadd4091SHoratiu Vultur 		err = switchdev_port_obj_add(br->dev, &test.obj, NULL);
86fadd4091SHoratiu Vultur 
87fadd4091SHoratiu Vultur 	return err;
88fadd4091SHoratiu Vultur }
89fadd4091SHoratiu Vultur 
90fadd4091SHoratiu Vultur int br_mrp_switchdev_set_ring_state(struct net_bridge *br,
91fadd4091SHoratiu Vultur 				    struct br_mrp *mrp,
92fadd4091SHoratiu Vultur 				    enum br_mrp_ring_state_type state)
93fadd4091SHoratiu Vultur {
94fadd4091SHoratiu Vultur 	struct switchdev_obj_ring_state_mrp mrp_state = {
95fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
96fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_RING_STATE_MRP,
97fadd4091SHoratiu Vultur 		.ring_state = state,
98fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
99fadd4091SHoratiu Vultur 	};
100fadd4091SHoratiu Vultur 	int err;
101fadd4091SHoratiu Vultur 
102fadd4091SHoratiu Vultur 	err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL);
103fadd4091SHoratiu Vultur 
104fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
105fadd4091SHoratiu Vultur 		return err;
106fadd4091SHoratiu Vultur 
107fadd4091SHoratiu Vultur 	return 0;
108fadd4091SHoratiu Vultur }
109fadd4091SHoratiu Vultur 
110*f23f0db3SHoratiu Vultur int br_mrp_switchdev_set_in_role(struct net_bridge *br, struct br_mrp *mrp,
111*f23f0db3SHoratiu Vultur 				 u16 in_id, u32 ring_id,
112*f23f0db3SHoratiu Vultur 				 enum br_mrp_in_role_type role)
113*f23f0db3SHoratiu Vultur {
114*f23f0db3SHoratiu Vultur 	struct switchdev_obj_in_role_mrp mrp_role = {
115*f23f0db3SHoratiu Vultur 		.obj.orig_dev = br->dev,
116*f23f0db3SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_IN_ROLE_MRP,
117*f23f0db3SHoratiu Vultur 		.in_role = role,
118*f23f0db3SHoratiu Vultur 		.in_id = mrp->in_id,
119*f23f0db3SHoratiu Vultur 		.ring_id = mrp->ring_id,
120*f23f0db3SHoratiu Vultur 		.i_port = rtnl_dereference(mrp->i_port)->dev,
121*f23f0db3SHoratiu Vultur 	};
122*f23f0db3SHoratiu Vultur 	int err;
123*f23f0db3SHoratiu Vultur 
124*f23f0db3SHoratiu Vultur 	if (role == BR_MRP_IN_ROLE_DISABLED)
125*f23f0db3SHoratiu Vultur 		err = switchdev_port_obj_del(br->dev, &mrp_role.obj);
126*f23f0db3SHoratiu Vultur 	else
127*f23f0db3SHoratiu Vultur 		err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL);
128*f23f0db3SHoratiu Vultur 
129*f23f0db3SHoratiu Vultur 	return err;
130*f23f0db3SHoratiu Vultur }
131*f23f0db3SHoratiu Vultur 
132*f23f0db3SHoratiu Vultur int br_mrp_switchdev_set_in_state(struct net_bridge *br, struct br_mrp *mrp,
133*f23f0db3SHoratiu Vultur 				  enum br_mrp_in_state_type state)
134*f23f0db3SHoratiu Vultur {
135*f23f0db3SHoratiu Vultur 	struct switchdev_obj_in_state_mrp mrp_state = {
136*f23f0db3SHoratiu Vultur 		.obj.orig_dev = br->dev,
137*f23f0db3SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_IN_STATE_MRP,
138*f23f0db3SHoratiu Vultur 		.in_state = state,
139*f23f0db3SHoratiu Vultur 		.in_id = mrp->in_id,
140*f23f0db3SHoratiu Vultur 	};
141*f23f0db3SHoratiu Vultur 	int err;
142*f23f0db3SHoratiu Vultur 
143*f23f0db3SHoratiu Vultur 	err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL);
144*f23f0db3SHoratiu Vultur 
145*f23f0db3SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
146*f23f0db3SHoratiu Vultur 		return err;
147*f23f0db3SHoratiu Vultur 
148*f23f0db3SHoratiu Vultur 	return 0;
149*f23f0db3SHoratiu Vultur }
150*f23f0db3SHoratiu Vultur 
151*f23f0db3SHoratiu Vultur int br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp,
152*f23f0db3SHoratiu Vultur 				  u32 interval, u8 max_miss, u32 period)
153*f23f0db3SHoratiu Vultur {
154*f23f0db3SHoratiu Vultur 	struct switchdev_obj_in_test_mrp test = {
155*f23f0db3SHoratiu Vultur 		.obj.orig_dev = br->dev,
156*f23f0db3SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_IN_TEST_MRP,
157*f23f0db3SHoratiu Vultur 		.interval = interval,
158*f23f0db3SHoratiu Vultur 		.max_miss = max_miss,
159*f23f0db3SHoratiu Vultur 		.in_id = mrp->in_id,
160*f23f0db3SHoratiu Vultur 		.period = period,
161*f23f0db3SHoratiu Vultur 	};
162*f23f0db3SHoratiu Vultur 	int err;
163*f23f0db3SHoratiu Vultur 
164*f23f0db3SHoratiu Vultur 	if (interval == 0)
165*f23f0db3SHoratiu Vultur 		err = switchdev_port_obj_del(br->dev, &test.obj);
166*f23f0db3SHoratiu Vultur 	else
167*f23f0db3SHoratiu Vultur 		err = switchdev_port_obj_add(br->dev, &test.obj, NULL);
168*f23f0db3SHoratiu Vultur 
169*f23f0db3SHoratiu Vultur 	return err;
170*f23f0db3SHoratiu Vultur }
171*f23f0db3SHoratiu Vultur 
172fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_state(struct net_bridge_port *p,
173fadd4091SHoratiu Vultur 				    enum br_mrp_port_state_type state)
174fadd4091SHoratiu Vultur {
175fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
176fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
177fadd4091SHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_MRP_PORT_STATE,
178fadd4091SHoratiu Vultur 		.u.mrp_port_state = state,
179fadd4091SHoratiu Vultur 	};
180fadd4091SHoratiu Vultur 	int err;
181fadd4091SHoratiu Vultur 
182fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
183fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
184fadd4091SHoratiu Vultur 		br_warn(p->br, "error setting offload MRP state on port %u(%s)\n",
185fadd4091SHoratiu Vultur 			(unsigned int)p->port_no, p->dev->name);
186fadd4091SHoratiu Vultur 
187fadd4091SHoratiu Vultur 	return err;
188fadd4091SHoratiu Vultur }
189fadd4091SHoratiu Vultur 
190fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_role(struct net_bridge_port *p,
191fadd4091SHoratiu Vultur 				   enum br_mrp_port_role_type role)
192fadd4091SHoratiu Vultur {
193fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
194fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
195fadd4091SHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_MRP_PORT_ROLE,
196fadd4091SHoratiu Vultur 		.u.mrp_port_role = role,
197fadd4091SHoratiu Vultur 	};
198fadd4091SHoratiu Vultur 	int err;
199fadd4091SHoratiu Vultur 
200fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
201fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
202fadd4091SHoratiu Vultur 		return err;
203fadd4091SHoratiu Vultur 
204fadd4091SHoratiu Vultur 	return 0;
205fadd4091SHoratiu Vultur }
206