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