xref: /openbmc/linux/net/bridge/br_mrp_switchdev.c (revision fadd409136f0f21192d80816edd9529f27d88c17)
1*fadd4091SHoratiu Vultur // SPDX-License-Identifier: GPL-2.0-or-later
2*fadd4091SHoratiu Vultur 
3*fadd4091SHoratiu Vultur #include <net/switchdev.h>
4*fadd4091SHoratiu Vultur 
5*fadd4091SHoratiu Vultur #include "br_private_mrp.h"
6*fadd4091SHoratiu Vultur 
7*fadd4091SHoratiu Vultur int br_mrp_switchdev_add(struct net_bridge *br, struct br_mrp *mrp)
8*fadd4091SHoratiu Vultur {
9*fadd4091SHoratiu Vultur 	struct switchdev_obj_mrp mrp_obj = {
10*fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
11*fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_MRP,
12*fadd4091SHoratiu Vultur 		.p_port = rtnl_dereference(mrp->p_port)->dev,
13*fadd4091SHoratiu Vultur 		.s_port = rtnl_dereference(mrp->s_port)->dev,
14*fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
15*fadd4091SHoratiu Vultur 	};
16*fadd4091SHoratiu Vultur 	int err;
17*fadd4091SHoratiu Vultur 
18*fadd4091SHoratiu Vultur 	err = switchdev_port_obj_add(br->dev, &mrp_obj.obj, NULL);
19*fadd4091SHoratiu Vultur 
20*fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
21*fadd4091SHoratiu Vultur 		return err;
22*fadd4091SHoratiu Vultur 
23*fadd4091SHoratiu Vultur 	return 0;
24*fadd4091SHoratiu Vultur }
25*fadd4091SHoratiu Vultur 
26*fadd4091SHoratiu Vultur int br_mrp_switchdev_del(struct net_bridge *br, struct br_mrp *mrp)
27*fadd4091SHoratiu Vultur {
28*fadd4091SHoratiu Vultur 	struct switchdev_obj_mrp mrp_obj = {
29*fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
30*fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_MRP,
31*fadd4091SHoratiu Vultur 		.p_port = NULL,
32*fadd4091SHoratiu Vultur 		.s_port = NULL,
33*fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
34*fadd4091SHoratiu Vultur 	};
35*fadd4091SHoratiu Vultur 	int err;
36*fadd4091SHoratiu Vultur 
37*fadd4091SHoratiu Vultur 	err = switchdev_port_obj_del(br->dev, &mrp_obj.obj);
38*fadd4091SHoratiu Vultur 
39*fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
40*fadd4091SHoratiu Vultur 		return err;
41*fadd4091SHoratiu Vultur 
42*fadd4091SHoratiu Vultur 	return 0;
43*fadd4091SHoratiu Vultur }
44*fadd4091SHoratiu Vultur 
45*fadd4091SHoratiu Vultur int br_mrp_switchdev_set_ring_role(struct net_bridge *br,
46*fadd4091SHoratiu Vultur 				   struct br_mrp *mrp,
47*fadd4091SHoratiu Vultur 				   enum br_mrp_ring_role_type role)
48*fadd4091SHoratiu Vultur {
49*fadd4091SHoratiu Vultur 	struct switchdev_obj_ring_role_mrp mrp_role = {
50*fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
51*fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_RING_ROLE_MRP,
52*fadd4091SHoratiu Vultur 		.ring_role = role,
53*fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
54*fadd4091SHoratiu Vultur 	};
55*fadd4091SHoratiu Vultur 	int err;
56*fadd4091SHoratiu Vultur 
57*fadd4091SHoratiu Vultur 	if (role == BR_MRP_RING_ROLE_DISABLED)
58*fadd4091SHoratiu Vultur 		err = switchdev_port_obj_del(br->dev, &mrp_role.obj);
59*fadd4091SHoratiu Vultur 	else
60*fadd4091SHoratiu Vultur 		err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL);
61*fadd4091SHoratiu Vultur 
62*fadd4091SHoratiu Vultur 	return err;
63*fadd4091SHoratiu Vultur }
64*fadd4091SHoratiu Vultur 
65*fadd4091SHoratiu Vultur int br_mrp_switchdev_send_ring_test(struct net_bridge *br,
66*fadd4091SHoratiu Vultur 				    struct br_mrp *mrp, u32 interval,
67*fadd4091SHoratiu Vultur 				    u8 max_miss, u32 period)
68*fadd4091SHoratiu Vultur {
69*fadd4091SHoratiu Vultur 	struct switchdev_obj_ring_test_mrp test = {
70*fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
71*fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_RING_TEST_MRP,
72*fadd4091SHoratiu Vultur 		.interval = interval,
73*fadd4091SHoratiu Vultur 		.max_miss = max_miss,
74*fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
75*fadd4091SHoratiu Vultur 		.period = period,
76*fadd4091SHoratiu Vultur 	};
77*fadd4091SHoratiu Vultur 	int err;
78*fadd4091SHoratiu Vultur 
79*fadd4091SHoratiu Vultur 	if (interval == 0)
80*fadd4091SHoratiu Vultur 		err = switchdev_port_obj_del(br->dev, &test.obj);
81*fadd4091SHoratiu Vultur 	else
82*fadd4091SHoratiu Vultur 		err = switchdev_port_obj_add(br->dev, &test.obj, NULL);
83*fadd4091SHoratiu Vultur 
84*fadd4091SHoratiu Vultur 	return err;
85*fadd4091SHoratiu Vultur }
86*fadd4091SHoratiu Vultur 
87*fadd4091SHoratiu Vultur int br_mrp_switchdev_set_ring_state(struct net_bridge *br,
88*fadd4091SHoratiu Vultur 				    struct br_mrp *mrp,
89*fadd4091SHoratiu Vultur 				    enum br_mrp_ring_state_type state)
90*fadd4091SHoratiu Vultur {
91*fadd4091SHoratiu Vultur 	struct switchdev_obj_ring_state_mrp mrp_state = {
92*fadd4091SHoratiu Vultur 		.obj.orig_dev = br->dev,
93*fadd4091SHoratiu Vultur 		.obj.id = SWITCHDEV_OBJ_ID_RING_STATE_MRP,
94*fadd4091SHoratiu Vultur 		.ring_state = state,
95*fadd4091SHoratiu Vultur 		.ring_id = mrp->ring_id,
96*fadd4091SHoratiu Vultur 	};
97*fadd4091SHoratiu Vultur 	int err;
98*fadd4091SHoratiu Vultur 
99*fadd4091SHoratiu Vultur 	err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL);
100*fadd4091SHoratiu Vultur 
101*fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
102*fadd4091SHoratiu Vultur 		return err;
103*fadd4091SHoratiu Vultur 
104*fadd4091SHoratiu Vultur 	return 0;
105*fadd4091SHoratiu Vultur }
106*fadd4091SHoratiu Vultur 
107*fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_state(struct net_bridge_port *p,
108*fadd4091SHoratiu Vultur 				    enum br_mrp_port_state_type state)
109*fadd4091SHoratiu Vultur {
110*fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
111*fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
112*fadd4091SHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_MRP_PORT_STATE,
113*fadd4091SHoratiu Vultur 		.u.mrp_port_state = state,
114*fadd4091SHoratiu Vultur 	};
115*fadd4091SHoratiu Vultur 	int err;
116*fadd4091SHoratiu Vultur 
117*fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
118*fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
119*fadd4091SHoratiu Vultur 		br_warn(p->br, "error setting offload MRP state on port %u(%s)\n",
120*fadd4091SHoratiu Vultur 			(unsigned int)p->port_no, p->dev->name);
121*fadd4091SHoratiu Vultur 
122*fadd4091SHoratiu Vultur 	return err;
123*fadd4091SHoratiu Vultur }
124*fadd4091SHoratiu Vultur 
125*fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_role(struct net_bridge_port *p,
126*fadd4091SHoratiu Vultur 				   enum br_mrp_port_role_type role)
127*fadd4091SHoratiu Vultur {
128*fadd4091SHoratiu Vultur 	struct switchdev_attr attr = {
129*fadd4091SHoratiu Vultur 		.orig_dev = p->dev,
130*fadd4091SHoratiu Vultur 		.id = SWITCHDEV_ATTR_ID_MRP_PORT_ROLE,
131*fadd4091SHoratiu Vultur 		.u.mrp_port_role = role,
132*fadd4091SHoratiu Vultur 	};
133*fadd4091SHoratiu Vultur 	int err;
134*fadd4091SHoratiu Vultur 
135*fadd4091SHoratiu Vultur 	err = switchdev_port_attr_set(p->dev, &attr);
136*fadd4091SHoratiu Vultur 	if (err && err != -EOPNOTSUPP)
137*fadd4091SHoratiu Vultur 		return err;
138*fadd4091SHoratiu Vultur 
139*fadd4091SHoratiu Vultur 	return 0;
140*fadd4091SHoratiu Vultur }
141