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