Commit a026c50b authored by Horatiu Vultur's avatar Horatiu Vultur Committed by David S. Miller

net: dsa: felix: Add support for MRP

Implement functions 'port_mrp_add', 'port_mrp_del',
'port_mrp_add_ring_role' and 'port_mrp_del_ring_role' to call the mrp
functions from ocelot.

Also all MRP frames that arrive to CPU on queue number OCELOT_MRP_CPUQ
will be forward by the SW.
Signed-off-by: default avatarHoratiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c595c433
...@@ -1582,6 +1582,40 @@ static int felix_sb_occ_tc_port_bind_get(struct dsa_switch *ds, int port, ...@@ -1582,6 +1582,40 @@ static int felix_sb_occ_tc_port_bind_get(struct dsa_switch *ds, int port,
pool_type, p_cur, p_max); pool_type, p_cur, p_max);
} }
static int felix_mrp_add(struct dsa_switch *ds, int port,
const struct switchdev_obj_mrp *mrp)
{
struct ocelot *ocelot = ds->priv;
return ocelot_mrp_add(ocelot, port, mrp);
}
static int felix_mrp_del(struct dsa_switch *ds, int port,
const struct switchdev_obj_mrp *mrp)
{
struct ocelot *ocelot = ds->priv;
return ocelot_mrp_add(ocelot, port, mrp);
}
static int
felix_mrp_add_ring_role(struct dsa_switch *ds, int port,
const struct switchdev_obj_ring_role_mrp *mrp)
{
struct ocelot *ocelot = ds->priv;
return ocelot_mrp_add_ring_role(ocelot, port, mrp);
}
static int
felix_mrp_del_ring_role(struct dsa_switch *ds, int port,
const struct switchdev_obj_ring_role_mrp *mrp)
{
struct ocelot *ocelot = ds->priv;
return ocelot_mrp_del_ring_role(ocelot, port, mrp);
}
const struct dsa_switch_ops felix_switch_ops = { const struct dsa_switch_ops felix_switch_ops = {
.get_tag_protocol = felix_get_tag_protocol, .get_tag_protocol = felix_get_tag_protocol,
.change_tag_protocol = felix_change_tag_protocol, .change_tag_protocol = felix_change_tag_protocol,
...@@ -1636,6 +1670,10 @@ const struct dsa_switch_ops felix_switch_ops = { ...@@ -1636,6 +1670,10 @@ const struct dsa_switch_ops felix_switch_ops = {
.devlink_sb_occ_max_clear = felix_sb_occ_max_clear, .devlink_sb_occ_max_clear = felix_sb_occ_max_clear,
.devlink_sb_occ_port_pool_get = felix_sb_occ_port_pool_get, .devlink_sb_occ_port_pool_get = felix_sb_occ_port_pool_get,
.devlink_sb_occ_tc_port_bind_get= felix_sb_occ_tc_port_bind_get, .devlink_sb_occ_tc_port_bind_get= felix_sb_occ_tc_port_bind_get,
.port_mrp_add = felix_mrp_add,
.port_mrp_del = felix_mrp_del,
.port_mrp_add_ring_role = felix_mrp_add_ring_role,
.port_mrp_del_ring_role = felix_mrp_del_ring_role,
}; };
struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port) struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port)
......
...@@ -83,6 +83,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, ...@@ -83,6 +83,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
struct dsa_port *dp; struct dsa_port *dp;
u8 *extraction; u8 *extraction;
u16 vlan_tpid; u16 vlan_tpid;
u64 cpuq;
/* Revert skb->data by the amount consumed by the DSA master, /* Revert skb->data by the amount consumed by the DSA master,
* so it points to the beginning of the frame. * so it points to the beginning of the frame.
...@@ -112,6 +113,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, ...@@ -112,6 +113,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
ocelot_xfh_get_qos_class(extraction, &qos_class); ocelot_xfh_get_qos_class(extraction, &qos_class);
ocelot_xfh_get_tag_type(extraction, &tag_type); ocelot_xfh_get_tag_type(extraction, &tag_type);
ocelot_xfh_get_vlan_tci(extraction, &vlan_tci); ocelot_xfh_get_vlan_tci(extraction, &vlan_tci);
ocelot_xfh_get_cpuq(extraction, &cpuq);
skb->dev = dsa_master_find_slave(netdev, 0, src_port); skb->dev = dsa_master_find_slave(netdev, 0, src_port);
if (!skb->dev) if (!skb->dev)
...@@ -126,6 +128,12 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, ...@@ -126,6 +128,12 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
skb->offload_fwd_mark = 1; skb->offload_fwd_mark = 1;
skb->priority = qos_class; skb->priority = qos_class;
#if IS_ENABLED(CONFIG_BRIDGE_MRP)
if (eth_hdr(skb)->h_proto == cpu_to_be16(ETH_P_MRP) &&
cpuq & BIT(OCELOT_MRP_CPUQ))
skb->offload_fwd_mark = 0;
#endif
/* Ocelot switches copy frames unmodified to the CPU. However, it is /* Ocelot switches copy frames unmodified to the CPU. However, it is
* possible for the user to request a VLAN modification through * possible for the user to request a VLAN modification through
* VCAP_IS1_ACT_VID_REPLACE_ENA. In this case, what will happen is that * VCAP_IS1_ACT_VID_REPLACE_ENA. In this case, what will happen is that
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment