xref: /openbmc/linux/net/bridge/br_mrp_switchdev.c (revision c6676e7d62cfb5cb7c1c5320a26f3634a11afdb0)
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,
68*c6676e7dSHoratiu Vultur 				    u8 max_miss, u32 period,
69*c6676e7dSHoratiu 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,
78*c6676e7dSHoratiu 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 
110fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_state(struct net_bridge_port *p,
111fadd4091SHoratiu Vultur 				    enum br_mrp_port_state_type state)
112fadd4091SHoratiu Vultur {
113fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
114fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
115fadd4091SHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_MRP_PORT_STATE,
116fadd4091SHoratiu Vultur 		.u.mrp_port_state = state,
117fadd4091SHoratiu Vultur 	};
118fadd4091SHoratiu Vultur 	int err;
119fadd4091SHoratiu Vultur 
120fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
121fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
122fadd4091SHoratiu Vultur 		br_warn(p->br, "error setting offload MRP state on port %u(%s)\n",
123fadd4091SHoratiu Vultur 			(unsigned int)p->port_no, p->dev->name);
124fadd4091SHoratiu Vultur 
125fadd4091SHoratiu Vultur 	return err;
126fadd4091SHoratiu Vultur }
127fadd4091SHoratiu Vultur 
128fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_role(struct net_bridge_port *p,
129fadd4091SHoratiu Vultur 				   enum br_mrp_port_role_type role)
130fadd4091SHoratiu Vultur {
131fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
132fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
133fadd4091SHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_MRP_PORT_ROLE,
134fadd4091SHoratiu Vultur 		.u.mrp_port_role = role,
135fadd4091SHoratiu Vultur 	};
136fadd4091SHoratiu Vultur 	int err;
137fadd4091SHoratiu Vultur 
138fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
139fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
140fadd4091SHoratiu Vultur 		return err;
141fadd4091SHoratiu Vultur 
142fadd4091SHoratiu Vultur 	return 0;
143fadd4091SHoratiu Vultur }
144