Commit 0ad4982c authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by David S. Miller

net: renesas: rswitch: Fix timestamp feature after all descriptors are used

The timestamp descriptors were intended to act cyclically. Descriptors
from index 0 through gq->ring_size - 1 contain actual information, and
the last index (gq->ring_size) should have LINKFIX to indicate
the first index 0 descriptor. However, the LINKFIX value is missing,
causing the timestamp feature to stop after all descriptors are used.
To resolve this issue, set the LINKFIX to the timestamp descritors.
Reported-by: default avatarPhong Hoang <phong.hoang.wz@renesas.com>
Fixes: 33f5d733 ("net: renesas: rswitch: Improve TX timestamp accuracy")
Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6c02568f
......@@ -347,17 +347,6 @@ static int rswitch_gwca_queue_alloc(struct net_device *ndev,
return -ENOMEM;
}
static int rswitch_gwca_ts_queue_alloc(struct rswitch_private *priv)
{
struct rswitch_gwca_queue *gq = &priv->gwca.ts_queue;
gq->ring_size = TS_RING_SIZE;
gq->ts_ring = dma_alloc_coherent(&priv->pdev->dev,
sizeof(struct rswitch_ts_desc) *
(gq->ring_size + 1), &gq->ring_dma, GFP_KERNEL);
return !gq->ts_ring ? -ENOMEM : 0;
}
static void rswitch_desc_set_dptr(struct rswitch_desc *desc, dma_addr_t addr)
{
desc->dptrl = cpu_to_le32(lower_32_bits(addr));
......@@ -533,6 +522,28 @@ static void rswitch_gwca_linkfix_free(struct rswitch_private *priv)
gwca->linkfix_table = NULL;
}
static int rswitch_gwca_ts_queue_alloc(struct rswitch_private *priv)
{
struct rswitch_gwca_queue *gq = &priv->gwca.ts_queue;
struct rswitch_ts_desc *desc;
gq->ring_size = TS_RING_SIZE;
gq->ts_ring = dma_alloc_coherent(&priv->pdev->dev,
sizeof(struct rswitch_ts_desc) *
(gq->ring_size + 1), &gq->ring_dma, GFP_KERNEL);
if (!gq->ts_ring)
return -ENOMEM;
rswitch_gwca_ts_queue_fill(priv, 0, TS_RING_SIZE);
desc = &gq->ts_ring[gq->ring_size];
desc->desc.die_dt = DT_LINKFIX;
rswitch_desc_set_dptr(&desc->desc, gq->ring_dma);
INIT_LIST_HEAD(&priv->gwca.ts_info_list);
return 0;
}
static struct rswitch_gwca_queue *rswitch_gwca_get(struct rswitch_private *priv)
{
struct rswitch_gwca_queue *gq;
......@@ -1780,9 +1791,6 @@ static int rswitch_init(struct rswitch_private *priv)
if (err < 0)
goto err_ts_queue_alloc;
rswitch_gwca_ts_queue_fill(priv, 0, TS_RING_SIZE);
INIT_LIST_HEAD(&priv->gwca.ts_info_list);
for (i = 0; i < RSWITCH_NUM_PORTS; i++) {
err = rswitch_device_alloc(priv, i);
if (err < 0) {
......
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