1fadd4091SHoratiu Vultur // SPDX-License-Identifier: GPL-2.0-or-later 2fadd4091SHoratiu Vultur 3fadd4091SHoratiu Vultur #include <net/switchdev.h> 4fadd4091SHoratiu Vultur 5fadd4091SHoratiu Vultur #include "br_private_mrp.h" 6fadd4091SHoratiu Vultur 7fadd4091SHoratiu Vultur int br_mrp_switchdev_add(struct net_bridge *br, struct br_mrp *mrp) 8fadd4091SHoratiu Vultur { 9fadd4091SHoratiu Vultur struct switchdev_obj_mrp mrp_obj = { 10fadd4091SHoratiu Vultur .obj.orig_dev = br->dev, 11fadd4091SHoratiu Vultur .obj.id = SWITCHDEV_OBJ_ID_MRP, 12fadd4091SHoratiu Vultur .p_port = rtnl_dereference(mrp->p_port)->dev, 13fadd4091SHoratiu Vultur .s_port = rtnl_dereference(mrp->s_port)->dev, 14fadd4091SHoratiu Vultur .ring_id = mrp->ring_id, 154b3a61b0SHoratiu Vultur .prio = mrp->prio, 16fadd4091SHoratiu Vultur }; 17fadd4091SHoratiu Vultur int err; 18fadd4091SHoratiu Vultur 19fadd4091SHoratiu Vultur err = switchdev_port_obj_add(br->dev, &mrp_obj.obj, NULL); 20fadd4091SHoratiu Vultur 21fadd4091SHoratiu Vultur if (err && err != -EOPNOTSUPP) 22fadd4091SHoratiu Vultur return err; 23fadd4091SHoratiu Vultur 24fadd4091SHoratiu Vultur return 0; 25fadd4091SHoratiu Vultur } 26fadd4091SHoratiu Vultur 27fadd4091SHoratiu Vultur int br_mrp_switchdev_del(struct net_bridge *br, struct br_mrp *mrp) 28fadd4091SHoratiu Vultur { 29fadd4091SHoratiu Vultur struct switchdev_obj_mrp mrp_obj = { 30fadd4091SHoratiu Vultur .obj.orig_dev = br->dev, 31fadd4091SHoratiu Vultur .obj.id = SWITCHDEV_OBJ_ID_MRP, 32fadd4091SHoratiu Vultur .p_port = NULL, 33fadd4091SHoratiu Vultur .s_port = NULL, 34fadd4091SHoratiu Vultur .ring_id = mrp->ring_id, 35fadd4091SHoratiu Vultur }; 36fadd4091SHoratiu Vultur int err; 37fadd4091SHoratiu Vultur 38fadd4091SHoratiu Vultur err = switchdev_port_obj_del(br->dev, &mrp_obj.obj); 39fadd4091SHoratiu Vultur 40fadd4091SHoratiu Vultur if (err && err != -EOPNOTSUPP) 41fadd4091SHoratiu Vultur return err; 42fadd4091SHoratiu Vultur 43fadd4091SHoratiu Vultur return 0; 44fadd4091SHoratiu Vultur } 45fadd4091SHoratiu Vultur 46fadd4091SHoratiu Vultur int br_mrp_switchdev_set_ring_role(struct net_bridge *br, 47fadd4091SHoratiu Vultur struct br_mrp *mrp, 48fadd4091SHoratiu Vultur enum br_mrp_ring_role_type role) 49fadd4091SHoratiu Vultur { 50fadd4091SHoratiu Vultur struct switchdev_obj_ring_role_mrp mrp_role = { 51fadd4091SHoratiu Vultur .obj.orig_dev = br->dev, 52fadd4091SHoratiu Vultur .obj.id = SWITCHDEV_OBJ_ID_RING_ROLE_MRP, 53fadd4091SHoratiu Vultur .ring_role = role, 54fadd4091SHoratiu Vultur .ring_id = mrp->ring_id, 55fadd4091SHoratiu Vultur }; 56fadd4091SHoratiu Vultur int err; 57fadd4091SHoratiu Vultur 58fadd4091SHoratiu Vultur if (role == BR_MRP_RING_ROLE_DISABLED) 59fadd4091SHoratiu Vultur err = switchdev_port_obj_del(br->dev, &mrp_role.obj); 60fadd4091SHoratiu Vultur else 61fadd4091SHoratiu Vultur err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL); 62fadd4091SHoratiu Vultur 63fadd4091SHoratiu Vultur return err; 64fadd4091SHoratiu Vultur } 65fadd4091SHoratiu Vultur 66fadd4091SHoratiu Vultur int br_mrp_switchdev_send_ring_test(struct net_bridge *br, 67fadd4091SHoratiu Vultur struct br_mrp *mrp, u32 interval, 68c6676e7dSHoratiu Vultur u8 max_miss, u32 period, 69c6676e7dSHoratiu Vultur bool monitor) 70fadd4091SHoratiu Vultur { 71fadd4091SHoratiu Vultur struct switchdev_obj_ring_test_mrp test = { 72fadd4091SHoratiu Vultur .obj.orig_dev = br->dev, 73fadd4091SHoratiu Vultur .obj.id = SWITCHDEV_OBJ_ID_RING_TEST_MRP, 74fadd4091SHoratiu Vultur .interval = interval, 75fadd4091SHoratiu Vultur .max_miss = max_miss, 76fadd4091SHoratiu Vultur .ring_id = mrp->ring_id, 77fadd4091SHoratiu Vultur .period = period, 78c6676e7dSHoratiu Vultur .monitor = monitor, 79fadd4091SHoratiu Vultur }; 80fadd4091SHoratiu Vultur int err; 81fadd4091SHoratiu Vultur 82fadd4091SHoratiu Vultur if (interval == 0) 83fadd4091SHoratiu Vultur err = switchdev_port_obj_del(br->dev, &test.obj); 84fadd4091SHoratiu Vultur else 85fadd4091SHoratiu Vultur err = switchdev_port_obj_add(br->dev, &test.obj, NULL); 86fadd4091SHoratiu Vultur 87fadd4091SHoratiu Vultur return err; 88fadd4091SHoratiu Vultur } 89fadd4091SHoratiu Vultur 90fadd4091SHoratiu Vultur int br_mrp_switchdev_set_ring_state(struct net_bridge *br, 91fadd4091SHoratiu Vultur struct br_mrp *mrp, 92fadd4091SHoratiu Vultur enum br_mrp_ring_state_type state) 93fadd4091SHoratiu Vultur { 94fadd4091SHoratiu Vultur struct switchdev_obj_ring_state_mrp mrp_state = { 95fadd4091SHoratiu Vultur .obj.orig_dev = br->dev, 96fadd4091SHoratiu Vultur .obj.id = SWITCHDEV_OBJ_ID_RING_STATE_MRP, 97fadd4091SHoratiu Vultur .ring_state = state, 98fadd4091SHoratiu Vultur .ring_id = mrp->ring_id, 99fadd4091SHoratiu Vultur }; 100fadd4091SHoratiu Vultur int err; 101fadd4091SHoratiu Vultur 102fadd4091SHoratiu Vultur err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL); 103fadd4091SHoratiu Vultur 104fadd4091SHoratiu Vultur if (err && err != -EOPNOTSUPP) 105fadd4091SHoratiu Vultur return err; 106fadd4091SHoratiu Vultur 107fadd4091SHoratiu Vultur return 0; 108fadd4091SHoratiu Vultur } 109fadd4091SHoratiu Vultur 110f23f0db3SHoratiu Vultur int br_mrp_switchdev_set_in_role(struct net_bridge *br, struct br_mrp *mrp, 111f23f0db3SHoratiu Vultur u16 in_id, u32 ring_id, 112f23f0db3SHoratiu Vultur enum br_mrp_in_role_type role) 113f23f0db3SHoratiu Vultur { 114f23f0db3SHoratiu Vultur struct switchdev_obj_in_role_mrp mrp_role = { 115f23f0db3SHoratiu Vultur .obj.orig_dev = br->dev, 116f23f0db3SHoratiu Vultur .obj.id = SWITCHDEV_OBJ_ID_IN_ROLE_MRP, 117f23f0db3SHoratiu Vultur .in_role = role, 118f23f0db3SHoratiu Vultur .in_id = mrp->in_id, 119f23f0db3SHoratiu Vultur .ring_id = mrp->ring_id, 120f23f0db3SHoratiu Vultur .i_port = rtnl_dereference(mrp->i_port)->dev, 121f23f0db3SHoratiu Vultur }; 122f23f0db3SHoratiu Vultur int err; 123f23f0db3SHoratiu Vultur 124f23f0db3SHoratiu Vultur if (role == BR_MRP_IN_ROLE_DISABLED) 125f23f0db3SHoratiu Vultur err = switchdev_port_obj_del(br->dev, &mrp_role.obj); 126f23f0db3SHoratiu Vultur else 127f23f0db3SHoratiu Vultur err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL); 128f23f0db3SHoratiu Vultur 129f23f0db3SHoratiu Vultur return err; 130f23f0db3SHoratiu Vultur } 131f23f0db3SHoratiu Vultur 132f23f0db3SHoratiu Vultur int br_mrp_switchdev_set_in_state(struct net_bridge *br, struct br_mrp *mrp, 133f23f0db3SHoratiu Vultur enum br_mrp_in_state_type state) 134f23f0db3SHoratiu Vultur { 135f23f0db3SHoratiu Vultur struct switchdev_obj_in_state_mrp mrp_state = { 136f23f0db3SHoratiu Vultur .obj.orig_dev = br->dev, 137f23f0db3SHoratiu Vultur .obj.id = SWITCHDEV_OBJ_ID_IN_STATE_MRP, 138f23f0db3SHoratiu Vultur .in_state = state, 139f23f0db3SHoratiu Vultur .in_id = mrp->in_id, 140f23f0db3SHoratiu Vultur }; 141f23f0db3SHoratiu Vultur int err; 142f23f0db3SHoratiu Vultur 143f23f0db3SHoratiu Vultur err = switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL); 144f23f0db3SHoratiu Vultur 145f23f0db3SHoratiu Vultur if (err && err != -EOPNOTSUPP) 146f23f0db3SHoratiu Vultur return err; 147f23f0db3SHoratiu Vultur 148f23f0db3SHoratiu Vultur return 0; 149f23f0db3SHoratiu Vultur } 150f23f0db3SHoratiu Vultur 151f23f0db3SHoratiu Vultur int br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp, 152f23f0db3SHoratiu Vultur u32 interval, u8 max_miss, u32 period) 153f23f0db3SHoratiu Vultur { 154f23f0db3SHoratiu Vultur struct switchdev_obj_in_test_mrp test = { 155f23f0db3SHoratiu Vultur .obj.orig_dev = br->dev, 156f23f0db3SHoratiu Vultur .obj.id = SWITCHDEV_OBJ_ID_IN_TEST_MRP, 157f23f0db3SHoratiu Vultur .interval = interval, 158f23f0db3SHoratiu Vultur .max_miss = max_miss, 159f23f0db3SHoratiu Vultur .in_id = mrp->in_id, 160f23f0db3SHoratiu Vultur .period = period, 161f23f0db3SHoratiu Vultur }; 162f23f0db3SHoratiu Vultur int err; 163f23f0db3SHoratiu Vultur 164f23f0db3SHoratiu Vultur if (interval == 0) 165f23f0db3SHoratiu Vultur err = switchdev_port_obj_del(br->dev, &test.obj); 166f23f0db3SHoratiu Vultur else 167f23f0db3SHoratiu Vultur err = switchdev_port_obj_add(br->dev, &test.obj, NULL); 168f23f0db3SHoratiu Vultur 169f23f0db3SHoratiu Vultur return err; 170f23f0db3SHoratiu Vultur } 171f23f0db3SHoratiu Vultur 172*b2bdba1cSHoratiu Vultur int br_mrp_port_switchdev_set_state(struct net_bridge_port *p, u32 state) 173fadd4091SHoratiu Vultur { 174fadd4091SHoratiu Vultur struct switchdev_attr attr = { 175fadd4091SHoratiu Vultur .orig_dev = p->dev, 176*b2bdba1cSHoratiu Vultur .id = SWITCHDEV_ATTR_ID_PORT_STP_STATE, 177*b2bdba1cSHoratiu Vultur .u.stp_state = state, 178fadd4091SHoratiu Vultur }; 179fadd4091SHoratiu Vultur int err; 180fadd4091SHoratiu Vultur 181fadd4091SHoratiu Vultur err = switchdev_port_attr_set(p->dev, &attr); 182fadd4091SHoratiu Vultur if (err && err != -EOPNOTSUPP) 183fadd4091SHoratiu Vultur br_warn(p->br, "error setting offload MRP state on port %u(%s)\n", 184fadd4091SHoratiu Vultur (unsigned int)p->port_no, p->dev->name); 185fadd4091SHoratiu Vultur 186fadd4091SHoratiu Vultur return err; 187fadd4091SHoratiu Vultur } 188fadd4091SHoratiu Vultur 189fadd4091SHoratiu Vultur int br_mrp_port_switchdev_set_role(struct net_bridge_port *p, 190fadd4091SHoratiu Vultur enum br_mrp_port_role_type role) 191fadd4091SHoratiu Vultur { 192fadd4091SHoratiu Vultur struct switchdev_attr attr = { 193fadd4091SHoratiu Vultur .orig_dev = p->dev, 194fadd4091SHoratiu Vultur .id = SWITCHDEV_ATTR_ID_MRP_PORT_ROLE, 195fadd4091SHoratiu Vultur .u.mrp_port_role = role, 196fadd4091SHoratiu Vultur }; 197fadd4091SHoratiu Vultur int err; 198fadd4091SHoratiu Vultur 199fadd4091SHoratiu Vultur err = switchdev_port_attr_set(p->dev, &attr); 200fadd4091SHoratiu Vultur if (err && err != -EOPNOTSUPP) 201fadd4091SHoratiu Vultur return err; 202fadd4091SHoratiu Vultur 203fadd4091SHoratiu Vultur return 0; 204fadd4091SHoratiu Vultur } 205