Commit 6246168b authored by WingMan Kwok's avatar WingMan Kwok Committed by David S. Miller

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: default avatarWingMan Kwok <w-kwok2@ti.com>
Signed-off-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 529ed127
...@@ -75,12 +75,13 @@ config TI_CPSW ...@@ -75,12 +75,13 @@ config TI_CPSW
config TI_CPTS config TI_CPTS
tristate "TI Common Platform Time Sync (CPTS) Support" tristate "TI Common Platform Time Sync (CPTS) Support"
depends on TI_CPSW depends on TI_CPSW || TI_KEYSTONE_NETCP
select PTP_1588_CLOCK select PTP_1588_CLOCK
---help--- ---help---
This driver supports the Common Platform Time Sync unit of This driver supports the Common Platform Time Sync unit of
the CPSW Ethernet Switch. The unit can time stamp PTP UDP/IPv4 the CPSW Ethernet Switch and Keystone 2 1g/10g Switch Subsystem.
and Layer 2 packets, and the driver offers a PTP Hardware Clock. The unit can time stamp PTP UDP/IPv4 and Layer 2 packets, and the
driver offers a PTP Hardware Clock.
config TI_KEYSTONE_NETCP config TI_KEYSTONE_NETCP
tristate "TI Keystone NETCP Core Support" tristate "TI Keystone NETCP Core Support"
......
...@@ -121,7 +121,7 @@ struct netcp_packet { ...@@ -121,7 +121,7 @@ struct netcp_packet {
bool rxtstamp_complete; bool rxtstamp_complete;
void *ts_context; void *ts_context;
int (*txtstamp_complete)(void *ctx, struct netcp_packet *pkt); void (*txtstamp)(void *ctx, struct sk_buff *skb);
}; };
static inline u32 *netcp_push_psdata(struct netcp_packet *p_info, static inline u32 *netcp_push_psdata(struct netcp_packet *p_info,
......
...@@ -100,6 +100,11 @@ struct netcp_intf_modpriv { ...@@ -100,6 +100,11 @@ struct netcp_intf_modpriv {
void *module_priv; void *module_priv;
}; };
struct netcp_tx_cb {
void *ts_context;
void (*txtstamp)(void *context, struct sk_buff *skb);
};
static LIST_HEAD(netcp_devices); static LIST_HEAD(netcp_devices);
static LIST_HEAD(netcp_modules); static LIST_HEAD(netcp_modules);
static DEFINE_MUTEX(netcp_modules_lock); static DEFINE_MUTEX(netcp_modules_lock);
...@@ -544,6 +549,7 @@ int netcp_register_rxhook(struct netcp_intf *netcp_priv, int order, ...@@ -544,6 +549,7 @@ int netcp_register_rxhook(struct netcp_intf *netcp_priv, int order,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(netcp_register_rxhook);
int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order,
netcp_hook_rtn *hook_rtn, void *hook_data) netcp_hook_rtn *hook_rtn, void *hook_data)
...@@ -566,6 +572,7 @@ int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, ...@@ -566,6 +572,7 @@ int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order,
return -ENOENT; return -ENOENT;
} }
EXPORT_SYMBOL_GPL(netcp_unregister_rxhook);
static void netcp_frag_free(bool is_frag, void *ptr) static void netcp_frag_free(bool is_frag, void *ptr)
{ {
...@@ -730,6 +737,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) ...@@ -730,6 +737,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
/* Call each of the RX hooks */ /* Call each of the RX hooks */
p_info.skb = skb; p_info.skb = skb;
skb->dev = netcp->ndev;
p_info.rxtstamp_complete = false; p_info.rxtstamp_complete = false;
list_for_each_entry(rx_hook, &netcp->rxhook_list_head, list) { list_for_each_entry(rx_hook, &netcp->rxhook_list_head, list) {
int ret; int ret;
...@@ -987,6 +995,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, ...@@ -987,6 +995,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
unsigned int budget) unsigned int budget)
{ {
struct knav_dma_desc *desc; struct knav_dma_desc *desc;
struct netcp_tx_cb *tx_cb;
struct sk_buff *skb; struct sk_buff *skb;
unsigned int dma_sz; unsigned int dma_sz;
dma_addr_t dma; dma_addr_t dma;
...@@ -1014,6 +1023,10 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, ...@@ -1014,6 +1023,10 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
continue; continue;
} }
tx_cb = (struct netcp_tx_cb *)skb->cb;
if (tx_cb->txtstamp)
tx_cb->txtstamp(tx_cb->ts_context, skb);
if (netif_subqueue_stopped(netcp->ndev, skb) && if (netif_subqueue_stopped(netcp->ndev, skb) &&
netif_running(netcp->ndev) && netif_running(netcp->ndev) &&
(knav_pool_count(netcp->tx_pool) > (knav_pool_count(netcp->tx_pool) >
...@@ -1154,6 +1167,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, ...@@ -1154,6 +1167,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
struct netcp_tx_pipe *tx_pipe = NULL; struct netcp_tx_pipe *tx_pipe = NULL;
struct netcp_hook_list *tx_hook; struct netcp_hook_list *tx_hook;
struct netcp_packet p_info; struct netcp_packet p_info;
struct netcp_tx_cb *tx_cb;
unsigned int dma_sz; unsigned int dma_sz;
dma_addr_t dma; dma_addr_t dma;
u32 tmp = 0; u32 tmp = 0;
...@@ -1164,7 +1178,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, ...@@ -1164,7 +1178,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
p_info.tx_pipe = NULL; p_info.tx_pipe = NULL;
p_info.psdata_len = 0; p_info.psdata_len = 0;
p_info.ts_context = NULL; p_info.ts_context = NULL;
p_info.txtstamp_complete = NULL; p_info.txtstamp = NULL;
p_info.epib = desc->epib; p_info.epib = desc->epib;
p_info.psdata = (u32 __force *)desc->psdata; p_info.psdata = (u32 __force *)desc->psdata;
memset(p_info.epib, 0, KNAV_DMA_NUM_EPIB_WORDS * sizeof(__le32)); 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,6 +1203,10 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
goto out; goto out;
} }
tx_cb = (struct netcp_tx_cb *)skb->cb;
tx_cb->ts_context = p_info.ts_context;
tx_cb->txtstamp = p_info.txtstamp;
/* update descriptor */ /* update descriptor */
if (p_info.psdata_len) { if (p_info.psdata_len) {
/* psdata points to both native-endian and device-endian data */ /* psdata points to both native-endian and device-endian data */
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment