summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTexas Instruments Auto Merger <lcpd_integration@list.ti.com>2022-05-09 03:21:59 -0500
committerTexas Instruments Auto Merger <lcpd_integration@list.ti.com>2022-05-09 03:21:59 -0500
commit5ea577eaff94c7d6ce3325688c5b6ffbbeaa415b (patch)
tree76935b1d4af04188221d4bf54025a25bfb54c238
parent2f6b5cad94895e2f0491dc34bcce93a382f80f28 (diff)
parent91ea70eb3334d9d5b2c9ea13b274bbeb5bc678f9 (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.dts2
-rw-r--r--drivers/net/ethernet/ti/icssg_prueth.c95
-rw-r--r--drivers/net/ethernet/ti/icssg_prueth.h1
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;