mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
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: Horatiu Vultur <horatiu.vultur@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
c595c4330d
commit
a026c50b59
@@ -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 = {
|
|||||||
.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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user