mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-15 03:06:41 +07:00
net: mscc: ocelot: convert to use ocelot_get_txtstamp()
The method getting TX timestamp by reading timestamp FIFO and matching skbs list is common for DSA Felix driver too. So move code out of ocelot_board.c, convert to use ocelot_get_txtstamp() function and export it. Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f145922ddc
commit
e23a7b3e8d
@ -661,7 +661,8 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts)
|
static void ocelot_get_hwtimestamp(struct ocelot *ocelot,
|
||||||
|
struct timespec64 *ts)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 val;
|
u32 val;
|
||||||
@ -686,7 +687,64 @@ void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts)
|
|||||||
|
|
||||||
spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
|
spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ocelot_get_hwtimestamp);
|
|
||||||
|
void ocelot_get_txtstamp(struct ocelot *ocelot)
|
||||||
|
{
|
||||||
|
int budget = OCELOT_PTP_QUEUE_SZ;
|
||||||
|
|
||||||
|
while (budget--) {
|
||||||
|
struct skb_shared_hwtstamps shhwtstamps;
|
||||||
|
struct list_head *pos, *tmp;
|
||||||
|
struct sk_buff *skb = NULL;
|
||||||
|
struct ocelot_skb *entry;
|
||||||
|
struct ocelot_port *port;
|
||||||
|
struct timespec64 ts;
|
||||||
|
u32 val, id, txport;
|
||||||
|
|
||||||
|
val = ocelot_read(ocelot, SYS_PTP_STATUS);
|
||||||
|
|
||||||
|
/* Check if a timestamp can be retrieved */
|
||||||
|
if (!(val & SYS_PTP_STATUS_PTP_MESS_VLD))
|
||||||
|
break;
|
||||||
|
|
||||||
|
WARN_ON(val & SYS_PTP_STATUS_PTP_OVFL);
|
||||||
|
|
||||||
|
/* Retrieve the ts ID and Tx port */
|
||||||
|
id = SYS_PTP_STATUS_PTP_MESS_ID_X(val);
|
||||||
|
txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);
|
||||||
|
|
||||||
|
/* Retrieve its associated skb */
|
||||||
|
port = ocelot->ports[txport];
|
||||||
|
|
||||||
|
list_for_each_safe(pos, tmp, &port->skbs) {
|
||||||
|
entry = list_entry(pos, struct ocelot_skb, head);
|
||||||
|
if (entry->id != id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
skb = entry->skb;
|
||||||
|
|
||||||
|
list_del(pos);
|
||||||
|
kfree(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next ts */
|
||||||
|
ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
|
||||||
|
|
||||||
|
if (unlikely(!skb))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Get the h/w timestamp */
|
||||||
|
ocelot_get_hwtimestamp(ocelot, &ts);
|
||||||
|
|
||||||
|
/* Set the timestamp into the skb */
|
||||||
|
memset(&shhwtstamps, 0, sizeof(shhwtstamps));
|
||||||
|
shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
|
||||||
|
skb_tstamp_tx(skb, &shhwtstamps);
|
||||||
|
|
||||||
|
dev_kfree_skb_any(skb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ocelot_get_txtstamp);
|
||||||
|
|
||||||
static int ocelot_mc_unsync(struct net_device *dev, const unsigned char *addr)
|
static int ocelot_mc_unsync(struct net_device *dev, const unsigned char *addr)
|
||||||
{
|
{
|
||||||
|
@ -74,12 +74,6 @@ struct ocelot_port_private {
|
|||||||
struct ocelot_port_tc tc;
|
struct ocelot_port_tc tc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ocelot_skb {
|
|
||||||
struct list_head head;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
u8 id;
|
|
||||||
};
|
|
||||||
|
|
||||||
u32 ocelot_port_readl(struct ocelot_port *port, u32 reg);
|
u32 ocelot_port_readl(struct ocelot_port *port, u32 reg);
|
||||||
void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg);
|
void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg);
|
||||||
|
|
||||||
|
@ -190,60 +190,9 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
|
|||||||
|
|
||||||
static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
|
static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
|
||||||
{
|
{
|
||||||
int budget = OCELOT_PTP_QUEUE_SZ;
|
|
||||||
struct ocelot *ocelot = arg;
|
struct ocelot *ocelot = arg;
|
||||||
|
|
||||||
while (budget--) {
|
ocelot_get_txtstamp(ocelot);
|
||||||
struct skb_shared_hwtstamps shhwtstamps;
|
|
||||||
struct list_head *pos, *tmp;
|
|
||||||
struct sk_buff *skb = NULL;
|
|
||||||
struct ocelot_skb *entry;
|
|
||||||
struct ocelot_port *port;
|
|
||||||
struct timespec64 ts;
|
|
||||||
u32 val, id, txport;
|
|
||||||
|
|
||||||
val = ocelot_read(ocelot, SYS_PTP_STATUS);
|
|
||||||
|
|
||||||
/* Check if a timestamp can be retrieved */
|
|
||||||
if (!(val & SYS_PTP_STATUS_PTP_MESS_VLD))
|
|
||||||
break;
|
|
||||||
|
|
||||||
WARN_ON(val & SYS_PTP_STATUS_PTP_OVFL);
|
|
||||||
|
|
||||||
/* Retrieve the ts ID and Tx port */
|
|
||||||
id = SYS_PTP_STATUS_PTP_MESS_ID_X(val);
|
|
||||||
txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);
|
|
||||||
|
|
||||||
/* Retrieve its associated skb */
|
|
||||||
port = ocelot->ports[txport];
|
|
||||||
|
|
||||||
list_for_each_safe(pos, tmp, &port->skbs) {
|
|
||||||
entry = list_entry(pos, struct ocelot_skb, head);
|
|
||||||
if (entry->id != id)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
skb = entry->skb;
|
|
||||||
|
|
||||||
list_del(pos);
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next ts */
|
|
||||||
ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
|
|
||||||
|
|
||||||
if (unlikely(!skb))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Get the h/w timestamp */
|
|
||||||
ocelot_get_hwtimestamp(ocelot, &ts);
|
|
||||||
|
|
||||||
/* Set the timestamp into the skb */
|
|
||||||
memset(&shhwtstamps, 0, sizeof(shhwtstamps));
|
|
||||||
shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
|
|
||||||
skb_tstamp_tx(skb, &shhwtstamps);
|
|
||||||
|
|
||||||
dev_kfree_skb_any(skb);
|
|
||||||
}
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
@ -406,6 +406,13 @@ struct ocelot_ops {
|
|||||||
int (*reset)(struct ocelot *ocelot);
|
int (*reset)(struct ocelot *ocelot);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ocelot_skb {
|
||||||
|
struct list_head head;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
u8 id;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ocelot_port {
|
struct ocelot_port {
|
||||||
struct ocelot *ocelot;
|
struct ocelot *ocelot;
|
||||||
|
|
||||||
@ -536,6 +543,6 @@ int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid);
|
|||||||
int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr);
|
int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr);
|
||||||
int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr);
|
int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr);
|
||||||
int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts);
|
int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts);
|
||||||
void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts);
|
void ocelot_get_txtstamp(struct ocelot *ocelot);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user