Skip to content

Commit 434ceba

Browse files
claudiu-mdavem330
authored andcommitted
enetc: Add dynamic allocation of extended Rx BD rings
Hardware timestamping support (PTP) on Rx requires extended buffer descriptors, double the size of normal Rx descriptors. On the current controller revision only the timestamping offload requires extended Rx descriptors. Since Rx timestamping can be turned on/off at runtime, make Rx ring allocation configurable at runtime too. As a result, the static config option FSL_ENETC_HW_TIMESTAMPING can be dropped and the extended descriptors can be used only when Rx timestamping gets activated. The extension has the same size as the base descriptor, making the descriptor iterators easy to update for the extended case. Signed-off-by: Claudiu Manoil <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 714239a commit 434ceba

File tree

5 files changed

+48
-30
lines changed

5 files changed

+48
-30
lines changed

drivers/net/ethernet/freescale/enetc/Kconfig

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,6 @@ config FSL_ENETC_PTP_CLOCK
4242

4343
If compiled as module (M), the module name is fsl-enetc-ptp.
4444

45-
config FSL_ENETC_HW_TIMESTAMPING
46-
bool "ENETC hardware timestamping support"
47-
depends on FSL_ENETC || FSL_ENETC_VF
48-
help
49-
Enable hardware timestamping support on the Ethernet packets
50-
using the SO_TIMESTAMPING API. Because the RX BD ring dynamic
51-
allocation has not been supported and it is too expensive to use
52-
extended RX BDs if timestamping is not used, this option enables
53-
extended RX BDs in order to support hardware timestamping.
54-
5545
config FSL_ENETC_QOS
5646
bool "ENETC hardware Time-sensitive Network support"
5747
depends on (FSL_ENETC || FSL_ENETC_VF) && (NET_SCH_TAPRIO || NET_SCH_CBS)

drivers/net/ethernet/freescale/enetc/enetc.c

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ static int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
487487
return j;
488488
}
489489

