diff options
author | WingMan Kwok <w-kwok2@ti.com> | 2016-12-08 17:21:56 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-12-10 23:31:19 -0500 |
commit | 6246168b4a38357b135d07370464f27d4f3a68ce (patch) | |
tree | 7b686426cda1f210122265ae98220609c88ec58c | |
parent | 529ed12752635ba8a35dc78ec70ed6f42570b4ca (diff) |
net: ethernet: ti: netcp: add support of cpts
This patch adds support of the cpts device found in the
gbe and 10gbe ethernet switches on the keystone 2 SoCs
(66AK2E/L/Hx, 66AK2Gx).
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/ti/Kconfig | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/netcp.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/netcp_core.c | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/netcp_ethss.c | 437 |
4 files changed, 452 insertions, 14 deletions
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index ff7f518a0702..dc217fd7a734 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig | |||
@@ -75,12 +75,13 @@ config TI_CPSW | |||
75 | 75 | ||
76 | config TI_CPTS | 76 | config TI_CPTS |
77 | tristate "TI Common Platform Time Sync (CPTS) Support" | 77 | tristate "TI Common Platform Time Sync (CPTS) Support" |
78 | depends on TI_CPSW | 78 | depends on TI_CPSW || TI_KEYSTONE_NETCP |
79 | select PTP_1588_CLOCK | 79 | select PTP_1588_CLOCK |
80 | ---help--- | 80 | ---help--- |
81 | This driver supports the Common Platform Time Sync unit of | 81 | This driver supports the Common Platform Time Sync unit of |
82 | the CPSW Ethernet Switch. The unit can time stamp PTP UDP/IPv4 | 82 | the CPSW Ethernet Switch and Keystone 2 1g/10g Switch Subsystem. |
83 | and Layer 2 packets, and the driver offers a PTP Hardware Clock. | 83 | The unit can time stamp PTP UDP/IPv4 and Layer 2 packets, and the |
84 | driver offers a PTP Hardware Clock. | ||
84 | 85 | ||
85 | config TI_KEYSTONE_NETCP | 86 | config TI_KEYSTONE_NETCP |
86 | tristate "TI Keystone NETCP Core Support" | 87 | tristate "TI Keystone NETCP Core Support" |
diff --git a/drivers/net/ethernet/ti/netcp.h b/drivers/net/ethernet/ti/netcp.h index 17a26a429b71..0f58c584ae09 100644 --- a/drivers/net/ethernet/ti/netcp.h +++ b/drivers/net/ethernet/ti/netcp.h | |||
@@ -121,7 +121,7 @@ struct netcp_packet { | |||
121 | bool rxtstamp_complete; | 121 | bool rxtstamp_complete; |
122 | void *ts_context; | 122 | void *ts_context; |
123 | 123 | ||
124 | int (*txtstamp_complete)(void *ctx, struct netcp_packet *pkt); | 124 | void (*txtstamp)(void *ctx, struct sk_buff *skb); |
125 | }; | 125 | }; |
126 | 126 | ||
127 | static inline u32 *netcp_push_psdata(struct netcp_packet *p_info, | 127 | static inline u32 *netcp_push_psdata(struct netcp_packet *p_info, |
diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index 7981b99ea06e..c243335ed649 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c | |||
@@ -100,6 +100,11 @@ struct netcp_intf_modpriv { | |||
100 | void *module_priv; | 100 | void *module_priv; |
101 | }; | 101 | }; |
102 | 102 | ||
103 | struct netcp_tx_cb { | ||
104 | void *ts_context; | ||
105 | void (*txtstamp)(void *context, struct sk_buff *skb); | ||
106 | }; | ||
107 | |||
103 | static LIST_HEAD(netcp_devices); | 108 | static LIST_HEAD(netcp_devices); |
104 | static LIST_HEAD(netcp_modules); | 109 | static LIST_HEAD(netcp_modules); |
105 | static DEFINE_MUTEX(netcp_modules_lock); | 110 | static DEFINE_MUTEX(netcp_modules_lock); |
@@ -544,6 +549,7 @@ int netcp_register_rxhook(struct netcp_intf *netcp_priv, int order, | |||
544 | 549 | ||
545 | return 0; | 550 | return 0; |
546 | } | 551 | } |
552 | EXPORT_SYMBOL_GPL(netcp_register_rxhook); | ||
547 | 553 | ||
548 | int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, | 554 | int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, |
549 | netcp_hook_rtn *hook_rtn, void *hook_data) | 555 | netcp_hook_rtn *hook_rtn, void *hook_data) |
@@ -566,6 +572,7 @@ int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, | |||
566 | 572 | ||
567 | return -ENOENT; | 573 | return -ENOENT; |
568 | } | 574 | } |
575 | EXPORT_SYMBOL_GPL(netcp_unregister_rxhook); | ||
569 | 576 | ||
570 | static void netcp_frag_free(bool is_frag, void *ptr) | 577 | static void netcp_frag_free(bool is_frag, void *ptr) |
571 | { | 578 | { |
@@ -730,6 +737,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) | |||
730 | 737 | ||
731 | /* Call each of the RX hooks */ | 738 | /* Call each of the RX hooks */ |
732 | p_info.skb = skb; | 739 | p_info.skb = skb; |
740 | skb->dev = netcp->ndev; | ||
733 | p_info.rxtstamp_complete = false; | 741 | p_info.rxtstamp_complete = false; |
734 | list_for_each_entry(rx_hook, &netcp->rxhook_list_head, list) { | 742 | list_for_each_entry(rx_hook, &netcp->rxhook_list_head, list) { |
735 | int ret; | 743 | int ret; |
@@ -987,6 +995,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, | |||
987 | unsigned int budget) | 995 | unsigned int budget) |
988 | { | 996 | { |
989 | struct knav_dma_desc *desc; | 997 | struct knav_dma_desc *desc; |
998 | struct netcp_tx_cb *tx_cb; | ||
990 | struct sk_buff *skb; | 999 | struct sk_buff *skb; |
991 | unsigned int dma_sz; | 1000 | unsigned int dma_sz; |
992 | dma_addr_t dma; | 1001 | dma_addr_t dma; |
@@ -1014,6 +1023,10 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, | |||
1014 | continue; | 1023 | continue; |
1015 | } | 1024 | } |
1016 | 1025 | ||
1026 | tx_cb = (struct netcp_tx_cb *)skb->cb; | ||
1027 | if (tx_cb->txtstamp) | ||
1028 | tx_cb->txtstamp(tx_cb->ts_context, skb); | ||
1029 | |||
1017 | if (netif_subqueue_stopped(netcp->ndev, skb) && | 1030 | if (netif_subqueue_stopped(netcp->ndev, skb) && |
1018 | netif_running(netcp->ndev) && | 1031 | netif_running(netcp->ndev) && |
1019 | (knav_pool_count(netcp->tx_pool) > | 1032 | (knav_pool_count(netcp->tx_pool) > |
@@ -1154,6 +1167,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, | |||
1154 | struct netcp_tx_pipe *tx_pipe = NULL; | 1167 | struct netcp_tx_pipe *tx_pipe = NULL; |
1155 | struct netcp_hook_list *tx_hook; | 1168 | struct netcp_hook_list *tx_hook; |
1156 | struct netcp_packet p_info; | 1169 | struct netcp_packet p_info; |
1170 | struct netcp_tx_cb *tx_cb; | ||
1157 | unsigned int dma_sz; | 1171 | unsigned int dma_sz; |
1158 | dma_addr_t dma; | 1172 | dma_addr_t dma; |
1159 | u32 tmp = 0; | 1173 | u32 tmp = 0; |
@@ -1164,7 +1178,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, | |||
1164 | p_info.tx_pipe = NULL; | 1178 | p_info.tx_pipe = NULL; |
1165 | p_info.psdata_len = 0; | 1179 | p_info.psdata_len = 0; |
1166 | p_info.ts_context = NULL; | 1180 | p_info.ts_context = NULL; |
1167 | p_info.txtstamp_complete = NULL; | 1181 | p_info.txtstamp = NULL; |
1168 | p_info.epib = desc->epib; | 1182 | p_info.epib = desc->epib; |
1169 | p_info.psdata = (u32 __force *)desc->psdata; | 1183 | p_info.psdata = (u32 __force *)desc->psdata; |
1170 | memset(p_info.epib, 0, KNAV_DMA_NUM_EPIB_WORDS * sizeof(__le32)); | 1184 | memset(p_info.epib, 0, KNAV_DMA_NUM_EPIB_WORDS * sizeof(__le32)); |
@@ -1189,6 +1203,10 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, | |||
1189 | goto out; | 1203 | goto out; |
1190 | } | 1204 | } |
1191 | 1205 | ||
1206 | tx_cb = (struct netcp_tx_cb *)skb->cb; | ||
1207 | tx_cb->ts_context = p_info.ts_context; | ||
1208 | tx_cb->txtstamp = p_info.txtstamp; | ||
1209 | |||
1192 | /* update descriptor */ | 1210 | /* update descriptor */ |
1193 | if (p_info.psdata_len) { | 1211 | if (p_info.psdata_len) { |
1194 | /* psdata points to both native-endian and device-endian data */ | 1212 | /* psdata points to both native-endian and device-endian data */ |
diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c index 48cb04fb7e0c..c7e547e4f2b1 100644 --- a/drivers/net/ethernet/ti/netcp_ethss.c +++ b/drivers/net/ethernet/ti/netcp_ethss.c | |||
@@ -23,10 +23,13 @@ | |||
23 | #include <linux/of_mdio.h> | 23 | #include <linux/of_mdio.h> |
24 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
25 | #include <linux/if_vlan.h> | 25 | #include <linux/if_vlan.h> |
26 | #include <linux/ptp_classify.h> | ||
27 | #include <linux/net_tstamp.h> | ||
26 | #include <linux/ethtool.h> | 28 | #include <linux/ethtool.h> |
27 | 29 | ||
28 | #include "cpsw_ale.h" | 30 | #include "cpsw_ale.h" |
29 | #include "netcp.h" | 31 | #include "netcp.h" |
32 | #include "cpts.h" | ||
30 | 33 | ||
31 | #define NETCP_DRIVER_NAME "TI KeyStone Ethernet Driver" | 34 | #define NETCP_DRIVER_NAME "TI KeyStone Ethernet Driver" |
32 | #define NETCP_DRIVER_VERSION "v1.0" | 35 | #define NETCP_DRIVER_VERSION "v1.0" |
@@ -51,6 +54,7 @@ | |||
51 | #define GBE13_EMAC_OFFSET 0x100 | 54 | #define GBE13_EMAC_OFFSET 0x100 |
52 | #define GBE13_SLAVE_PORT2_OFFSET 0x200 | 55 | #define GBE13_SLAVE_PORT2_OFFSET 0x200 |
53 | #define GBE13_HW_STATS_OFFSET 0x300 | 56 | #define GBE13_HW_STATS_OFFSET 0x300 |
57 | #define GBE13_CPTS_OFFSET 0x500 | ||
54 | #define GBE13_ALE_OFFSET 0x600 | 58 | #define GBE13_ALE_OFFSET 0x600 |
55 | #define GBE13_HOST_PORT_NUM 0 | 59 | #define GBE13_HOST_PORT_NUM 0 |
56 | #define GBE13_NUM_ALE_ENTRIES 1024 | 60 | #define GBE13_NUM_ALE_ENTRIES 1024 |
@@ -74,6 +78,7 @@ | |||
74 | #define GBENU_SLAVE_PORT_OFFSET 0x2000 | 78 | #define GBENU_SLAVE_PORT_OFFSET 0x2000 |
75 | #define GBENU_EMAC_OFFSET 0x2330 | 79 | #define GBENU_EMAC_OFFSET 0x2330 |
76 | #define GBENU_HW_STATS_OFFSET 0x1a000 | 80 | #define GBENU_HW_STATS_OFFSET 0x1a000 |
81 | #define GBENU_CPTS_OFFSET 0x1d000 | ||
77 | #define GBENU_ALE_OFFSET 0x1e000 | 82 | #define GBENU_ALE_OFFSET 0x1e000 |
78 | #define GBENU_HOST_PORT_NUM 0 | 83 | #define GBENU_HOST_PORT_NUM 0 |
79 | #define GBENU_NUM_ALE_ENTRIES 1024 | 84 | #define GBENU_NUM_ALE_ENTRIES 1024 |
@@ -93,6 +98,7 @@ | |||
93 | #define XGBE10_HOST_PORT_OFFSET 0x34 | 98 | #define XGBE10_HOST_PORT_OFFSET 0x34 |
94 | #define XGBE10_SLAVE_PORT_OFFSET 0x64 | 99 | #define XGBE10_SLAVE_PORT_OFFSET 0x64 |
95 | #define XGBE10_EMAC_OFFSET 0x400 | 100 | #define XGBE10_EMAC_OFFSET 0x400 |
101 | #define XGBE10_CPTS_OFFSET 0x600 | ||
96 | #define XGBE10_ALE_OFFSET 0x700 | 102 | #define XGBE10_ALE_OFFSET 0x700 |
97 | #define XGBE10_HW_STATS_OFFSET 0x800 | 103 | #define XGBE10_HW_STATS_OFFSET 0x800 |
98 | #define XGBE10_HOST_PORT_NUM 0 | 104 | #define XGBE10_HOST_PORT_NUM 0 |
@@ -155,6 +161,7 @@ | |||
155 | 161 | ||
156 | #define GBE_TX_QUEUE 648 | 162 | #define GBE_TX_QUEUE 648 |
157 | #define GBE_TXHOOK_ORDER 0 | 163 | #define GBE_TXHOOK_ORDER 0 |
164 | #define GBE_RXHOOK_ORDER 0 | ||
158 | #define GBE_DEFAULT_ALE_AGEOUT 30 | 165 | #define GBE_DEFAULT_ALE_AGEOUT 30 |
159 | #define SLAVE_LINK_IS_XGMII(s) ((s)->link_interface >= XGMII_LINK_MAC_PHY) | 166 | #define SLAVE_LINK_IS_XGMII(s) ((s)->link_interface >= XGMII_LINK_MAC_PHY) |
160 | #define NETCP_LINK_STATE_INVALID -1 | 167 | #define NETCP_LINK_STATE_INVALID -1 |
@@ -169,6 +176,56 @@ | |||
169 | 176 | ||
170 | #define HOST_TX_PRI_MAP_DEFAULT 0x00000000 | 177 | #define HOST_TX_PRI_MAP_DEFAULT 0x00000000 |
171 | 178 | ||
179 | #if IS_ENABLED(CONFIG_TI_CPTS) | ||
180 | /* Px_TS_CTL register fields */ | ||
181 | #define TS_RX_ANX_F_EN BIT(0) | ||
182 | #define TS_RX_VLAN_LT1_EN BIT(1) | ||
183 | #define TS_RX_VLAN_LT2_EN BIT(2) | ||
184 | #define TS_RX_ANX_D_EN BIT(3) | ||
185 | #define TS_TX_ANX_F_EN BIT(4) | ||
186 | #define TS_TX_VLAN_LT1_EN BIT(5) | ||
187 | #define TS_TX_VLAN_LT2_EN BIT(6) | ||
188 | #define TS_TX_ANX_D_EN BIT(7) | ||
189 | #define TS_LT2_EN BIT(8) | ||
190 | #define TS_RX_ANX_E_EN BIT(9) | ||
191 | #define TS_TX_ANX_E_EN BIT(10) | ||
192 | #define TS_MSG_TYPE_EN_SHIFT 16 | ||
193 | #define TS_MSG_TYPE_EN_MASK 0xffff | ||
194 | |||
195 | /* Px_TS_SEQ_LTYPE register fields */ | ||
196 | #define TS_SEQ_ID_OFS_SHIFT 16 | ||
197 | #define TS_SEQ_ID_OFS_MASK 0x3f | ||
198 | |||
199 | /* Px_TS_CTL_LTYPE2 register fields */ | ||
200 | #define TS_107 BIT(16) | ||
201 | #define TS_129 BIT(17) | ||
202 | #define TS_130 BIT(18) | ||
203 | #define TS_131 BIT(19) | ||
204 | #define TS_132 BIT(20) | ||
205 | #define TS_319 BIT(21) | ||
206 | #define TS_320 BIT(22) | ||
207 | #define TS_TTL_NONZERO BIT(23) | ||
208 | #define TS_UNI_EN BIT(24) | ||
209 | #define TS_UNI_EN_SHIFT 24 | ||
210 | |||
211 | #define TS_TX_ANX_ALL_EN \ | ||
212 | (TS_TX_ANX_D_EN | TS_TX_ANX_E_EN | TS_TX_ANX_F_EN) | ||
213 | |||
214 | #define TS_RX_ANX_ALL_EN \ | ||
215 | (TS_RX_ANX_D_EN | TS_RX_ANX_E_EN | TS_RX_ANX_F_EN) | ||
216 | |||
217 | #define TS_CTL_DST_PORT TS_319 | ||
218 | #define TS_CTL_DST_PORT_SHIFT 21 | ||
219 | |||
220 | #define TS_CTL_MADDR_ALL \ | ||
221 | (TS_107 | TS_129 | TS_130 | TS_131 | TS_132) | ||
222 | |||
223 | #define TS_CTL_MADDR_SHIFT 16 | ||
224 | |||
225 | /* The PTP event messages - Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp. */ | ||
226 | #define EVENT_MSG_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3)) | ||
227 | #endif /* CONFIG_TI_CPTS */ | ||
228 | |||
172 | struct xgbe_ss_regs { | 229 | struct xgbe_ss_regs { |
173 | u32 id_ver; | 230 | u32 id_ver; |
174 | u32 synce_count; | 231 | u32 synce_count; |
@@ -616,6 +673,13 @@ struct gbe_hw_stats { | |||
616 | #define GBE_MAX_HW_STAT_MODS 9 | 673 | #define GBE_MAX_HW_STAT_MODS 9 |
617 | #define GBE_HW_STATS_REG_MAP_SZ 0x100 | 674 | #define GBE_HW_STATS_REG_MAP_SZ 0x100 |
618 | 675 | ||
676 | struct ts_ctl { | ||
677 | int uni; | ||
678 | u8 dst_port_map; | ||
679 | u8 maddr_map; | ||
680 | u8 ts_mcast_type; | ||
681 | }; | ||
682 | |||
619 | struct gbe_slave { | 683 | struct gbe_slave { |
620 | void __iomem *port_regs; | 684 | void __iomem *port_regs; |
621 | void __iomem *emac_regs; | 685 | void __iomem *emac_regs; |
@@ -630,6 +694,7 @@ struct gbe_slave { | |||
630 | u32 mac_control; | 694 | u32 mac_control; |
631 | u8 phy_port_t; | 695 | u8 phy_port_t; |
632 | struct device_node *phy_node; | 696 | struct device_node *phy_node; |
697 | struct ts_ctl ts_ctl; | ||
633 | struct list_head slave_list; | 698 | struct list_head slave_list; |
634 | }; | 699 | }; |
635 | 700 | ||
@@ -655,6 +720,7 @@ struct gbe_priv { | |||
655 | void __iomem *switch_regs; | 720 | void __iomem *switch_regs; |
656 | void __iomem *host_port_regs; | 721 | void __iomem *host_port_regs; |
657 | void __iomem *ale_reg; | 722 | void __iomem *ale_reg; |
723 | void __iomem *cpts_reg; | ||
658 | void __iomem *sgmii_port_regs; | 724 | void __iomem *sgmii_port_regs; |
659 | void __iomem *sgmii_port34_regs; | 725 | void __iomem *sgmii_port34_regs; |
660 | void __iomem *xgbe_serdes_regs; | 726 | void __iomem *xgbe_serdes_regs; |
@@ -678,6 +744,9 @@ struct gbe_priv { | |||
678 | int num_et_stats; | 744 | int num_et_stats; |
679 | /* Lock for updating the hwstats */ | 745 | /* Lock for updating the hwstats */ |
680 | spinlock_t hw_stats_lock; | 746 | spinlock_t hw_stats_lock; |
747 | |||
748 | int cpts_registered; | ||
749 | struct cpts *cpts; | ||
681 | }; | 750 | }; |
682 | 751 | ||
683 | struct gbe_intf { | 752 | struct gbe_intf { |
@@ -1912,6 +1981,49 @@ static int keystone_set_link_ksettings(struct net_device *ndev, | |||
1912 | return phy_ethtool_ksettings_set(phy, cmd); | 1981 | return phy_ethtool_ksettings_set(phy, cmd); |
1913 | } | 1982 | } |
1914 | 1983 | ||
1984 | #if IS_ENABLED(CONFIG_TI_CPTS) | ||
1985 | static int keystone_get_ts_info(struct net_device *ndev, | ||
1986 | struct ethtool_ts_info *info) | ||
1987 | { | ||
1988 | struct netcp_intf *netcp = netdev_priv(ndev); | ||
1989 | struct gbe_intf *gbe_intf; | ||
1990 | |||
1991 | gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); | ||
1992 | if (!gbe_intf || !gbe_intf->gbe_dev->cpts) | ||
1993 | return -EINVAL; | ||
1994 | |||
1995 | info->so_timestamping = | ||
1996 | SOF_TIMESTAMPING_TX_HARDWARE | | ||
1997 | SOF_TIMESTAMPING_TX_SOFTWARE | | ||
1998 | SOF_TIMESTAMPING_RX_HARDWARE | | ||
1999 | SOF_TIMESTAMPING_RX_SOFTWARE | | ||
2000 | SOF_TIMESTAMPING_SOFTWARE | | ||
2001 | SOF_TIMESTAMPING_RAW_HARDWARE; | ||
2002 | info->phc_index = gbe_intf->gbe_dev->cpts->phc_index; | ||
2003 | info->tx_types = | ||
2004 | (1 << HWTSTAMP_TX_OFF) | | ||
2005 | (1 << HWTSTAMP_TX_ON); | ||
2006 | info->rx_filters = | ||
2007 | (1 << HWTSTAMP_FILTER_NONE) | | ||
2008 | (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) | | ||
2009 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); | ||
2010 | return 0; | ||
2011 | } | ||
2012 | #else | ||
2013 | static int keystone_get_ts_info(struct net_device *ndev, | ||
2014 | struct ethtool_ts_info *info) | ||
2015 | { | ||
2016 | info->so_timestamping = | ||
2017 | SOF_TIMESTAMPING_TX_SOFTWARE | | ||
2018 | SOF_TIMESTAMPING_RX_SOFTWARE | | ||
2019 | SOF_TIMESTAMPING_SOFTWARE; | ||
2020 | info->phc_index = -1; | ||
2021 | info->tx_types = 0; | ||
2022 | info->rx_filters = 0; | ||
2023 | return 0; | ||
2024 | } | ||
2025 | #endif /* CONFIG_TI_CPTS */ | ||
2026 | |||
1915 | static const struct ethtool_ops keystone_ethtool_ops = { | 2027 | static const struct ethtool_ops keystone_ethtool_ops = { |
1916 | .get_drvinfo = keystone_get_drvinfo, | 2028 | .get_drvinfo = keystone_get_drvinfo, |
1917 | .get_link = ethtool_op_get_link, | 2029 | .get_link = ethtool_op_get_link, |
@@ -1922,6 +2034,7 @@ static const struct ethtool_ops keystone_ethtool_ops = { | |||
1922 | .get_ethtool_stats = keystone_get_ethtool_stats, | 2034 | .get_ethtool_stats = keystone_get_ethtool_stats, |
1923 | .get_link_ksettings = keystone_get_link_ksettings, | 2035 | .get_link_ksettings = keystone_get_link_ksettings, |
1924 | .set_link_ksettings = keystone_set_link_ksettings, | 2036 | .set_link_ksettings = keystone_set_link_ksettings, |
2037 | .get_ts_info = keystone_get_ts_info, | ||
1925 | }; | 2038 | }; |
1926 | 2039 | ||
1927 | #define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \ | 2040 | #define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \ |
@@ -2365,16 +2478,279 @@ static int gbe_del_vid(void *intf_priv, int vid) | |||
2365 | return 0; | 2478 | return 0; |
2366 | } | 2479 | } |
2367 | 2480 | ||
2481 | #if IS_ENABLED(CONFIG_TI_CPTS) | ||
2482 | #define HAS_PHY_TXTSTAMP(p) ((p)->drv && (p)->drv->txtstamp) | ||
2483 | #define HAS_PHY_RXTSTAMP(p) ((p)->drv && (p)->drv->rxtstamp) | ||
2484 | |||
2485 | static void gbe_txtstamp(void *context, struct sk_buff *skb) | ||
2486 | { | ||
2487 | struct gbe_intf *gbe_intf = context; | ||
2488 | struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; | ||
2489 | |||
2490 | cpts_tx_timestamp(gbe_dev->cpts, skb); | ||
2491 | } | ||
2492 | |||
2493 | static bool gbe_need_txtstamp(struct gbe_intf *gbe_intf, | ||
2494 | const struct netcp_packet *p_info) | ||
2495 | { | ||
2496 | struct sk_buff *skb = p_info->skb; | ||
2497 | unsigned int class = ptp_classify_raw(skb); | ||
2498 | |||
2499 | if (class == PTP_CLASS_NONE) | ||
2500 | return false; | ||
2501 | |||
2502 | switch (class) { | ||
2503 | case PTP_CLASS_V1_IPV4: | ||
2504 | case PTP_CLASS_V1_IPV6: | ||
2505 | case PTP_CLASS_V2_IPV4: | ||
2506 | case PTP_CLASS_V2_IPV6: | ||
2507 | case PTP_CLASS_V2_L2: | ||
2508 | case (PTP_CLASS_V2_VLAN | PTP_CLASS_L2): | ||
2509 | case (PTP_CLASS_V2_VLAN | PTP_CLASS_IPV4): | ||
2510 | case (PTP_CLASS_V2_VLAN | PTP_CLASS_IPV6): | ||
2511 | return true; | ||
2512 | } | ||
2513 | |||
2514 | return false; | ||
2515 | } | ||
2516 | |||
2517 | static int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf, | ||
2518 | struct netcp_packet *p_info) | ||
2519 | { | ||
2520 | struct phy_device *phydev = p_info->skb->dev->phydev; | ||
2521 | struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; | ||
2522 | |||
2523 | if (!(skb_shinfo(p_info->skb)->tx_flags & SKBTX_HW_TSTAMP) || | ||
2524 | !cpts_is_tx_enabled(gbe_dev->cpts)) | ||
2525 | return 0; | ||
2526 | |||
2527 | /* If phy has the txtstamp api, assume it will do it. | ||
2528 | * We mark it here because skb_tx_timestamp() is called | ||
2529 | * after all the txhooks are called. | ||
2530 | */ | ||
2531 | if (phydev && HAS_PHY_TXTSTAMP(phydev)) { | ||
2532 | skb_shinfo(p_info->skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
2533 | return 0; | ||
2534 | } | ||
2535 | |||
2536 | if (gbe_need_txtstamp(gbe_intf, p_info)) { | ||
2537 | p_info->txtstamp = gbe_txtstamp; | ||
2538 | p_info->ts_context = (void *)gbe_intf; | ||
2539 | skb_shinfo(p_info->skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
2540 | } | ||
2541 | |||
2542 | return 0; | ||
2543 | } | ||
2544 | |||
2545 | static int gbe_rxtstamp(struct gbe_intf *gbe_intf, struct netcp_packet *p_info) | ||
2546 | { | ||
2547 | struct phy_device *phydev = p_info->skb->dev->phydev; | ||
2548 | struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; | ||
2549 | |||
2550 | if (p_info->rxtstamp_complete) | ||
2551 | return 0; | ||
2552 | |||
2553 | if (phydev && HAS_PHY_RXTSTAMP(phydev)) { | ||
2554 | p_info->rxtstamp_complete = true; | ||
2555 | return 0; | ||
2556 | } | ||
2557 | |||
2558 | cpts_rx_timestamp(gbe_dev->cpts, p_info->skb); | ||
2559 | p_info->rxtstamp_complete = true; | ||
2560 | |||
2561 | return 0; | ||
2562 | } | ||
2563 | |||
2564 | static int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *ifr) | ||
2565 | { | ||
2566 | struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; | ||
2567 | struct cpts *cpts = gbe_dev->cpts; | ||
2568 | struct hwtstamp_config cfg; | ||
2569 | |||
2570 | if (!cpts) | ||
2571 | return -EOPNOTSUPP; | ||
2572 | |||
2573 | cfg.flags = 0; | ||
2574 | cfg.tx_type = cpts_is_tx_enabled(cpts) ? | ||
2575 | HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; | ||
2576 | cfg.rx_filter = (cpts_is_rx_enabled(cpts) ? | ||
2577 | cpts->rx_enable : HWTSTAMP_FILTER_NONE); | ||
2578 | |||
2579 | return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; | ||
2580 | } | ||
2581 | |||
2582 | static void gbe_hwtstamp(struct gbe_intf *gbe_intf) | ||
2583 | { | ||
2584 | struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; | ||
2585 | struct gbe_slave *slave = gbe_intf->slave; | ||
2586 | u32 ts_en, seq_id, ctl; | ||
2587 | |||
2588 | if (!cpts_is_rx_enabled(gbe_dev->cpts) && | ||
2589 | !cpts_is_tx_enabled(gbe_dev->cpts)) { | ||
2590 | writel(0, GBE_REG_ADDR(slave, port_regs, ts_ctl)); | ||
2591 | return; | ||
2592 | } | ||
2593 | |||
2594 | seq_id = (30 << TS_SEQ_ID_OFS_SHIFT) | ETH_P_1588; | ||
2595 | ts_en = EVENT_MSG_BITS << TS_MSG_TYPE_EN_SHIFT; | ||
2596 | ctl = ETH_P_1588 | TS_TTL_NONZERO | | ||
2597 | (slave->ts_ctl.dst_port_map << TS_CTL_DST_PORT_SHIFT) | | ||
2598 | (slave->ts_ctl.uni ? TS_UNI_EN : | ||
2599 | slave->ts_ctl.maddr_map << TS_CTL_MADDR_SHIFT); | ||
2600 | |||
2601 | if (cpts_is_tx_enabled(gbe_dev->cpts)) | ||
2602 | ts_en |= (TS_TX_ANX_ALL_EN | TS_TX_VLAN_LT1_EN); | ||
2603 | |||
2604 | if (cpts_is_rx_enabled(gbe_dev->cpts)) | ||
2605 | ts_en |= (TS_RX_ANX_ALL_EN | TS_RX_VLAN_LT1_EN); | ||
2606 | |||
2607 | writel(ts_en, GBE_REG_ADDR(slave, port_regs, ts_ctl)); | ||
2608 | writel(seq_id, GBE_REG_ADDR(slave, port_regs, ts_seq_ltype)); | ||
2609 | writel(ctl, GBE_REG_ADDR(slave, port_regs, ts_ctl_ltype2)); | ||
2610 | } | ||
2611 | |||
2612 | static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr) | ||
2613 | { | ||
2614 | struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; | ||
2615 | struct cpts *cpts = gbe_dev->cpts; | ||
2616 | struct hwtstamp_config cfg; | ||
2617 | |||
2618 | if (!cpts) | ||
2619 | return -EOPNOTSUPP; | ||
2620 | |||
2621 | if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) | ||
2622 | return -EFAULT; | ||
2623 | |||
2624 | /* reserved for future extensions */ | ||
2625 | if (cfg.flags) | ||
2626 | return -EINVAL; | ||
2627 | |||
2628 | switch (cfg.tx_type) { | ||
2629 | case HWTSTAMP_TX_OFF: | ||
2630 | cpts_tx_enable(cpts, 0); | ||
2631 | break; | ||
2632 | case HWTSTAMP_TX_ON: | ||
2633 | cpts_tx_enable(cpts, 1); | ||
2634 | break; | ||
2635 | default: | ||
2636 | return -ERANGE; | ||
2637 | } | ||
2638 | |||
2639 | switch (cfg.rx_filter) { | ||
2640 | case HWTSTAMP_FILTER_NONE: | ||
2641 | cpts_rx_enable(cpts, 0); | ||
2642 | break; | ||
2643 | case HWTSTAMP_FILTER_ALL: | ||
2644 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
2645 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
2646 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
2647 | cpts_rx_enable(cpts, HWTSTAMP_FILTER_PTP_V1_L4_EVENT); | ||
2648 | cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; | ||
2649 | break; | ||
2650 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
2651 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
2652 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
2653 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | ||
2654 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
2655 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
2656 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | ||
2657 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | ||
2658 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
2659 | cpts_rx_enable(cpts, HWTSTAMP_FILTER_PTP_V2_EVENT); | ||
2660 | cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | ||
2661 | break; | ||
2662 | default: | ||
2663 | return -ERANGE; | ||
2664 | } | ||
2665 | |||
2666 | gbe_hwtstamp(gbe_intf); | ||
2667 | |||
2668 | return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; | ||
2669 | } | ||
2670 | |||
2671 | static void gbe_register_cpts(struct gbe_priv *gbe_dev) | ||
2672 | { | ||
2673 | if (!gbe_dev->cpts) | ||
2674 | return; | ||
2675 | |||
2676 | if (gbe_dev->cpts_registered > 0) | ||
2677 | goto done; | ||
2678 | |||
2679 | if (cpts_register(gbe_dev->cpts)) { | ||
2680 | dev_err(gbe_dev->dev, "error registering cpts device\n"); | ||
2681 | return; | ||
2682 | } | ||
2683 | |||
2684 | done: | ||
2685 | ++gbe_dev->cpts_registered; | ||
2686 | } | ||
2687 | |||
2688 | static void gbe_unregister_cpts(struct gbe_priv *gbe_dev) | ||
2689 | { | ||
2690 | if (!gbe_dev->cpts || (gbe_dev->cpts_registered <= 0)) | ||
2691 | return; | ||
2692 | |||
2693 | if (--gbe_dev->cpts_registered) | ||
2694 | return; | ||
2695 | |||
2696 | cpts_unregister(gbe_dev->cpts); | ||
2697 | } | ||
2698 | #else | ||
2699 | static inline int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf, | ||
2700 | struct netcp_packet *p_info) | ||
2701 | { | ||
2702 | return 0; | ||
2703 | } | ||
2704 | |||
2705 | static inline int gbe_rxtstamp(struct gbe_intf *gbe_intf, | ||
2706 | struct netcp_packet *p_info) | ||
2707 | { | ||
2708 | return 0; | ||
2709 | } | ||
2710 | |||
2711 | static inline int gbe_hwtstamp(struct gbe_intf *gbe_intf, | ||
2712 | struct ifreq *ifr, int cmd) | ||
2713 | { | ||
2714 | return -EOPNOTSUPP; | ||
2715 | } | ||
2716 | |||
2717 | static inline void gbe_register_cpts(struct gbe_priv *gbe_dev) | ||
2718 | { | ||
2719 | } | ||
2720 | |||
2721 | static inline void gbe_unregister_cpts(struct gbe_priv *gbe_dev) | ||
2722 | { | ||
2723 | } | ||
2724 | |||
2725 | static inline int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *req) | ||
2726 | { | ||
2727 | return -EOPNOTSUPP; | ||
2728 | } | ||
2729 | |||
2730 | static inline int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *req) | ||
2731 | { | ||
2732 | return -EOPNOTSUPP; | ||
2733 | } | ||
2734 | #endif /* CONFIG_TI_CPTS */ | ||
2735 | |||
2368 | static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd) | 2736 | static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd) |
2369 | { | 2737 | { |
2370 | struct gbe_intf *gbe_intf = intf_priv; | 2738 | struct gbe_intf *gbe_intf = intf_priv; |
2371 | struct phy_device *phy = gbe_intf->slave->phy; | 2739 | struct phy_device *phy = gbe_intf->slave->phy; |
2372 | int ret = -EOPNOTSUPP; | 2740 | |
2741 | if (!phy || !phy->drv->hwtstamp) { | ||
2742 | switch (cmd) { | ||
2743 | case SIOCGHWTSTAMP: | ||
2744 | return gbe_hwtstamp_get(gbe_intf, req); | ||
2745 | case SIOCSHWTSTAMP: | ||
2746 | return gbe_hwtstamp_set(gbe_intf, req); | ||
2747 | } | ||
2748 | } | ||
2373 | 2749 | ||
2374 | if (phy) | 2750 | if (phy) |
2375 | ret = phy_mii_ioctl(phy, req, cmd); | 2751 | return phy_mii_ioctl(phy, req, cmd); |
2376 | 2752 | ||
2377 | return ret; | 2753 | return -EOPNOTSUPP; |
2378 | } | 2754 | } |
2379 | 2755 | ||
2380 | static void netcp_ethss_timer(unsigned long arg) | 2756 | static void netcp_ethss_timer(unsigned long arg) |
@@ -2410,12 +2786,20 @@ static void netcp_ethss_timer(unsigned long arg) | |||
2410 | add_timer(&gbe_dev->timer); | 2786 | add_timer(&gbe_dev->timer); |
2411 | } | 2787 | } |
2412 | 2788 | ||
2413 | static int gbe_tx_hook(int order, void *data, struct netcp_packet *p_info) | 2789 | static int gbe_txhook(int order, void *data, struct netcp_packet *p_info) |
2414 | { | 2790 | { |
2415 | struct gbe_intf *gbe_intf = data; | 2791 | struct gbe_intf *gbe_intf = data; |
2416 | 2792 | ||
2417 | p_info->tx_pipe = &gbe_intf->tx_pipe; | 2793 | p_info->tx_pipe = &gbe_intf->tx_pipe; |
2418 | return 0; | 2794 | |
2795 | return gbe_txtstamp_mark_pkt(gbe_intf, p_info); | ||
2796 | } | ||
2797 | |||
2798 | static int gbe_rxhook(int order, void *data, struct netcp_packet *p_info) | ||
2799 | { | ||
2800 | struct gbe_intf *gbe_intf = data; | ||
2801 | |||
2802 | return gbe_rxtstamp(gbe_intf, p_info); | ||
2419 | } | 2803 | } |
2420 | 2804 | ||
2421 | static int gbe_open(void *intf_priv, struct net_device *ndev) | 2805 | static int gbe_open(void *intf_priv, struct net_device *ndev) |
@@ -2465,11 +2849,14 @@ static int gbe_open(void *intf_priv, struct net_device *ndev) | |||
2465 | if (ret) | 2849 | if (ret) |
2466 | goto fail; | 2850 | goto fail; |
2467 | 2851 | ||
2468 | netcp_register_txhook(netcp, GBE_TXHOOK_ORDER, gbe_tx_hook, | 2852 | netcp_register_txhook(netcp, GBE_TXHOOK_ORDER, gbe_txhook, gbe_intf); |
2469 | gbe_intf); | 2853 | netcp_register_rxhook(netcp, GBE_RXHOOK_ORDER, gbe_rxhook, gbe_intf); |
2470 | 2854 | ||
2471 | slave->open = true; | 2855 | slave->open = true; |
2472 | netcp_ethss_update_link_state(gbe_dev, slave, ndev); | 2856 | netcp_ethss_update_link_state(gbe_dev, slave, ndev); |
2857 | |||
2858 | gbe_register_cpts(gbe_dev); | ||
2859 | |||
2473 | return 0; | 2860 | return 0; |
2474 | 2861 | ||
2475 | fail: | 2862 | fail: |
@@ -2481,16 +2868,36 @@ static int gbe_close(void *intf_priv, struct net_device *ndev) | |||
2481 | { | 2868 | { |
2482 | struct gbe_intf *gbe_intf = intf_priv; | 2869 | struct gbe_intf *gbe_intf = intf_priv; |
2483 | struct netcp_intf *netcp = netdev_priv(ndev); | 2870 | struct netcp_intf *netcp = netdev_priv(ndev); |
2871 | struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; | ||
2872 | |||
2873 | gbe_unregister_cpts(gbe_dev); | ||
2484 | 2874 | ||
2485 | gbe_slave_stop(gbe_intf); | 2875 | gbe_slave_stop(gbe_intf); |
2486 | netcp_unregister_txhook(netcp, GBE_TXHOOK_ORDER, gbe_tx_hook, | 2876 | |
2487 | gbe_intf); | 2877 | netcp_unregister_rxhook(netcp, GBE_RXHOOK_ORDER, gbe_rxhook, gbe_intf); |
2878 | netcp_unregister_txhook(netcp, GBE_TXHOOK_ORDER, gbe_txhook, gbe_intf); | ||
2488 | 2879 | ||
2489 | gbe_intf->slave->open = false; | 2880 | gbe_intf->slave->open = false; |
2490 | atomic_set(&gbe_intf->slave->link_state, NETCP_LINK_STATE_INVALID); | 2881 | atomic_set(&gbe_intf->slave->link_state, NETCP_LINK_STATE_INVALID); |
2491 | return 0; | 2882 | return 0; |
2492 | } | 2883 | } |
2493 | 2884 | ||
2885 | #if IS_ENABLED(CONFIG_TI_CPTS) | ||
2886 | static void init_slave_ts_ctl(struct gbe_slave *slave) | ||
2887 | { | ||
2888 | slave->ts_ctl.uni = 1; | ||
2889 | slave->ts_ctl.dst_port_map = | ||
2890 | (TS_CTL_DST_PORT >> TS_CTL_DST_PORT_SHIFT) & 0x3; | ||
2891 | slave->ts_ctl.maddr_map = | ||
2892 | (TS_CTL_MADDR_ALL >> TS_CTL_MADDR_SHIFT) & 0x1f; | ||
2893 | } | ||
2894 | |||
2895 | #else | ||
2896 | static void init_slave_ts_ctl(struct gbe_slave *slave) | ||
2897 | { | ||
2898 | } | ||
2899 | #endif /* CONFIG_TI_CPTS */ | ||
2900 | |||
2494 | static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave, | 2901 | static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave, |
2495 | struct device_node *node) | 2902 | struct device_node *node) |
2496 | { | 2903 | { |
@@ -2605,6 +3012,8 @@ static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave, | |||
2605 | } | 3012 | } |
2606 | 3013 | ||
2607 | atomic_set(&slave->link_state, NETCP_LINK_STATE_INVALID); | 3014 | atomic_set(&slave->link_state, NETCP_LINK_STATE_INVALID); |
3015 | |||
3016 | init_slave_ts_ctl(slave); | ||
2608 | return 0; | 3017 | return 0; |
2609 | } | 3018 | } |
2610 | 3019 | ||
@@ -2795,6 +3204,7 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev, | |||
2795 | XGBE10_HW_STATS_OFFSET + (GBE_HW_STATS_REG_MAP_SZ * i); | 3204 | XGBE10_HW_STATS_OFFSET + (GBE_HW_STATS_REG_MAP_SZ * i); |
2796 | 3205 | ||
2797 | gbe_dev->ale_reg = gbe_dev->switch_regs + XGBE10_ALE_OFFSET; | 3206 | gbe_dev->ale_reg = gbe_dev->switch_regs + XGBE10_ALE_OFFSET; |
3207 | gbe_dev->cpts_reg = gbe_dev->switch_regs + XGBE10_CPTS_OFFSET; | ||
2798 | gbe_dev->ale_ports = gbe_dev->max_num_ports; | 3208 | gbe_dev->ale_ports = gbe_dev->max_num_ports; |
2799 | gbe_dev->host_port = XGBE10_HOST_PORT_NUM; | 3209 | gbe_dev->host_port = XGBE10_HOST_PORT_NUM; |
2800 | gbe_dev->ale_entries = XGBE10_NUM_ALE_ENTRIES; | 3210 | gbe_dev->ale_entries = XGBE10_NUM_ALE_ENTRIES; |
@@ -2917,6 +3327,7 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev, | |||
2917 | (GBE_HW_STATS_REG_MAP_SZ * (i & 0x1)); | 3327 | (GBE_HW_STATS_REG_MAP_SZ * (i & 0x1)); |
2918 | } | 3328 | } |
2919 | 3329 | ||
3330 | gbe_dev->cpts_reg = gbe_dev->switch_regs + GBE13_CPTS_OFFSET; | ||
2920 | gbe_dev->ale_reg = gbe_dev->switch_regs + GBE13_ALE_OFFSET; | 3331 | gbe_dev->ale_reg = gbe_dev->switch_regs + GBE13_ALE_OFFSET; |
2921 | gbe_dev->ale_ports = gbe_dev->max_num_ports; | 3332 | gbe_dev->ale_ports = gbe_dev->max_num_ports; |
2922 | gbe_dev->host_port = GBE13_HOST_PORT_NUM; | 3333 | gbe_dev->host_port = GBE13_HOST_PORT_NUM; |
@@ -3006,6 +3417,7 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev, | |||
3006 | gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + | 3417 | gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + |
3007 | GBENU_HW_STATS_OFFSET + (GBENU_HW_STATS_REG_MAP_SZ * i); | 3418 | GBENU_HW_STATS_OFFSET + (GBENU_HW_STATS_REG_MAP_SZ * i); |
3008 | 3419 | ||
3420 | gbe_dev->cpts_reg = gbe_dev->switch_regs + GBENU_CPTS_OFFSET; | ||
3009 | gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET; | 3421 | gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET; |
3010 | gbe_dev->ale_ports = gbe_dev->max_num_ports; | 3422 | gbe_dev->ale_ports = gbe_dev->max_num_ports; |
3011 | gbe_dev->host_port = GBENU_HOST_PORT_NUM; | 3423 | gbe_dev->host_port = GBENU_HOST_PORT_NUM; |
@@ -3187,6 +3599,12 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev, | |||
3187 | dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n"); | 3599 | dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n"); |
3188 | } | 3600 | } |
3189 | 3601 | ||
3602 | gbe_dev->cpts = cpts_create(gbe_dev->dev, gbe_dev->cpts_reg, node); | ||
3603 | if (IS_ENABLED(CONFIG_TI_CPTS) && IS_ERR(gbe_dev->cpts)) { | ||
3604 | ret = PTR_ERR(gbe_dev->cpts); | ||
3605 | goto free_sec_ports; | ||
3606 | } | ||
3607 | |||
3190 | /* initialize host port */ | 3608 | /* initialize host port */ |
3191 | gbe_init_host_port(gbe_dev); | 3609 | gbe_init_host_port(gbe_dev); |
3192 | 3610 | ||
@@ -3275,6 +3693,7 @@ static int gbe_remove(struct netcp_device *netcp_device, void *inst_priv) | |||
3275 | struct gbe_priv *gbe_dev = inst_priv; | 3693 | struct gbe_priv *gbe_dev = inst_priv; |
3276 | 3694 | ||
3277 | del_timer_sync(&gbe_dev->timer); | 3695 | del_timer_sync(&gbe_dev->timer); |
3696 | cpts_release(gbe_dev->cpts); | ||
3278 | cpsw_ale_stop(gbe_dev->ale); | 3697 | cpsw_ale_stop(gbe_dev->ale); |
3279 | cpsw_ale_destroy(gbe_dev->ale); | 3698 | cpsw_ale_destroy(gbe_dev->ale); |
3280 | netcp_txpipe_close(&gbe_dev->tx_pipe); | 3699 | netcp_txpipe_close(&gbe_dev->tx_pipe); |