Skip to content

Commit

Permalink
net: mscc: ocelot: convert to use ocelot_get_txtstamp()
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Reviewed-by: Florian Fainelli <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
yangbolu1991 authored and davem330 committed Nov 21, 2019
1 parent f145922 commit e23a7b3
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 61 deletions.
62 changes: 60 additions & 2 deletions drivers/net/ethernet/mscc/ocelot.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,8 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
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;
u32 val;
Expand All @@ -686,7 +687,64 @@ void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts)

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)
{
Expand Down
6 changes: 0 additions & 6 deletions drivers/net/ethernet/mscc/ocelot.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,6 @@ struct ocelot_port_private {
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);
void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg);

Expand Down
53 changes: 1 addition & 52 deletions drivers/net/ethernet/mscc/ocelot_board.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
int budget = OCELOT_PTP_QUEUE_SZ;
struct ocelot *ocelot = arg;

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);
}
ocelot_get_txtstamp(ocelot);

return IRQ_HANDLED;
}
Expand Down
9 changes: 8 additions & 1 deletion include/soc/mscc/ocelot.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,13 @@ struct ocelot_ops {
int (*reset)(struct ocelot *ocelot);
};

struct ocelot_skb {
struct list_head head;
struct sk_buff *skb;
u8 id;
};


struct ocelot_port {
struct ocelot *ocelot;

Expand Down Expand Up @@ -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_set(struct ocelot *ocelot, int port, struct ifreq *ifr);
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

0 comments on commit e23a7b3

Please sign in to comment.