br_mrp_switchdev.c 4.6 KB

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