xref: /openbmc/linux/net/bridge/br_mrp_switchdev.c (revision 4b3a61b030d1131dcf3633a276158a3d0a435a47)
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,
15*4b3a61b0SHoratiu 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,
68fadd4091SHoratiu Vultur 				    u8 max_miss, u32 period)
69fadd4091SHoratiu Vultur {
70fadd4091SHoratiu Vultur 	struct switchdev_obj_ring_test_mrp test = {
71fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
72fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_RING_TEST_MRP,
73fadd4091SHoratiu Vultur 		.interval = interval,
74fadd4091SHoratiu Vultur 		.max_miss = max_miss,
75fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
76fadd4091SHoratiu Vultur 		.period = period,
77fadd4091SHoratiu Vultur 	};
78fadd4091SHoratiu Vultur 	int err;
79fadd4091SHoratiu Vultur 
80fadd4091SHoratiu Vultur 	if (interval == 0)
81fadd4091SHoratiu Vultur 		err = switchdev_port_obj_del(br->dev, &test.obj);
82fadd4091SHoratiu Vultur 	else
83fadd4091SHoratiu Vultur 		err = switchdev_port_obj_add(br->dev, &test.obj, NULL);
84fadd4091SHoratiu Vultur 
85fadd4091SHoratiu Vultur 	return err;
86fadd4091SHoratiu Vultur }
87fadd4091SHoratiu Vultur 
88fadd4091SHoratiu Vultur int br_mrp_switchdev_set_ring_state(struct net_bridge *br,
89fadd4091SHoratiu Vultur 				    struct br_mrp *mrp,
90fadd4091SHoratiu Vultur 				    enum br_mrp_ring_state_type state)
91fadd4091SHoratiu Vultur {
92fadd4091SHoratiu Vultur 	struct switchdev_obj_ring_state_mrp mrp_state = {
93fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
94fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_RING_STATE_MRP,
95fadd4091SHoratiu Vultur 		.ring_state = state,
96fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
97fadd4091SHoratiu Vultur 	};
98fadd4091SHoratiu Vultur 	int err;
99fadd4091SHoratiu Vultur 
100fadd4091SHoratiu Vultur 	err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL);
101fadd4091SHoratiu Vultur 
102fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
103fadd4091SHoratiu Vultur 		return err;
104fadd4091SHoratiu Vultur 
105fadd4091SHoratiu Vultur 	return 0;
106fadd4091SHoratiu Vultur }
107fadd4091SHoratiu Vultur 
108fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_state(struct net_bridge_port *p,
109fadd4091SHoratiu Vultur 				    enum br_mrp_port_state_type state)
110fadd4091SHoratiu Vultur {
111fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
112fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
113fadd4091SHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_MRP_PORT_STATE,
114fadd4091SHoratiu Vultur 		.u.mrp_port_state = state,
115fadd4091SHoratiu Vultur 	};
116fadd4091SHoratiu Vultur 	int err;
117fadd4091SHoratiu Vultur 
118fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
119fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
120fadd4091SHoratiu Vultur 		br_warn(p->br, "error setting offload MRP state on port %u(%s)\n",
121fadd4091SHoratiu Vultur 			(unsigned int)p->port_no, p->dev->name);
122fadd4091SHoratiu Vultur 
123fadd4091SHoratiu Vultur 	return err;
124fadd4091SHoratiu Vultur }
125fadd4091SHoratiu Vultur 
126fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_role(struct net_bridge_port *p,
127fadd4091SHoratiu Vultur 				   enum br_mrp_port_role_type role)
128fadd4091SHoratiu Vultur {
129fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
130fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
131fadd4091SHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_MRP_PORT_ROLE,
132fadd4091SHoratiu Vultur 		.u.mrp_port_role = role,
133fadd4091SHoratiu Vultur 	};
134fadd4091SHoratiu Vultur 	int err;
135fadd4091SHoratiu Vultur 
136fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
137fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
138fadd4091SHoratiu Vultur 		return err;
139fadd4091SHoratiu Vultur 
140fadd4091SHoratiu Vultur 	return 0;
141fadd4091SHoratiu Vultur }
142