summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/ti/icssg_prueth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/ti/icssg_prueth.c')
-rw-r--r--drivers/net/ethernet/ti/icssg_prueth.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c
index 6ad92f40c71c..f3d033723857 100644
--- a/drivers/net/ethernet/ti/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg_prueth.c
@@ -67,7 +67,9 @@
#define DEFAULT_UNTAG_MASK 1
#define NETIF_PRUETH_HSR_OFFLOAD (NETIF_F_HW_HSR_FWD | \
- NETIF_F_HW_HSR_DUP)
+ NETIF_F_HW_HSR_DUP | \
+ NETIF_F_HW_HSR_TAG_INS | \
+ NETIF_F_HW_HSR_TAG_RM)
/* CTRLMMR_ICSSG_RGMII_CTRL register bits */
#define ICSSG_CTRL_RGMII_ID_MODE BIT(24)
@@ -75,6 +77,7 @@
#define IEP_DEFAULT_CYCLE_TIME_NS 1000000 /* 1 ms */
#define PRUETH_UNDIRECTED_PKT_DST_TAG 0
+#define PRUETH_UNDIRECTED_PKT_TAG_INS BIT(30)
static void prueth_cleanup_rx_chns(struct prueth_emac *emac,
struct prueth_rx_chn *rx_chn,
@@ -875,6 +878,9 @@ static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device
if (prueth->is_hsr_offload_mode && (ndev->features & NETIF_F_HW_HSR_DUP))
dst_tag_id = PRUETH_UNDIRECTED_PKT_DST_TAG;
+ if (prueth->is_hsr_offload_mode && (ndev->features & NETIF_F_HW_HSR_TAG_INS))
+ epib[1] |= PRUETH_UNDIRECTED_PKT_TAG_INS;
+
cppi5_desc_set_tags_ids(&first_desc->hdr, 0, dst_tag_id);
k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len);
@@ -1486,7 +1492,8 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
sc_desc.cyclecounter0_set = cyclecount & GENMASK(31, 0);
sc_desc.cyclecounter1_set = (cyclecount & GENMASK(63, 32)) >> 32;
sc_desc.iepcount_set = ns % cycletime;
- sc_desc.CMP0_current = cycletime - 4; //Count from 0 to (cycle time)-4
+ /* Count from 0 to (cycle time)- emac->iep->def_inc */
+ sc_desc.CMP0_current = cycletime - emac->iep->def_inc;
memcpy_toio(sc_descp, &sc_desc, sizeof(sc_desc));
@@ -1677,6 +1684,13 @@ static int emac_ndo_open(struct net_device *ndev)
}
}
+ if (prueth->is_hsr_offload_mode) {
+ if (ndev->features & NETIF_F_HW_HSR_TAG_RM)
+ emac_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_ENABLE);
+ else
+ emac_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_DISABLE);
+ }
+
flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
ret = emac_fdb_flow_id_updated(emac);
@@ -2688,16 +2702,20 @@ static int prueth_netdevice_event(struct notifier_block *unused,
if ((ndev->features & NETIF_PRUETH_HSR_OFFLOAD) &&
is_hsr_master(info->upper_dev)) {
- if (!prueth->hsr_dev) {
- prueth->hsr_dev = info->upper_dev;
-
- icssg_class_set_host_mac_addr(prueth->miig_rt,
- prueth->hsr_dev->dev_addr);
- } else {
- if (prueth->hsr_dev != info->upper_dev) {
- dev_err(prueth->dev, "Both interfaces must be linked to same upper device\n");
- return -EOPNOTSUPP;
+ if (info->linking) {
+ if (!prueth->hsr_dev) {
+ prueth->hsr_dev = info->upper_dev;
+
+ icssg_class_set_host_mac_addr(prueth->miig_rt,
+ prueth->hsr_dev->dev_addr);
+ } else {
+ if (prueth->hsr_dev != info->upper_dev) {
+ dev_err(prueth->dev, "Both interfaces must be linked to same upper device\n");
+ return -EOPNOTSUPP;
+ }
}
+ } else {
+ prueth->hsr_dev = NULL;
}
}
@@ -3280,6 +3298,7 @@ static int prueth_probe(struct platform_device *pdev)
icss_iep_init_fw(prueth->iep1);
}
+ spin_lock_init(&prueth->vtbl_lock);
/* setup netdev interfaces */
if (eth0_node) {
ret = prueth_netdev_init(prueth, eth0_node);