net: dsa: sja1105: Use PTP core's dedicated kernel thread for RX timestamping
And move the queue of skb's waiting for RX timestamps into the ptp_data structure, since it isn't needed if PTP is not compiled. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
544fed47af
commit
1e762bd278
@@ -367,22 +367,16 @@ static int sja1105_ptpclkval_write(struct sja1105_private *priv, u64 ticks,
|
|||||||
ptp_sts);
|
ptp_sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define rxtstamp_to_tagger(d) \
|
static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp)
|
||||||
container_of((d), struct sja1105_tagger_data, rxtstamp_work)
|
|
||||||
#define tagger_to_sja1105(d) \
|
|
||||||
container_of((d), struct sja1105_private, tagger_data)
|
|
||||||
|
|
||||||
static void sja1105_rxtstamp_work(struct work_struct *work)
|
|
||||||
{
|
{
|
||||||
struct sja1105_tagger_data *tagger_data = rxtstamp_to_tagger(work);
|
struct sja1105_ptp_data *ptp_data = ptp_caps_to_data(ptp);
|
||||||
struct sja1105_private *priv = tagger_to_sja1105(tagger_data);
|
struct sja1105_private *priv = ptp_data_to_sja1105(ptp_data);
|
||||||
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
|
|
||||||
struct dsa_switch *ds = priv->ds;
|
struct dsa_switch *ds = priv->ds;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
mutex_lock(&ptp_data->lock);
|
mutex_lock(&ptp_data->lock);
|
||||||
|
|
||||||
while ((skb = skb_dequeue(&tagger_data->skb_rxtstamp_queue)) != NULL) {
|
while ((skb = skb_dequeue(&ptp_data->skb_rxtstamp_queue)) != NULL) {
|
||||||
struct skb_shared_hwtstamps *shwt = skb_hwtstamps(skb);
|
struct skb_shared_hwtstamps *shwt = skb_hwtstamps(skb);
|
||||||
u64 ticks, ts;
|
u64 ticks, ts;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -404,6 +398,9 @@ static void sja1105_rxtstamp_work(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&ptp_data->lock);
|
mutex_unlock(&ptp_data->lock);
|
||||||
|
|
||||||
|
/* Don't restart */
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from dsa_skb_defer_rx_timestamp */
|
/* Called from dsa_skb_defer_rx_timestamp */
|
||||||
@@ -411,16 +408,16 @@ bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
|
|||||||
struct sk_buff *skb, unsigned int type)
|
struct sk_buff *skb, unsigned int type)
|
||||||
{
|
{
|
||||||
struct sja1105_private *priv = ds->priv;
|
struct sja1105_private *priv = ds->priv;
|
||||||
struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
|
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
|
||||||
|
|
||||||
if (!test_bit(SJA1105_HWTS_RX_EN, &tagger_data->state))
|
if (!test_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* We need to read the full PTP clock to reconstruct the Rx
|
/* We need to read the full PTP clock to reconstruct the Rx
|
||||||
* timestamp. For that we need a sleepable context.
|
* timestamp. For that we need a sleepable context.
|
||||||
*/
|
*/
|
||||||
skb_queue_tail(&tagger_data->skb_rxtstamp_queue, skb);
|
skb_queue_tail(&ptp_data->skb_rxtstamp_queue, skb);
|
||||||
schedule_work(&tagger_data->rxtstamp_work);
|
ptp_schedule_worker(ptp_data->clock, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,11 +625,11 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds)
|
|||||||
.adjtime = sja1105_ptp_adjtime,
|
.adjtime = sja1105_ptp_adjtime,
|
||||||
.gettimex64 = sja1105_ptp_gettimex,
|
.gettimex64 = sja1105_ptp_gettimex,
|
||||||
.settime64 = sja1105_ptp_settime,
|
.settime64 = sja1105_ptp_settime,
|
||||||
|
.do_aux_work = sja1105_rxtstamp_work,
|
||||||
.max_adj = SJA1105_MAX_ADJ_PPB,
|
.max_adj = SJA1105_MAX_ADJ_PPB,
|
||||||
};
|
};
|
||||||
|
|
||||||
skb_queue_head_init(&tagger_data->skb_rxtstamp_queue);
|
skb_queue_head_init(&ptp_data->skb_rxtstamp_queue);
|
||||||
INIT_WORK(&tagger_data->rxtstamp_work, sja1105_rxtstamp_work);
|
|
||||||
spin_lock_init(&tagger_data->meta_lock);
|
spin_lock_init(&tagger_data->meta_lock);
|
||||||
|
|
||||||
ptp_data->clock = ptp_clock_register(&ptp_data->caps, ds->dev);
|
ptp_data->clock = ptp_clock_register(&ptp_data->caps, ds->dev);
|
||||||
@@ -653,8 +650,8 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
|
|||||||
if (IS_ERR_OR_NULL(ptp_data->clock))
|
if (IS_ERR_OR_NULL(ptp_data->clock))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cancel_work_sync(&priv->tagger_data.rxtstamp_work);
|
ptp_cancel_worker_sync(ptp_data->clock);
|
||||||
skb_queue_purge(&priv->tagger_data.skb_rxtstamp_queue);
|
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
|
||||||
ptp_clock_unregister(ptp_data->clock);
|
ptp_clock_unregister(ptp_data->clock);
|
||||||
ptp_data->clock = NULL;
|
ptp_data->clock = NULL;
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@ struct sja1105_ptp_cmd {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct sja1105_ptp_data {
|
struct sja1105_ptp_data {
|
||||||
|
struct sk_buff_head skb_rxtstamp_queue;
|
||||||
struct ptp_clock_info caps;
|
struct ptp_clock_info caps;
|
||||||
struct ptp_clock *clock;
|
struct ptp_clock *clock;
|
||||||
struct sja1105_ptp_cmd cmd;
|
struct sja1105_ptp_cmd cmd;
|
||||||
|
@@ -37,8 +37,6 @@
|
|||||||
* the structure defined in struct sja1105_private.
|
* the structure defined in struct sja1105_private.
|
||||||
*/
|
*/
|
||||||
struct sja1105_tagger_data {
|
struct sja1105_tagger_data {
|
||||||
struct sk_buff_head skb_rxtstamp_queue;
|
|
||||||
struct work_struct rxtstamp_work;
|
|
||||||
struct sk_buff *stampable_skb;
|
struct sk_buff *stampable_skb;
|
||||||
/* Protects concurrent access to the meta state machine
|
/* Protects concurrent access to the meta state machine
|
||||||
* from taggers running on multiple ports on SMP systems
|
* from taggers running on multiple ports on SMP systems
|
||||||
|
Reference in New Issue
Block a user