cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

br_mrp_switchdev.c (5924B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2
      3#include <net/switchdev.h>
      4
      5#include "br_private_mrp.h"
      6
      7static enum br_mrp_hw_support
      8br_mrp_switchdev_port_obj(struct net_bridge *br,
      9			  const struct switchdev_obj *obj, bool add)
     10{
     11	int err;
     12
     13	if (add)
     14		err = switchdev_port_obj_add(br->dev, obj, NULL);
     15	else
     16		err = switchdev_port_obj_del(br->dev, obj);
     17
     18	/* In case of success just return and notify the SW that doesn't need
     19	 * to do anything
     20	 */
     21	if (!err)
     22		return BR_MRP_HW;
     23
     24	if (err != -EOPNOTSUPP)
     25		return BR_MRP_NONE;
     26
     27	/* Continue with SW backup */
     28	return BR_MRP_SW;
     29}
     30
     31int br_mrp_switchdev_add(struct net_bridge *br, struct br_mrp *mrp)
     32{
     33	struct switchdev_obj_mrp mrp_obj = {
     34		.obj.orig_dev = br->dev,
     35		.obj.id = SWITCHDEV_OBJ_ID_MRP,
     36		.p_port = rtnl_dereference(mrp->p_port)->dev,
     37		.s_port = rtnl_dereference(mrp->s_port)->dev,
     38		.ring_id = mrp->ring_id,
     39		.prio = mrp->prio,
     40	};
     41
     42	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
     43		return 0;
     44
     45	return switchdev_port_obj_add(br->dev, &mrp_obj.obj, NULL);
     46}
     47
     48int br_mrp_switchdev_del(struct net_bridge *br, struct br_mrp *mrp)
     49{
     50	struct switchdev_obj_mrp mrp_obj = {
     51		.obj.orig_dev = br->dev,
     52		.obj.id = SWITCHDEV_OBJ_ID_MRP,
     53		.p_port = NULL,
     54		.s_port = NULL,
     55		.ring_id = mrp->ring_id,
     56	};
     57
     58	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
     59		return 0;
     60
     61	return switchdev_port_obj_del(br->dev, &mrp_obj.obj);
     62}
     63
     64enum br_mrp_hw_support
     65br_mrp_switchdev_set_ring_role(struct net_bridge *br, struct br_mrp *mrp,
     66			       enum br_mrp_ring_role_type role)
     67{
     68	struct switchdev_obj_ring_role_mrp mrp_role = {
     69		.obj.orig_dev = br->dev,
     70		.obj.id = SWITCHDEV_OBJ_ID_RING_ROLE_MRP,
     71		.ring_role = role,
     72		.ring_id = mrp->ring_id,
     73		.sw_backup = false,
     74	};
     75	enum br_mrp_hw_support support;
     76	int err;
     77
     78	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
     79		return BR_MRP_SW;
     80
     81	support = br_mrp_switchdev_port_obj(br, &mrp_role.obj,
     82					    role != BR_MRP_RING_ROLE_DISABLED);
     83	if (support != BR_MRP_SW)
     84		return support;
     85
     86	/* If the driver can't configure to run completely the protocol in HW,
     87	 * then try again to configure the HW so the SW can run the protocol.
     88	 */
     89	mrp_role.sw_backup = true;
     90	if (role != BR_MRP_RING_ROLE_DISABLED)
     91		err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL);
     92	else
     93		err = switchdev_port_obj_del(br->dev, &mrp_role.obj);
     94
     95	if (!err)
     96		return BR_MRP_SW;
     97
     98	return BR_MRP_NONE;
     99}
    100
    101enum br_mrp_hw_support
    102br_mrp_switchdev_send_ring_test(struct net_bridge *br, struct br_mrp *mrp,
    103				u32 interval, u8 max_miss, u32 period,
    104				bool monitor)
    105{
    106	struct switchdev_obj_ring_test_mrp test = {
    107		.obj.orig_dev = br->dev,
    108		.obj.id = SWITCHDEV_OBJ_ID_RING_TEST_MRP,
    109		.interval = interval,
    110		.max_miss = max_miss,
    111		.ring_id = mrp->ring_id,
    112		.period = period,
    113		.monitor = monitor,
    114	};
    115
    116	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
    117		return BR_MRP_SW;
    118
    119	return br_mrp_switchdev_port_obj(br, &test.obj, interval != 0);
    120}
    121
    122int br_mrp_switchdev_set_ring_state(struct net_bridge *br,
    123				    struct br_mrp *mrp,
    124				    enum br_mrp_ring_state_type state)
    125{
    126	struct switchdev_obj_ring_state_mrp mrp_state = {
    127		.obj.orig_dev = br->dev,
    128		.obj.id = SWITCHDEV_OBJ_ID_RING_STATE_MRP,
    129		.ring_state = state,
    130		.ring_id = mrp->ring_id,
    131	};
    132
    133	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
    134		return 0;
    135
    136	return switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL);
    137}
    138
    139enum br_mrp_hw_support
    140br_mrp_switchdev_set_in_role(struct net_bridge *br, struct br_mrp *mrp,
    141			     u16 in_id, u32 ring_id,
    142			     enum br_mrp_in_role_type role)
    143{
    144	struct switchdev_obj_in_role_mrp mrp_role = {
    145		.obj.orig_dev = br->dev,
    146		.obj.id = SWITCHDEV_OBJ_ID_IN_ROLE_MRP,
    147		.in_role = role,
    148		.in_id = mrp->in_id,
    149		.ring_id = mrp->ring_id,
    150		.i_port = rtnl_dereference(mrp->i_port)->dev,
    151		.sw_backup = false,
    152	};
    153	enum br_mrp_hw_support support;
    154	int err;
    155
    156	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
    157		return BR_MRP_SW;
    158
    159	support = br_mrp_switchdev_port_obj(br, &mrp_role.obj,
    160					    role != BR_MRP_IN_ROLE_DISABLED);
    161	if (support != BR_MRP_NONE)
    162		return support;
    163
    164	/* If the driver can't configure to run completely the protocol in HW,
    165	 * then try again to configure the HW so the SW can run the protocol.
    166	 */
    167	mrp_role.sw_backup = true;
    168	if (role != BR_MRP_IN_ROLE_DISABLED)
    169		err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL);
    170	else
    171		err = switchdev_port_obj_del(br->dev, &mrp_role.obj);
    172
    173	if (!err)
    174		return BR_MRP_SW;
    175
    176	return BR_MRP_NONE;
    177}
    178
    179int br_mrp_switchdev_set_in_state(struct net_bridge *br, struct br_mrp *mrp,
    180				  enum br_mrp_in_state_type state)
    181{
    182	struct switchdev_obj_in_state_mrp mrp_state = {
    183		.obj.orig_dev = br->dev,
    184		.obj.id = SWITCHDEV_OBJ_ID_IN_STATE_MRP,
    185		.in_state = state,
    186		.in_id = mrp->in_id,
    187	};
    188
    189	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
    190		return 0;
    191
    192	return switchdev_port_obj_add(br->dev, &mrp_state.obj, NULL);
    193}
    194
    195enum br_mrp_hw_support
    196br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp,
    197			      u32 interval, u8 max_miss, u32 period)
    198{
    199	struct switchdev_obj_in_test_mrp test = {
    200		.obj.orig_dev = br->dev,
    201		.obj.id = SWITCHDEV_OBJ_ID_IN_TEST_MRP,
    202		.interval = interval,
    203		.max_miss = max_miss,
    204		.in_id = mrp->in_id,
    205		.period = period,
    206	};
    207
    208	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
    209		return BR_MRP_SW;
    210
    211	return br_mrp_switchdev_port_obj(br, &test.obj, interval != 0);
    212}
    213
    214int br_mrp_port_switchdev_set_state(struct net_bridge_port *p, u32 state)
    215{
    216	struct switchdev_attr attr = {
    217		.orig_dev = p->dev,
    218		.id = SWITCHDEV_ATTR_ID_PORT_STP_STATE,
    219		.u.stp_state = state,
    220	};
    221
    222	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
    223		return 0;
    224
    225	return switchdev_port_attr_set(p->dev, &attr, NULL);
    226}
    227
    228int br_mrp_port_switchdev_set_role(struct net_bridge_port *p,
    229				   enum br_mrp_port_role_type role)
    230{
    231	struct switchdev_attr attr = {
    232		.orig_dev = p->dev,
    233		.id = SWITCHDEV_ATTR_ID_MRP_PORT_ROLE,
    234		.u.mrp_port_role = role,
    235	};
    236
    237	if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
    238		return 0;
    239
    240	return switchdev_port_attr_set(p->dev, &attr, NULL);
    241}