1 // SPDX-License-Identifier: GPL-2.0-or-later
3 #include <net/switchdev.h>
5 #include "br_private_mrp.h"
7 int br_mrp_switchdev_add(struct net_bridge
*br
, struct br_mrp
*mrp
)
9 struct switchdev_obj_mrp mrp_obj
= {
10 .obj
.orig_dev
= br
->dev
,
11 .obj
.id
= SWITCHDEV_OBJ_ID_MRP
,
12 .p_port
= rtnl_dereference(mrp
->p_port
)->dev
,
13 .s_port
= rtnl_dereference(mrp
->s_port
)->dev
,
14 .ring_id
= mrp
->ring_id
,
19 err
= switchdev_port_obj_add(br
->dev
, &mrp_obj
.obj
, NULL
);
21 if (err
&& err
!= -EOPNOTSUPP
)
27 int br_mrp_switchdev_del(struct net_bridge
*br
, struct br_mrp
*mrp
)
29 struct switchdev_obj_mrp mrp_obj
= {
30 .obj
.orig_dev
= br
->dev
,
31 .obj
.id
= SWITCHDEV_OBJ_ID_MRP
,
34 .ring_id
= mrp
->ring_id
,
38 err
= switchdev_port_obj_del(br
->dev
, &mrp_obj
.obj
);
40 if (err
&& err
!= -EOPNOTSUPP
)
46 int br_mrp_switchdev_set_ring_role(struct net_bridge
*br
,
48 enum br_mrp_ring_role_type role
)
50 struct switchdev_obj_ring_role_mrp mrp_role
= {
51 .obj
.orig_dev
= br
->dev
,
52 .obj
.id
= SWITCHDEV_OBJ_ID_RING_ROLE_MRP
,
54 .ring_id
= mrp
->ring_id
,
58 if (role
== BR_MRP_RING_ROLE_DISABLED
)
59 err
= switchdev_port_obj_del(br
->dev
, &mrp_role
.obj
);
61 err
= switchdev_port_obj_add(br
->dev
, &mrp_role
.obj
, NULL
);
66 int br_mrp_switchdev_send_ring_test(struct net_bridge
*br
,
67 struct br_mrp
*mrp
, u32 interval
,
68 u8 max_miss
, u32 period
,
71 struct switchdev_obj_ring_test_mrp test
= {
72 .obj
.orig_dev
= br
->dev
,
73 .obj
.id
= SWITCHDEV_OBJ_ID_RING_TEST_MRP
,
76 .ring_id
= mrp
->ring_id
,
83 err
= switchdev_port_obj_del(br
->dev
, &test
.obj
);
85 err
= switchdev_port_obj_add(br
->dev
, &test
.obj
, NULL
);
90 int br_mrp_switchdev_set_ring_state(struct net_bridge
*br
,
92 enum br_mrp_ring_state_type state
)
94 struct switchdev_obj_ring_state_mrp mrp_state
= {
95 .obj
.orig_dev
= br
->dev
,
96 .obj
.id
= SWITCHDEV_OBJ_ID_RING_STATE_MRP
,
98 .ring_id
= mrp
->ring_id
,
102 err
= switchdev_port_obj_add(br
->dev
, &mrp_state
.obj
, NULL
);
104 if (err
&& err
!= -EOPNOTSUPP
)
110 int br_mrp_switchdev_set_in_role(struct net_bridge
*br
, struct br_mrp
*mrp
,
111 u16 in_id
, u32 ring_id
,
112 enum br_mrp_in_role_type role
)
114 struct switchdev_obj_in_role_mrp mrp_role
= {
115 .obj
.orig_dev
= br
->dev
,
116 .obj
.id
= SWITCHDEV_OBJ_ID_IN_ROLE_MRP
,
119 .ring_id
= mrp
->ring_id
,
120 .i_port
= rtnl_dereference(mrp
->i_port
)->dev
,
124 if (role
== BR_MRP_IN_ROLE_DISABLED
)
125 err
= switchdev_port_obj_del(br
->dev
, &mrp_role
.obj
);
127 err
= switchdev_port_obj_add(br
->dev
, &mrp_role
.obj
, NULL
);
132 int br_mrp_switchdev_set_in_state(struct net_bridge
*br
, struct br_mrp
*mrp
,
133 enum br_mrp_in_state_type state
)
135 struct switchdev_obj_in_state_mrp mrp_state
= {
136 .obj
.orig_dev
= br
->dev
,
137 .obj
.id
= SWITCHDEV_OBJ_ID_IN_STATE_MRP
,
143 err
= switchdev_port_obj_add(br
->dev
, &mrp_state
.obj
, NULL
);
145 if (err
&& err
!= -EOPNOTSUPP
)
151 int br_mrp_switchdev_send_in_test(struct net_bridge
*br
, struct br_mrp
*mrp
,
152 u32 interval
, u8 max_miss
, u32 period
)
154 struct switchdev_obj_in_test_mrp test
= {
155 .obj
.orig_dev
= br
->dev
,
156 .obj
.id
= SWITCHDEV_OBJ_ID_IN_TEST_MRP
,
157 .interval
= interval
,
158 .max_miss
= max_miss
,
165 err
= switchdev_port_obj_del(br
->dev
, &test
.obj
);
167 err
= switchdev_port_obj_add(br
->dev
, &test
.obj
, NULL
);
172 int br_mrp_port_switchdev_set_state(struct net_bridge_port
*p
,
173 enum br_mrp_port_state_type state
)
175 struct switchdev_attr attr
= {
177 .id
= SWITCHDEV_ATTR_ID_MRP_PORT_STATE
,
178 .u
.mrp_port_state
= state
,
182 err
= switchdev_port_attr_set(p
->dev
, &attr
);
183 if (err
&& err
!= -EOPNOTSUPP
)
184 br_warn(p
->br
, "error setting offload MRP state on port %u(%s)\n",
185 (unsigned int)p
->port_no
, p
->dev
->name
);
190 int br_mrp_port_switchdev_set_role(struct net_bridge_port
*p
,
191 enum br_mrp_port_role_type role
)
193 struct switchdev_attr attr
= {
195 .id
= SWITCHDEV_ATTR_ID_MRP_PORT_ROLE
,
196 .u
.mrp_port_role
= role
,
200 err
= switchdev_port_attr_set(p
->dev
, &attr
);
201 if (err
&& err
!= -EOPNOTSUPP
)