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 } 144