Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2
  3#include <net/switchdev.h>
  4
  5#include "br_private_mrp.h"
  6
  7int 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
 27int 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
 46int 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
 66int 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
 90int 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
110int 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)
113{
114	struct switchdev_obj_in_role_mrp mrp_role = {
115		.obj.orig_dev = br->dev,
116		.obj.id = SWITCHDEV_OBJ_ID_IN_ROLE_MRP,
117		.in_role = role,
118		.in_id = mrp->in_id,
119		.ring_id = mrp->ring_id,
120		.i_port = rtnl_dereference(mrp->i_port)->dev,
121	};
122	int err;
123
124	if (role == BR_MRP_IN_ROLE_DISABLED)
125		err = switchdev_port_obj_del(br->dev, &mrp_role.obj);
126	else
127		err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL);
128
129	return err;
130}
131
132int br_mrp_switchdev_set_in_state(struct net_bridge *br, struct br_mrp *mrp,
133				  enum br_mrp_in_state_type state)
134{
135	struct switchdev_obj_in_state_mrp mrp_state = {
136		.obj.orig_dev = br->dev,
137		.obj.id = SWITCHDEV_OBJ_ID_IN_STATE_MRP,
138		.in_state = state,
139		.in_id = mrp->in_id,
140	};
141	int err;
142
143	err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL);
144
145	if (err && err != -EOPNOTSUPP)
146		return err;
147
148	return 0;
149}
150
151int br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp,
152				  u32 interval, u8 max_miss, u32 period)
153{
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,
159		.in_id = mrp->in_id,
160		.period = period,
161	};
162	int err;
163
164	if (interval == 0)
165		err = switchdev_port_obj_del(br->dev, &test.obj);
166	else
167		err = switchdev_port_obj_add(br->dev, &test.obj, NULL);
168
169	return err;
170}
171
172int br_mrp_port_switchdev_set_state(struct net_bridge_port *p,
173				    enum br_mrp_port_state_type state)
174{
175	struct switchdev_attr attr = {
176		.orig_dev = p->dev,
177		.id = SWITCHDEV_ATTR_ID_MRP_PORT_STATE,
178		.u.mrp_port_state = state,
179	};
180	int err;
181
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);
186
187	return err;
188}
189
190int br_mrp_port_switchdev_set_role(struct net_bridge_port *p,
191				   enum br_mrp_port_role_type role)
192{
193	struct switchdev_attr attr = {
194		.orig_dev = p->dev,
195		.id = SWITCHDEV_ATTR_ID_MRP_PORT_ROLE,
196		.u.mrp_port_role = role,
197	};
198	int err;
199
200	err = switchdev_port_attr_set(p->dev, &attr);
201	if (err && err != -EOPNOTSUPP)
202		return err;
203
204	return 0;
205}