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