diff options
| author | Texas Instruments Auto Merger <lcpd_integration@list.ti.com> | 2022-05-09 03:21:59 -0500 |
|---|---|---|
| committer | Texas Instruments Auto Merger <lcpd_integration@list.ti.com> | 2022-05-09 03:21:59 -0500 |
| commit | 5ea577eaff94c7d6ce3325688c5b6ffbbeaa415b (patch) | |
| tree | 76935b1d4af04188221d4bf54025a25bfb54c238 | |
| parent | 2f6b5cad94895e2f0491dc34bcce93a382f80f28 (diff) | |
| parent | 91ea70eb3334d9d5b2c9ea13b274bbeb5bc678f9 (diff) | |
Merged TI feature connectivity into ti-linux-5.10.y
TI-Feature: connectivity
TI-Branch: connectivity-ti-linux-5.10.y
* 'connectivity-ti-linux-5.10.y' of ssh://bitbucket.itg.ti.com/lcpdpublicdom/connectivity:
net: ti: icssg-prueth: move phy_connect()/phy_disconnect()
arm64: dts: ti: k3-am625-sk: Add missing ethernet aliases
net: ti: icssg_prueth: fix missed back to back TX timestamp responses
net: ti: icssg_prueth: clean up pending TX timestamp requests at link down
Signed-off-by: Texas Instruments Auto Merger <lcpd_integration@list.ti.com>
| -rw-r--r-- | arch/arm64/boot/dts/ti/k3-am625-sk.dts | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/ti/icssg_prueth.c | 95 | ||||
| -rw-r--r-- | drivers/net/ethernet/ti/icssg_prueth.h | 1 |
3 files changed, 61 insertions, 37 deletions
diff --git a/arch/arm64/boot/dts/ti/k3-am625-sk.dts b/arch/arm64/boot/dts/ti/k3-am625-sk.dts index 618e1efb7344..e5ca3b609ce0 100644 --- a/arch/arm64/boot/dts/ti/k3-am625-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am625-sk.dts @@ -24,6 +24,8 @@ spi0 = &ospi0; usb0 = &usb0; usb1 = &usb1; + ethernet0 = &cpsw_port1; + ethernet1 = &cpsw_port2; }; chosen { diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c index 979ba488a613..376f5ffde03e 100644 --- a/drivers/net/ethernet/ti/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg_prueth.c @@ -766,48 +766,44 @@ static void tx_ts_work(struct prueth_emac *emac) u64 ns; struct skb_shared_hwtstamps ssh; struct sk_buff *skb; - int timeout = 10; int ret = 0; struct emac_tx_ts_response tsr; u32 hi_sw; - while (timeout-- > 0) { - /* wait for response or timeout */ + /* There may be more than one pending requests */ + while (1) { ret = emac_get_tx_ts(emac, &tsr); - if (!ret) + if (ret) /* nothing more */ break; - usleep_range(10, 20); - } - if (ret) { - netdev_err(emac->ndev, "TX timestamp timeout\n"); - return; - } + if (tsr.cookie >= PRUETH_MAX_TX_TS_REQUESTS || + !emac->tx_ts_skb[tsr.cookie]) { + netdev_err(emac->ndev, "Invalid TX TS cookie 0x%x\n", + tsr.cookie); + break; + } - if (tsr.cookie >= PRUETH_MAX_TX_TS_REQUESTS || - !emac->tx_ts_skb[tsr.cookie]) { - netdev_err(emac->ndev, "Invalid TX TS cookie 0x%x\n", - tsr.cookie); - return; - } + skb = emac->tx_ts_skb[tsr.cookie]; + emac->tx_ts_skb[tsr.cookie] = NULL; /* free slot */ + if (!skb) { + netdev_err(emac->ndev, "Driver Bug! got NULL skb\n"); + break; + } - skb = emac->tx_ts_skb[tsr.cookie]; - emac->tx_ts_skb[tsr.cookie] = NULL; /* free slot */ - if (!skb) { - netdev_err(emac->ndev, "Driver Bug! got NULL skb\n"); - return; - } + hi_sw = readl(emac->prueth->shram.va + + TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); + ns = icssg_ts_to_ns(hi_sw, tsr.hi_ts, tsr.lo_ts, + IEP_DEFAULT_CYCLE_TIME_NS); - hi_sw = readl(emac->prueth->shram.va + - TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); - ns = icssg_ts_to_ns(hi_sw, tsr.hi_ts, tsr.lo_ts, - IEP_DEFAULT_CYCLE_TIME_NS); + memset(&ssh, 0, sizeof(ssh)); + ssh.hwtstamp = ns_to_ktime(ns); - memset(&ssh, 0, sizeof(ssh)); - ssh.hwtstamp = ns_to_ktime(ns); + skb_tstamp_tx(skb, &ssh); + dev_consume_skb_any(skb); - skb_tstamp_tx(skb, &ssh); - dev_consume_skb_any(skb); + if (atomic_dec_and_test(&emac->tx_ts_pending)) /* no more? */ + break; + } return; } @@ -883,7 +879,6 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) epib[1] = 0; if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && emac->tx_ts_enabled) { - /* We currently support only one TX HW timestamp at a time */ tx_ts_cookie = prueth_tx_ts_cookie_get(emac); if (tx_ts_cookie >= 0) { skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; @@ -961,6 +956,9 @@ tx_push: goto drop_free_descs; } + if (in_tx_ts) + atomic_inc(&emac->tx_ts_pending); + if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) < MAX_SKB_FRAGS) { netif_tx_stop_queue(netif_txq); /* Barrier, so that stop_queue visible to other cpus */ @@ -1300,6 +1298,18 @@ static void prueth_emac_stop(struct prueth_emac *emac) rproc_shutdown(prueth->pru[slice]); } +static void prueth_cleanup_tx_ts(struct prueth_emac *emac) +{ + int i; + + for (i = 0; i < PRUETH_MAX_TX_TS_REQUESTS; i++) { + if (emac->tx_ts_skb[i]) { + dev_kfree_skb_any(emac->tx_ts_skb[i]); + emac->tx_ts_skb[i] = NULL; + } + } +} + /* called back by PHY layer if there is change in link state of hw port*/ static void emac_adjust_link(struct net_device *ndev) { @@ -1380,6 +1390,7 @@ static void emac_adjust_link(struct net_device *ndev) /* link OFF */ netif_carrier_off(ndev); netif_tx_stop_all_queues(ndev); + prueth_cleanup_tx_ts(emac); } } @@ -1788,10 +1799,6 @@ skip_mgm_irq: icssg_qos_init(ndev); - emac_phy_connect(emac); - /* Get attached phy details */ - phy_attached_info(emac->phydev); - /* start PHY */ phy_start(emac->phydev); @@ -1874,8 +1881,6 @@ static int emac_ndo_stop(struct net_device *ndev) /* block packets from wire */ phy_stop(emac->phydev); - phy_disconnect(emac->phydev); - emac->phydev = NULL; icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac)); @@ -2952,6 +2957,11 @@ static int prueth_probe(struct platform_device *pdev) devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC0]->devlink_port, prueth->emac[PRUETH_MAC0]->ndev); prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev; + + emac_phy_connect(prueth->emac[PRUETH_MAC0]); + /* Get attached phy details */ + phy_attached_info(prueth->emac[PRUETH_MAC0]->phydev); + } if (eth1_node) { @@ -2960,10 +2970,15 @@ static int prueth_probe(struct platform_device *pdev) dev_err(dev, "can't register netdev for port MII1"); goto netdev_unregister; } + devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC1]->devlink_port, prueth->emac[PRUETH_MAC1]->ndev); prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev; + + emac_phy_connect(prueth->emac[PRUETH_MAC1]); + /* Get attached phy details */ + phy_attached_info(prueth->emac[PRUETH_MAC1]->phydev); } if (prueth->is_switchmode_supported) { @@ -2988,6 +3003,10 @@ netdev_unregister: for (i = 0; i < PRUETH_NUM_MACS; i++) { if (!prueth->registered_netdevs[i]) continue; + if (prueth->emac[i]->phydev) { + phy_disconnect(prueth->emac[i]->phydev); + prueth->emac[i]->phydev = NULL; + } unregister_netdev(prueth->registered_netdevs[i]); } @@ -3046,6 +3065,8 @@ static int prueth_remove(struct platform_device *pdev) for (i = 0; i < PRUETH_NUM_MACS; i++) { if (!prueth->registered_netdevs[i]) continue; + phy_disconnect(prueth->emac[i]->phydev); + prueth->emac[i]->phydev = NULL; unregister_netdev(prueth->registered_netdevs[i]); } prueth_unregister_devlink(prueth); diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h index b176ac96c2d7..9c0d948ed700 100644 --- a/drivers/net/ethernet/ti/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg_prueth.h @@ -170,6 +170,7 @@ struct prueth_emac { /* TX HW Timestamping */ /* TX TS cookie will be index to the tx_ts_skb array */ struct sk_buff *tx_ts_skb[PRUETH_MAX_TX_TS_REQUESTS]; + atomic_t tx_ts_pending; int tx_ts_irq; u8 cmd_seq; |
