Commit 4fd3e2ac authored by David S. Miller's avatar David S. Miller

Merge branch 'cpsw-allow-vlan-h-w-timestamping'

Ivan Khoronzhuk says:

====================
net: ethernet: ti: cpsw: allow vlan h/w timestamping

The patchset adds several improvements and allows vlan h/w ts.

Based on net-next/master
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3e536cff 1ebb2446
...@@ -283,7 +283,7 @@ struct cpsw_ss_regs { ...@@ -283,7 +283,7 @@ struct cpsw_ss_regs {
#define CTRL_V2_TS_BITS \ #define CTRL_V2_TS_BITS \
(TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\ (TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\
TS_TTL_NONZERO | TS_ANNEX_D_EN | TS_LTYPE1_EN) TS_TTL_NONZERO | TS_ANNEX_D_EN | TS_LTYPE1_EN | VLAN_LTYPE1_EN)
#define CTRL_V2_ALL_TS_MASK (CTRL_V2_TS_BITS | TS_TX_EN | TS_RX_EN) #define CTRL_V2_ALL_TS_MASK (CTRL_V2_TS_BITS | TS_TX_EN | TS_RX_EN)
#define CTRL_V2_TX_TS_BITS (CTRL_V2_TS_BITS | TS_TX_EN) #define CTRL_V2_TX_TS_BITS (CTRL_V2_TS_BITS | TS_TX_EN)
...@@ -293,7 +293,7 @@ struct cpsw_ss_regs { ...@@ -293,7 +293,7 @@ struct cpsw_ss_regs {
#define CTRL_V3_TS_BITS \ #define CTRL_V3_TS_BITS \
(TS_107 | TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\ (TS_107 | TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\
TS_TTL_NONZERO | TS_ANNEX_F_EN | TS_ANNEX_D_EN |\ TS_TTL_NONZERO | TS_ANNEX_F_EN | TS_ANNEX_D_EN |\
TS_LTYPE1_EN) TS_LTYPE1_EN | VLAN_LTYPE1_EN)
#define CTRL_V3_ALL_TS_MASK (CTRL_V3_TS_BITS | TS_TX_EN | TS_RX_EN) #define CTRL_V3_ALL_TS_MASK (CTRL_V3_TS_BITS | TS_TX_EN | TS_RX_EN)
#define CTRL_V3_TX_TS_BITS (CTRL_V3_TS_BITS | TS_TX_EN) #define CTRL_V3_TX_TS_BITS (CTRL_V3_TS_BITS | TS_TX_EN)
...@@ -466,6 +466,8 @@ struct cpsw_priv { ...@@ -466,6 +466,8 @@ struct cpsw_priv {
bool mqprio_hw; bool mqprio_hw;
int fifo_bw[CPSW_TC_NUM]; int fifo_bw[CPSW_TC_NUM];
int shp_cfg_speed; int shp_cfg_speed;
int tx_ts_enabled;
int rx_ts_enabled;
u32 emac_port; u32 emac_port;
struct cpsw_common *cpsw; struct cpsw_common *cpsw;
}; };
...@@ -905,6 +907,7 @@ static void cpsw_rx_handler(void *token, int len, int status) ...@@ -905,6 +907,7 @@ static void cpsw_rx_handler(void *token, int len, int status)
struct net_device *ndev = skb->dev; struct net_device *ndev = skb->dev;
int ret = 0, port; int ret = 0, port;
struct cpsw_common *cpsw = ndev_to_cpsw(ndev); struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
struct cpsw_priv *priv;
if (cpsw->data.dual_emac) { if (cpsw->data.dual_emac) {
port = CPDMA_RX_SOURCE_PORT(status); port = CPDMA_RX_SOURCE_PORT(status);
...@@ -939,7 +942,9 @@ static void cpsw_rx_handler(void *token, int len, int status) ...@@ -939,7 +942,9 @@ static void cpsw_rx_handler(void *token, int len, int status)
skb_put(skb, len); skb_put(skb, len);
if (status & CPDMA_RX_VLAN_ENCAP) if (status & CPDMA_RX_VLAN_ENCAP)
cpsw_rx_vlan_encap(skb); cpsw_rx_vlan_encap(skb);
cpts_rx_timestamp(cpsw->cpts, skb); priv = netdev_priv(ndev);
if (priv->rx_ts_enabled)
cpts_rx_timestamp(cpsw->cpts, skb);
skb->protocol = eth_type_trans(skb, ndev); skb->protocol = eth_type_trans(skb, ndev);
netif_receive_skb(skb); netif_receive_skb(skb);
ndev->stats.rx_bytes += len; ndev->stats.rx_bytes += len;
...@@ -2126,7 +2131,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, ...@@ -2126,7 +2131,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
} }
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
cpts_is_tx_enabled(cpts) && cpts_can_timestamp(cpts, skb)) priv->tx_ts_enabled && cpts_can_timestamp(cpts, skb))
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
q_idx = skb_get_queue_mapping(skb); q_idx = skb_get_queue_mapping(skb);
...@@ -2170,13 +2175,13 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, ...@@ -2170,13 +2175,13 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
#if IS_ENABLED(CONFIG_TI_CPTS) #if IS_ENABLED(CONFIG_TI_CPTS)
static void cpsw_hwtstamp_v1(struct cpsw_common *cpsw) static void cpsw_hwtstamp_v1(struct cpsw_priv *priv)
{ {
struct cpsw_common *cpsw = priv->cpsw;
struct cpsw_slave *slave = &cpsw->slaves[cpsw->data.active_slave]; struct cpsw_slave *slave = &cpsw->slaves[cpsw->data.active_slave];
u32 ts_en, seq_id; u32 ts_en, seq_id;
if (!cpts_is_tx_enabled(cpsw->cpts) && if (!priv->tx_ts_enabled && !priv->rx_ts_enabled) {
!cpts_is_rx_enabled(cpsw->cpts)) {
slave_write(slave, 0, CPSW1_TS_CTL); slave_write(slave, 0, CPSW1_TS_CTL);
return; return;
} }
...@@ -2184,10 +2189,10 @@ static void cpsw_hwtstamp_v1(struct cpsw_common *cpsw) ...@@ -2184,10 +2189,10 @@ static void cpsw_hwtstamp_v1(struct cpsw_common *cpsw)
seq_id = (30 << CPSW_V1_SEQ_ID_OFS_SHIFT) | ETH_P_1588; seq_id = (30 << CPSW_V1_SEQ_ID_OFS_SHIFT) | ETH_P_1588;
ts_en = EVENT_MSG_BITS << CPSW_V1_MSG_TYPE_OFS; ts_en = EVENT_MSG_BITS << CPSW_V1_MSG_TYPE_OFS;
if (cpts_is_tx_enabled(cpsw->cpts)) if (priv->tx_ts_enabled)
ts_en |= CPSW_V1_TS_TX_EN; ts_en |= CPSW_V1_TS_TX_EN;
if (cpts_is_rx_enabled(cpsw->cpts)) if (priv->rx_ts_enabled)
ts_en |= CPSW_V1_TS_RX_EN; ts_en |= CPSW_V1_TS_RX_EN;
slave_write(slave, ts_en, CPSW1_TS_CTL); slave_write(slave, ts_en, CPSW1_TS_CTL);
...@@ -2207,20 +2212,20 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) ...@@ -2207,20 +2212,20 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv)
case CPSW_VERSION_2: case CPSW_VERSION_2:
ctrl &= ~CTRL_V2_ALL_TS_MASK; ctrl &= ~CTRL_V2_ALL_TS_MASK;
if (cpts_is_tx_enabled(cpsw->cpts)) if (priv->tx_ts_enabled)
ctrl |= CTRL_V2_TX_TS_BITS; ctrl |= CTRL_V2_TX_TS_BITS;
if (cpts_is_rx_enabled(cpsw->cpts)) if (priv->rx_ts_enabled)
ctrl |= CTRL_V2_RX_TS_BITS; ctrl |= CTRL_V2_RX_TS_BITS;
break; break;
case CPSW_VERSION_3: case CPSW_VERSION_3:
default: default:
ctrl &= ~CTRL_V3_ALL_TS_MASK; ctrl &= ~CTRL_V3_ALL_TS_MASK;
if (cpts_is_tx_enabled(cpsw->cpts)) if (priv->tx_ts_enabled)
ctrl |= CTRL_V3_TX_TS_BITS; ctrl |= CTRL_V3_TX_TS_BITS;
if (cpts_is_rx_enabled(cpsw->cpts)) if (priv->rx_ts_enabled)
ctrl |= CTRL_V3_RX_TS_BITS; ctrl |= CTRL_V3_RX_TS_BITS;
break; break;
} }
...@@ -2230,6 +2235,7 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) ...@@ -2230,6 +2235,7 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv)
slave_write(slave, mtype, CPSW2_TS_SEQ_MTYPE); slave_write(slave, mtype, CPSW2_TS_SEQ_MTYPE);
slave_write(slave, ctrl, CPSW2_CONTROL); slave_write(slave, ctrl, CPSW2_CONTROL);
writel_relaxed(ETH_P_1588, &cpsw->regs->ts_ltype); writel_relaxed(ETH_P_1588, &cpsw->regs->ts_ltype);
writel_relaxed(ETH_P_8021Q, &cpsw->regs->vlan_ltype);
} }
static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
...@@ -2237,7 +2243,6 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) ...@@ -2237,7 +2243,6 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
struct cpsw_priv *priv = netdev_priv(dev); struct cpsw_priv *priv = netdev_priv(dev);
struct hwtstamp_config cfg; struct hwtstamp_config cfg;
struct cpsw_common *cpsw = priv->cpsw; struct cpsw_common *cpsw = priv->cpsw;
struct cpts *cpts = cpsw->cpts;
if (cpsw->version != CPSW_VERSION_1 && if (cpsw->version != CPSW_VERSION_1 &&
cpsw->version != CPSW_VERSION_2 && cpsw->version != CPSW_VERSION_2 &&
...@@ -2256,7 +2261,7 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) ...@@ -2256,7 +2261,7 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
switch (cfg.rx_filter) { switch (cfg.rx_filter) {
case HWTSTAMP_FILTER_NONE: case HWTSTAMP_FILTER_NONE:
cpts_rx_enable(cpts, 0); priv->rx_ts_enabled = 0;
break; break;
case HWTSTAMP_FILTER_ALL: case HWTSTAMP_FILTER_ALL:
case HWTSTAMP_FILTER_NTP_ALL: case HWTSTAMP_FILTER_NTP_ALL:
...@@ -2264,7 +2269,7 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) ...@@ -2264,7 +2269,7 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
cpts_rx_enable(cpts, HWTSTAMP_FILTER_PTP_V1_L4_EVENT); priv->rx_ts_enabled = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
break; break;
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
...@@ -2276,18 +2281,18 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) ...@@ -2276,18 +2281,18 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
case HWTSTAMP_FILTER_PTP_V2_EVENT: case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
cpts_rx_enable(cpts, HWTSTAMP_FILTER_PTP_V2_EVENT); priv->rx_ts_enabled = HWTSTAMP_FILTER_PTP_V2_EVENT;
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
break; break;
default: default:
return -ERANGE; return -ERANGE;
} }
cpts_tx_enable(cpts, cfg.tx_type == HWTSTAMP_TX_ON); priv->tx_ts_enabled = cfg.tx_type == HWTSTAMP_TX_ON;
switch (cpsw->version) { switch (cpsw->version) {
case CPSW_VERSION_1: case CPSW_VERSION_1:
cpsw_hwtstamp_v1(cpsw); cpsw_hwtstamp_v1(priv);
break; break;
case CPSW_VERSION_2: case CPSW_VERSION_2:
case CPSW_VERSION_3: case CPSW_VERSION_3:
...@@ -2303,7 +2308,7 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) ...@@ -2303,7 +2308,7 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
{ {
struct cpsw_common *cpsw = ndev_to_cpsw(dev); struct cpsw_common *cpsw = ndev_to_cpsw(dev);
struct cpts *cpts = cpsw->cpts; struct cpsw_priv *priv = netdev_priv(dev);
struct hwtstamp_config cfg; struct hwtstamp_config cfg;
if (cpsw->version != CPSW_VERSION_1 && if (cpsw->version != CPSW_VERSION_1 &&
...@@ -2312,10 +2317,8 @@ static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) ...@@ -2312,10 +2317,8 @@ static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
return -EOPNOTSUPP; return -EOPNOTSUPP;
cfg.flags = 0; cfg.flags = 0;
cfg.tx_type = cpts_is_tx_enabled(cpts) ? cfg.tx_type = priv->tx_ts_enabled ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; cfg.rx_filter = priv->rx_ts_enabled;
cfg.rx_filter = (cpts_is_rx_enabled(cpts) ?
cpts->rx_enable : HWTSTAMP_FILTER_NONE);
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
} }
......
...@@ -86,6 +86,25 @@ static int cpts_purge_events(struct cpts *cpts) ...@@ -86,6 +86,25 @@ static int cpts_purge_events(struct cpts *cpts)
return removed ? 0 : -1; return removed ? 0 : -1;
} }
static void cpts_purge_txq(struct cpts *cpts)
{
struct cpts_skb_cb_data *skb_cb;
struct sk_buff *skb, *tmp;
int removed = 0;
skb_queue_walk_safe(&cpts->txq, skb, tmp) {
skb_cb = (struct cpts_skb_cb_data *)skb->cb;
if (time_after(jiffies, skb_cb->tmo)) {
__skb_unlink(skb, &cpts->txq);
dev_consume_skb_any(skb);
++removed;
}
}
if (removed)
dev_dbg(cpts->dev, "txq cleaned up %d\n", removed);
}
static bool cpts_match_tx_ts(struct cpts *cpts, struct cpts_event *event) static bool cpts_match_tx_ts(struct cpts *cpts, struct cpts_event *event)
{ {
struct sk_buff *skb, *tmp; struct sk_buff *skb, *tmp;
...@@ -119,9 +138,7 @@ static bool cpts_match_tx_ts(struct cpts *cpts, struct cpts_event *event) ...@@ -119,9 +138,7 @@ static bool cpts_match_tx_ts(struct cpts *cpts, struct cpts_event *event)
if (time_after(jiffies, skb_cb->tmo)) { if (time_after(jiffies, skb_cb->tmo)) {
/* timeout any expired skbs over 1s */ /* timeout any expired skbs over 1s */
dev_dbg(cpts->dev, dev_dbg(cpts->dev, "expiring tx timestamp from txq\n");
"expiring tx timestamp mtype %u seqid %04x\n",
mtype, seqid);
__skb_unlink(skb, &cpts->txq); __skb_unlink(skb, &cpts->txq);
dev_consume_skb_any(skb); dev_consume_skb_any(skb);
} }
...@@ -294,8 +311,11 @@ static long cpts_overflow_check(struct ptp_clock_info *ptp) ...@@ -294,8 +311,11 @@ static long cpts_overflow_check(struct ptp_clock_info *ptp)
spin_lock_irqsave(&cpts->lock, flags); spin_lock_irqsave(&cpts->lock, flags);
ts = ns_to_timespec64(timecounter_read(&cpts->tc)); ts = ns_to_timespec64(timecounter_read(&cpts->tc));
if (!skb_queue_empty(&cpts->txq)) if (!skb_queue_empty(&cpts->txq)) {
delay = CPTS_SKB_TX_WORK_TIMEOUT; cpts_purge_txq(cpts);
if (!skb_queue_empty(&cpts->txq))
delay = CPTS_SKB_TX_WORK_TIMEOUT;
}
spin_unlock_irqrestore(&cpts->lock, flags); spin_unlock_irqrestore(&cpts->lock, flags);
pr_debug("cpts overflow check at %lld.%09ld\n", pr_debug("cpts overflow check at %lld.%09ld\n",
...@@ -410,8 +430,6 @@ void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb) ...@@ -410,8 +430,6 @@ void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
u64 ns; u64 ns;
struct skb_shared_hwtstamps *ssh; struct skb_shared_hwtstamps *ssh;
if (!cpts->rx_enable)
return;
ns = cpts_find_ts(cpts, skb, CPTS_EV_RX); ns = cpts_find_ts(cpts, skb, CPTS_EV_RX);
if (!ns) if (!ns)
return; return;
......
...@@ -136,26 +136,6 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs, ...@@ -136,26 +136,6 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
struct device_node *node); struct device_node *node);
void cpts_release(struct cpts *cpts); void cpts_release(struct cpts *cpts);
static inline void cpts_rx_enable(struct cpts *cpts, int enable)
{
cpts->rx_enable = enable;
}
static inline bool cpts_is_rx_enabled(struct cpts *cpts)
{
return !!cpts->rx_enable;
}
static inline void cpts_tx_enable(struct cpts *cpts, int enable)
{
cpts->tx_enable = enable;
}
static inline bool cpts_is_tx_enabled(struct cpts *cpts)
{
return !!cpts->tx_enable;
}
static inline bool cpts_can_timestamp(struct cpts *cpts, struct sk_buff *skb) static inline bool cpts_can_timestamp(struct cpts *cpts, struct sk_buff *skb)
{ {
unsigned int class = ptp_classify_raw(skb); unsigned int class = ptp_classify_raw(skb);
...@@ -197,24 +177,6 @@ static inline void cpts_unregister(struct cpts *cpts) ...@@ -197,24 +177,6 @@ static inline void cpts_unregister(struct cpts *cpts)
{ {
} }
static inline void cpts_rx_enable(struct cpts *cpts, int enable)
{
}
static inline bool cpts_is_rx_enabled(struct cpts *cpts)
{
return false;
}
static inline void cpts_tx_enable(struct cpts *cpts, int enable)
{
}
static inline bool cpts_is_tx_enabled(struct cpts *cpts)
{
return false;
}
static inline bool cpts_can_timestamp(struct cpts *cpts, struct sk_buff *skb) static inline bool cpts_can_timestamp(struct cpts *cpts, struct sk_buff *skb)
{ {
return false; return false;
......
...@@ -763,6 +763,8 @@ struct gbe_priv { ...@@ -763,6 +763,8 @@ struct gbe_priv {
int cpts_registered; int cpts_registered;
struct cpts *cpts; struct cpts *cpts;
int rx_ts_enabled;
int tx_ts_enabled;
}; };
struct gbe_intf { struct gbe_intf {
...@@ -2564,7 +2566,7 @@ static int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf, ...@@ -2564,7 +2566,7 @@ static int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf,
struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
if (!(skb_shinfo(p_info->skb)->tx_flags & SKBTX_HW_TSTAMP) || if (!(skb_shinfo(p_info->skb)->tx_flags & SKBTX_HW_TSTAMP) ||
!cpts_is_tx_enabled(gbe_dev->cpts)) !gbe_dev->tx_ts_enabled)
return 0; return 0;
/* If phy has the txtstamp api, assume it will do it. /* If phy has the txtstamp api, assume it will do it.
...@@ -2598,7 +2600,9 @@ static int gbe_rxtstamp(struct gbe_intf *gbe_intf, struct netcp_packet *p_info) ...@@ -2598,7 +2600,9 @@ static int gbe_rxtstamp(struct gbe_intf *gbe_intf, struct netcp_packet *p_info)
return 0; return 0;
} }
cpts_rx_timestamp(gbe_dev->cpts, p_info->skb); if (gbe_dev->rx_ts_enabled)
cpts_rx_timestamp(gbe_dev->cpts, p_info->skb);
p_info->rxtstamp_complete = true; p_info->rxtstamp_complete = true;
return 0; return 0;
...@@ -2614,10 +2618,8 @@ static int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *ifr) ...@@ -2614,10 +2618,8 @@ static int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *ifr)
return -EOPNOTSUPP; return -EOPNOTSUPP;
cfg.flags = 0; cfg.flags = 0;
cfg.tx_type = cpts_is_tx_enabled(cpts) ? cfg.tx_type = gbe_dev->tx_ts_enabled ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; cfg.rx_filter = gbe_dev->rx_ts_enabled;
cfg.rx_filter = (cpts_is_rx_enabled(cpts) ?
cpts->rx_enable : HWTSTAMP_FILTER_NONE);
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
} }
...@@ -2628,8 +2630,8 @@ static void gbe_hwtstamp(struct gbe_intf *gbe_intf) ...@@ -2628,8 +2630,8 @@ static void gbe_hwtstamp(struct gbe_intf *gbe_intf)
struct gbe_slave *slave = gbe_intf->slave; struct gbe_slave *slave = gbe_intf->slave;
u32 ts_en, seq_id, ctl; u32 ts_en, seq_id, ctl;
if (!cpts_is_rx_enabled(gbe_dev->cpts) && if (!gbe_dev->rx_ts_enabled &&
!cpts_is_tx_enabled(gbe_dev->cpts)) { !gbe_dev->tx_ts_enabled) {
writel(0, GBE_REG_ADDR(slave, port_regs, ts_ctl)); writel(0, GBE_REG_ADDR(slave, port_regs, ts_ctl));
return; return;
} }
...@@ -2641,10 +2643,10 @@ static void gbe_hwtstamp(struct gbe_intf *gbe_intf) ...@@ -2641,10 +2643,10 @@ static void gbe_hwtstamp(struct gbe_intf *gbe_intf)
(slave->ts_ctl.uni ? TS_UNI_EN : (slave->ts_ctl.uni ? TS_UNI_EN :
slave->ts_ctl.maddr_map << TS_CTL_MADDR_SHIFT); slave->ts_ctl.maddr_map << TS_CTL_MADDR_SHIFT);
if (cpts_is_tx_enabled(gbe_dev->cpts)) if (gbe_dev->tx_ts_enabled)
ts_en |= (TS_TX_ANX_ALL_EN | TS_TX_VLAN_LT1_EN); ts_en |= (TS_TX_ANX_ALL_EN | TS_TX_VLAN_LT1_EN);
if (cpts_is_rx_enabled(gbe_dev->cpts)) if (gbe_dev->rx_ts_enabled)
ts_en |= (TS_RX_ANX_ALL_EN | TS_RX_VLAN_LT1_EN); ts_en |= (TS_RX_ANX_ALL_EN | TS_RX_VLAN_LT1_EN);
writel(ts_en, GBE_REG_ADDR(slave, port_regs, ts_ctl)); writel(ts_en, GBE_REG_ADDR(slave, port_regs, ts_ctl));
...@@ -2670,10 +2672,10 @@ static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr) ...@@ -2670,10 +2672,10 @@ static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr)
switch (cfg.tx_type) { switch (cfg.tx_type) {
case HWTSTAMP_TX_OFF: case HWTSTAMP_TX_OFF:
cpts_tx_enable(cpts, 0); gbe_dev->tx_ts_enabled = 0;
break; break;
case HWTSTAMP_TX_ON: case HWTSTAMP_TX_ON:
cpts_tx_enable(cpts, 1); gbe_dev->tx_ts_enabled = 1;
break; break;
default: default:
return -ERANGE; return -ERANGE;
...@@ -2681,12 +2683,12 @@ static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr) ...@@ -2681,12 +2683,12 @@ static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr)
switch (cfg.rx_filter) { switch (cfg.rx_filter) {
case HWTSTAMP_FILTER_NONE: case HWTSTAMP_FILTER_NONE:
cpts_rx_enable(cpts, 0); gbe_dev->rx_ts_enabled = HWTSTAMP_FILTER_NONE;
break; break;
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
cpts_rx_enable(cpts, HWTSTAMP_FILTER_PTP_V1_L4_EVENT); gbe_dev->rx_ts_enabled = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
break; break;
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
...@@ -2698,7 +2700,7 @@ static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr) ...@@ -2698,7 +2700,7 @@ static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr)
case HWTSTAMP_FILTER_PTP_V2_EVENT: case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
cpts_rx_enable(cpts, HWTSTAMP_FILTER_PTP_V2_EVENT); gbe_dev->rx_ts_enabled = HWTSTAMP_FILTER_PTP_V2_EVENT;
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
break; break;
default: default:
......
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