490-
#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
490+
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
491491
static void enetc_get_rx_tstamp(struct net_device *ndev,
492492
union enetc_rx_bd *rxbd,
493493
struct sk_buff *skb)
@@ -501,7 +501,8 @@ static void enetc_get_rx_tstamp(struct net_device *ndev,
501501
if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_TSTMP) {
502502
lo = enetc_rd(hw, ENETC_SICTR0);
503503
hi = enetc_rd(hw, ENETC_SICTR1);
504-
tstamp_lo = le32_to_cpu(rxbd->r.tstamp);
504+
rxbd = enetc_rxbd_ext(rxbd);
505+
tstamp_lo = le32_to_cpu(rxbd->ext.tstamp);
505506
if (lo <= tstamp_lo)
506507
hi -= 1;
507508

@@ -515,7 +516,7 @@ static void enetc_get_rx_tstamp(struct net_device *ndev,
515516
static void enetc_get_offloads(struct enetc_bdr *rx_ring,
516517
union enetc_rx_bd *rxbd, struct sk_buff *skb)
517518
{
518-
#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
519+
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
519520
struct enetc_ndev_priv *priv = netdev_priv(rx_ring->ndev);
520521
#endif
521522
/* TODO: hashing */
@@ -532,7 +533,7 @@ static void enetc_get_offloads(struct enetc_bdr *rx_ring,
532533
if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN)
533534
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
534535
le16_to_cpu(rxbd->r.vlan_opt));
535-
#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
536+
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
536537
if (priv->active_offloads & ENETC_F_RX_TSTAMP)
537538
enetc_get_rx_tstamp(rx_ring->ndev, rxbd, skb);
538539
#endif
@@ -838,15 +839,19 @@ static void enetc_free_tx_resources(struct enetc_ndev_priv *priv)
838839
enetc_free_txbdr(priv->tx_ring[i]);
839840
}
840841

841-
static int enetc_alloc_rxbdr(struct enetc_bdr *rxr)
842+
static int enetc_alloc_rxbdr(struct enetc_bdr *rxr, bool extended)
842843
{
844+
size_t size = sizeof(union enetc_rx_bd);
843845
int err;
844846

845847
rxr->rx_swbd = vzalloc(rxr->bd_count * sizeof(struct enetc_rx_swbd));
846848
if (!rxr->rx_swbd)
847849
return -ENOMEM;
848850

849-
err = enetc_dma_alloc_bdr(rxr, sizeof(union enetc_rx_bd));
851+
if (extended)
852+
size *= 2;
853+
854+
err = enetc_dma_alloc_bdr(rxr, size);
850855
if (err) {
851856
vfree(rxr->rx_swbd);
852857
return err;
@@ -855,6 +860,7 @@ static int enetc_alloc_rxbdr(struct enetc_bdr *rxr)
855860
rxr->next_to_clean = 0;
856861
rxr->next_to_use = 0;
857862
rxr->next_to_alloc = 0;
863+
rxr->ext_en = extended;
858864

859865
return 0;
860866
}
@@ -874,10 +880,11 @@ static void enetc_free_rxbdr(struct enetc_bdr *rxr)
874880

875881
static int enetc_alloc_rx_resources(struct enetc_ndev_priv *priv)
876882
{
883+
bool extended = !!(priv->active_offloads & ENETC_F_RX_TSTAMP);
877884
int i, err;
878885

879886
for (i = 0; i < priv->num_rx_rings; i++) {
880-
err = enetc_alloc_rxbdr(priv->rx_ring[i]);
887+
err = enetc_alloc_rxbdr(priv->rx_ring[i], extended);
881888

882889
if (err)
883890
goto fail;
@@ -1167,9 +1174,10 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
11671174
enetc_rxbdr_wr(hw, idx, ENETC_RBICIR0, ENETC_RBICIR0_ICEN | 0x1);
11681175

11691176
rbmr = ENETC_RBMR_EN;
1170-
#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
1171-
rbmr |= ENETC_RBMR_BDS;
1172-
#endif
1177+
1178+
if (rx_ring->ext_en)
1179+
rbmr |= ENETC_RBMR_BDS;
1180+
11731181
if (rx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_RX)
11741182
rbmr |= ENETC_RBMR_VTE;
11751183

@@ -1570,11 +1578,12 @@ int enetc_set_features(struct net_device *ndev,
15701578
return 0;
15711579
}
15721580

1573-
#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
1581+
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
15741582
static int enetc_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
15751583
{
15761584
struct enetc_ndev_priv *priv = netdev_priv(ndev);
15771585
struct hwtstamp_config config;
1586+
int ao;
15781587

15791588
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
15801589
return -EFAULT;
@@ -1590,6 +1599,7 @@ static int enetc_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
15901599
return -ERANGE;
15911600
}
15921601

1602+
ao = priv->active_offloads;
15931603
switch (config.rx_filter) {
15941604
case HWTSTAMP_FILTER_NONE:
15951605
priv->active_offloads &= ~ENETC_F_RX_TSTAMP;
@@ -1599,6 +1609,11 @@ static int enetc_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
15991609
config.rx_filter = HWTSTAMP_FILTER_ALL;
16001610
}
16011611

1612+
if (netif_running(ndev) && ao != priv->active_offloads) {
1613+
enetc_close(ndev);
1614+
enetc_open(ndev);
1615+
}
1616+
16021617
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
16031618
-EFAULT : 0;
16041619
}
@@ -1625,7 +1640,7 @@ static int enetc_hwtstamp_get(struct net_device *ndev, struct ifreq *ifr)
16251640

16261641
int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
16271642
{
1628-
#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
1643+
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
16291644
if (cmd == SIOCSHWTSTAMP)
16301645
return enetc_hwtstamp_set(ndev, rq);
16311646
if (cmd == SIOCGHWTSTAMP)

drivers/net/ethernet/freescale/enetc/enetc.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ struct enetc_bdr {
7373

7474
dma_addr_t bd_dma_base;
7575
u8 tsd_enable; /* Time specific departure */
76+
bool ext_en; /* enable h/w descriptor extensions */
7677
} ____cacheline_aligned_in_smp;
7778

7879
static inline void enetc_bdr_idx_inc(struct enetc_bdr *bdr, int *i)
@@ -107,20 +108,35 @@ struct enetc_cbdr {
107108

108109
static inline union enetc_rx_bd *enetc_rxbd(struct enetc_bdr *rx_ring, int i)
109110
{
110-
return &(((union enetc_rx_bd *)rx_ring->bd_base)[i]);
111+
int hw_idx = i;
112+
113+
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
114+
if (rx_ring->ext_en)
115+
hw_idx = 2 * i;
116+
#endif
117+
return &(((union enetc_rx_bd *)rx_ring->bd_base)[hw_idx]);
111118
}
112119

113120
static inline union enetc_rx_bd *enetc_rxbd_next(struct enetc_bdr *rx_ring,
114121
union enetc_rx_bd *rxbd,
115122
int i)
116123
{
117124
rxbd++;
125+
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
126+
if (rx_ring->ext_en)
127+
rxbd++;
128+
#endif
118129
if (unlikely(++i == rx_ring->bd_count))
119130
rxbd = rx_ring->bd_base;
120131

121132
return rxbd;
122133
}
123134

135+
static inline union enetc_rx_bd *enetc_rxbd_ext(union enetc_rx_bd *rxbd)
136+
{
137+
return ++rxbd;
138+
}
139+
124140
struct enetc_msg_swbd {
125141
void *vaddr;
126142
dma_addr_t dma;

drivers/net/ethernet/freescale/enetc/enetc_ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ static int enetc_get_ts_info(struct net_device *ndev,
574574
info->phc_index = -1;
575575
}
576576

577-
#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
577+
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
578578
info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
579579
SOF_TIMESTAMPING_RX_HARDWARE |
580580
SOF_TIMESTAMPING_RAW_HARDWARE;

drivers/net/ethernet/freescale/enetc/enetc_hw.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,6 @@ union enetc_rx_bd {
418418
struct {
419419
__le64 addr;
420420
u8 reserved[8];
421-
#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
422-
u8 reserved1[16];
423-
#endif
424421
} w;
425422
struct {
426423
__le16 inet_csum;
@@ -435,11 +432,11 @@ union enetc_rx_bd {
435432
};
436433
__le32 lstatus;
437434
};
438-
#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
435+
} r;
436+
struct {
439437
__le32 tstamp;
440438
u8 reserved[12];
441-
#endif
442-
} r;
439+
} ext;
443440
};
444441

445442
#define ENETC_RXBD_LSTATUS_R BIT(30)

0 commit comments

Comments
 (0)