1 // SPDX-License-Identifier: GPL-2.0-or-later
3 #include <net/switchdev.h>
5 #include "br_private_mrp.h"
7 static enum br_mrp_hw_support
8 br_mrp_switchdev_port_obj(struct net_bridge
*br
,
9 const struct switchdev_obj
*obj
, bool add
)
14 err
= switchdev_port_obj_add(br
->dev
, obj
, NULL
);
16 err
= switchdev_port_obj_del(br
->dev
, obj
);
18 /* In case of success just return and notify the SW that doesn't need
24 if (err
!= -EOPNOTSUPP
)
27 /* Continue with SW backup */
31 int br_mrp_switchdev_add(struct net_bridge
*br
, struct br_mrp
*mrp
)
33 struct switchdev_obj_mrp mrp_obj
= {
34 .obj
.orig_dev
= br
->dev
,
35 .obj
.id
= SWITCHDEV_OBJ_ID_MRP
,
36 .p_port
= rtnl_dereference(mrp
->p_port
)->dev
,
37 .s_port
= rtnl_dereference(mrp
->s_port
)->dev
,
38 .ring_id
= mrp
->ring_id
,
42 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
45 return switchdev_port_obj_add(br
->dev
, &mrp_obj
.obj
, NULL
);
48 int br_mrp_switchdev_del(struct net_bridge
*br
, struct br_mrp
*mrp
)
50 struct switchdev_obj_mrp mrp_obj
= {
51 .obj
.orig_dev
= br
->dev
,
52 .obj
.id
= SWITCHDEV_OBJ_ID_MRP
,
55 .ring_id
= mrp
->ring_id
,
58 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
61 return switchdev_port_obj_del(br
->dev
, &mrp_obj
.obj
);
64 enum br_mrp_hw_support
65 br_mrp_switchdev_set_ring_role(struct net_bridge
*br
, struct br_mrp
*mrp
,
66 enum br_mrp_ring_role_type role
)
68 struct switchdev_obj_ring_role_mrp mrp_role
= {
69 .obj
.orig_dev
= br
->dev
,
70 .obj
.id
= SWITCHDEV_OBJ_ID_RING_ROLE_MRP
,
72 .ring_id
= mrp
->ring_id
,
75 enum br_mrp_hw_support support
;
78 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
81 support
= br_mrp_switchdev_port_obj(br
, &mrp_role
.obj
,
82 role
!= BR_MRP_RING_ROLE_DISABLED
);
83 if (support
!= BR_MRP_SW
)
86 /* If the driver can't configure to run completely the protocol in HW,
87 * then try again to configure the HW so the SW can run the protocol.
89 mrp_role
.sw_backup
= true;
90 if (role
!= BR_MRP_RING_ROLE_DISABLED
)
91 err
= switchdev_port_obj_add(br
->dev
, &mrp_role
.obj
, NULL
);
93 err
= switchdev_port_obj_del(br
->dev
, &mrp_role
.obj
);
101 enum br_mrp_hw_support
102 br_mrp_switchdev_send_ring_test(struct net_bridge
*br
, struct br_mrp
*mrp
,
103 u32 interval
, u8 max_miss
, u32 period
,
106 struct switchdev_obj_ring_test_mrp test
= {
107 .obj
.orig_dev
= br
->dev
,
108 .obj
.id
= SWITCHDEV_OBJ_ID_RING_TEST_MRP
,
109 .interval
= interval
,
110 .max_miss
= max_miss
,
111 .ring_id
= mrp
->ring_id
,
116 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
119 return br_mrp_switchdev_port_obj(br
, &test
.obj
, interval
!= 0);
122 int br_mrp_switchdev_set_ring_state(struct net_bridge
*br
,
124 enum br_mrp_ring_state_type state
)
126 struct switchdev_obj_ring_state_mrp mrp_state
= {
127 .obj
.orig_dev
= br
->dev
,
128 .obj
.id
= SWITCHDEV_OBJ_ID_RING_STATE_MRP
,
130 .ring_id
= mrp
->ring_id
,
133 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
136 return switchdev_port_obj_add(br
->dev
, &mrp_state
.obj
, NULL
);
139 enum br_mrp_hw_support
140 br_mrp_switchdev_set_in_role(struct net_bridge
*br
, struct br_mrp
*mrp
,
141 u16 in_id
, u32 ring_id
,
142 enum br_mrp_in_role_type role
)
144 struct switchdev_obj_in_role_mrp mrp_role
= {
145 .obj
.orig_dev
= br
->dev
,
146 .obj
.id
= SWITCHDEV_OBJ_ID_IN_ROLE_MRP
,
149 .ring_id
= mrp
->ring_id
,
150 .i_port
= rtnl_dereference(mrp
->i_port
)->dev
,
153 enum br_mrp_hw_support support
;
156 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
159 support
= br_mrp_switchdev_port_obj(br
, &mrp_role
.obj
,
160 role
!= BR_MRP_IN_ROLE_DISABLED
);
161 if (support
!= BR_MRP_NONE
)
164 /* If the driver can't configure to run completely the protocol in HW,
165 * then try again to configure the HW so the SW can run the protocol.
167 mrp_role
.sw_backup
= true;
168 if (role
!= BR_MRP_IN_ROLE_DISABLED
)
169 err
= switchdev_port_obj_add(br
->dev
, &mrp_role
.obj
, NULL
);
171 err
= switchdev_port_obj_del(br
->dev
, &mrp_role
.obj
);
179 int br_mrp_switchdev_set_in_state(struct net_bridge
*br
, struct br_mrp
*mrp
,
180 enum br_mrp_in_state_type state
)
182 struct switchdev_obj_in_state_mrp mrp_state
= {
183 .obj
.orig_dev
= br
->dev
,
184 .obj
.id
= SWITCHDEV_OBJ_ID_IN_STATE_MRP
,
189 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
192 return switchdev_port_obj_add(br
->dev
, &mrp_state
.obj
, NULL
);
195 enum br_mrp_hw_support
196 br_mrp_switchdev_send_in_test(struct net_bridge
*br
, struct br_mrp
*mrp
,
197 u32 interval
, u8 max_miss
, u32 period
)
199 struct switchdev_obj_in_test_mrp test
= {
200 .obj
.orig_dev
= br
->dev
,
201 .obj
.id
= SWITCHDEV_OBJ_ID_IN_TEST_MRP
,
202 .interval
= interval
,
203 .max_miss
= max_miss
,
208 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
211 return br_mrp_switchdev_port_obj(br
, &test
.obj
, interval
!= 0);
214 int br_mrp_port_switchdev_set_state(struct net_bridge_port
*p
, u32 state
)
216 struct switchdev_attr attr
= {
218 .id
= SWITCHDEV_ATTR_ID_PORT_STP_STATE
,
219 .u
.stp_state
= state
,
222 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
225 return switchdev_port_attr_set(p
->dev
, &attr
, NULL
);
228 int br_mrp_port_switchdev_set_role(struct net_bridge_port
*p
,
229 enum br_mrp_port_role_type role
)
231 struct switchdev_attr attr
= {
233 .id
= SWITCHDEV_ATTR_ID_MRP_PORT_ROLE
,
234 .u
.mrp_port_role
= role
,
237 if (!IS_ENABLED(CONFIG_NET_SWITCHDEV
))
240 return switchdev_port_attr_set(p
->dev
, &attr
, NULL
);