xref: /openbmc/linux/net/bridge/br_mrp_switchdev.c (revision b2bdba1cbc84cadb14393d0101a5bfd38d342e0a)
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 
110f23f0db3SHoratiu Vultur int br_mrp_switchdev_set_in_role(struct net_bridge *br, struct br_mrp *mrp,
111f23f0db3SHoratiu Vultur 				 u16 in_id, u32 ring_id,
112f23f0db3SHoratiu Vultur 				 enum br_mrp_in_role_type role)
113f23f0db3SHoratiu Vultur {
114f23f0db3SHoratiu Vultur 	struct switchdev_obj_in_role_mrp mrp_role = {
115f23f0db3SHoratiu Vultur 		.obj.orig_dev = br->dev,
116f23f0db3SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_IN_ROLE_MRP,
117f23f0db3SHoratiu Vultur 		.in_role = role,
118f23f0db3SHoratiu Vultur 		.in_id = mrp->in_id,
119f23f0db3SHoratiu Vultur 		.ring_id = mrp->ring_id,
120f23f0db3SHoratiu Vultur 		.i_port = rtnl_dereference(mrp->i_port)->dev,
121f23f0db3SHoratiu Vultur 	};
122f23f0db3SHoratiu Vultur 	int err;
123f23f0db3SHoratiu Vultur 
124f23f0db3SHoratiu Vultur 	if (role == BR_MRP_IN_ROLE_DISABLED)
125f23f0db3SHoratiu Vultur 		err = switchdev_port_obj_del(br->dev, &mrp_role.obj);
126f23f0db3SHoratiu Vultur 	else
127f23f0db3SHoratiu Vultur 		err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL);
128f23f0db3SHoratiu Vultur 
129f23f0db3SHoratiu Vultur 	return err;
130f23f0db3SHoratiu Vultur }
131f23f0db3SHoratiu Vultur 
132f23f0db3SHoratiu Vultur int br_mrp_switchdev_set_in_state(struct net_bridge *br, struct br_mrp *mrp,
133f23f0db3SHoratiu Vultur 				  enum br_mrp_in_state_type state)
134f23f0db3SHoratiu Vultur {
135f23f0db3SHoratiu Vultur 	struct switchdev_obj_in_state_mrp mrp_state = {
136f23f0db3SHoratiu Vultur 		.obj.orig_dev = br->dev,
137f23f0db3SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_IN_STATE_MRP,
138f23f0db3SHoratiu Vultur 		.in_state = state,
139f23f0db3SHoratiu Vultur 		.in_id = mrp->in_id,
140f23f0db3SHoratiu Vultur 	};
141f23f0db3SHoratiu Vultur 	int err;
142f23f0db3SHoratiu Vultur 
143f23f0db3SHoratiu Vultur 	err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL);
144f23f0db3SHoratiu Vultur 
145f23f0db3SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
146f23f0db3SHoratiu Vultur 		return err;
147f23f0db3SHoratiu Vultur 
148f23f0db3SHoratiu Vultur 	return 0;
149f23f0db3SHoratiu Vultur }
150f23f0db3SHoratiu Vultur 
151f23f0db3SHoratiu Vultur int br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp,
152f23f0db3SHoratiu Vultur 				  u32 interval, u8 max_miss, u32 period)
153f23f0db3SHoratiu Vultur {
154f23f0db3SHoratiu Vultur 	struct switchdev_obj_in_test_mrp test = {
155f23f0db3SHoratiu Vultur 		.obj.orig_dev = br->dev,
156f23f0db3SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_IN_TEST_MRP,
157f23f0db3SHoratiu Vultur 		.interval = interval,
158f23f0db3SHoratiu Vultur 		.max_miss = max_miss,
159f23f0db3SHoratiu Vultur 		.in_id = mrp->in_id,
160f23f0db3SHoratiu Vultur 		.period = period,
161f23f0db3SHoratiu Vultur 	};
162f23f0db3SHoratiu Vultur 	int err;
163f23f0db3SHoratiu Vultur 
164f23f0db3SHoratiu Vultur 	if (interval == 0)
165f23f0db3SHoratiu Vultur 		err = switchdev_port_obj_del(br->dev, &test.obj);
166f23f0db3SHoratiu Vultur 	else
167f23f0db3SHoratiu Vultur 		err = switchdev_port_obj_add(br->dev, &test.obj, NULL);
168f23f0db3SHoratiu Vultur 
169f23f0db3SHoratiu Vultur 	return err;
170f23f0db3SHoratiu Vultur }
171f23f0db3SHoratiu Vultur 
172*b2bdba1cSHoratiu Vultur int br_mrp_port_switchdev_set_state(struct net_bridge_port *p, u32 state)
173fadd4091SHoratiu Vultur {
174fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
175fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
176*b2bdba1cSHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_PORT_STP_STATE,
177*b2bdba1cSHoratiu Vultur 		.u.stp_state = state,
178fadd4091SHoratiu Vultur 	};
179fadd4091SHoratiu Vultur 	int err;
180fadd4091SHoratiu Vultur 
181fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
182fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
183fadd4091SHoratiu Vultur 		br_warn(p->br, "error setting offload MRP state on port %u(%s)\n",
184fadd4091SHoratiu Vultur 			(unsigned int)p->port_no, p->dev->name);
185fadd4091SHoratiu Vultur 
186fadd4091SHoratiu Vultur 	return err;
187fadd4091SHoratiu Vultur }
188fadd4091SHoratiu Vultur 
189fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_role(struct net_bridge_port *p,
190fadd4091SHoratiu Vultur 				   enum br_mrp_port_role_type role)
191fadd4091SHoratiu Vultur {
192fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
193fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
194fadd4091SHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_MRP_PORT_ROLE,
195fadd4091SHoratiu Vultur 		.u.mrp_port_role = role,
196fadd4091SHoratiu Vultur 	};
197fadd4091SHoratiu Vultur 	int err;
198fadd4091SHoratiu Vultur 
199fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
200fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
201fadd4091SHoratiu Vultur 		return err;
202fadd4091SHoratiu Vultur 
203fadd4091SHoratiu Vultur 	return 0;
204fadd4091SHoratiu Vultur }
205