Skip to content

Commit 99100d0

Browse files
Wei Fangdavem330
authored andcommitted
net: enetc: add preliminary support for i.MX95 ENETC PF
The i.MX95 ENETC has been upgraded to revision 4.1, which is different from the LS1028A ENETC (revision 1.0) except for the SI part. Therefore, the fsl-enetc driver is incompatible with i.MX95 ENETC PF. So add new nxp-enetc4 driver to support i.MX95 ENETC PF, and this driver will be used to support the ENETC PF with major revision 4 for other SoCs in the future. Currently, the nxp-enetc4 driver only supports basic transmission feature for i.MX95 ENETC PF, the more basic and advanced features will be added in the subsequent patches. In addition, PCS support has not been added yet, so 10G ENETC (ENETC instance 2) is not supported now. Signed-off-by: Wei Fang <[email protected]> Reviewed-by: Frank Li <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9e7f211 commit 99100d0

File tree

14 files changed

+1113
-28
lines changed

14 files changed

+1113
-28
lines changed

drivers/net/ethernet/freescale/enetc/Kconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,23 @@ config FSL_ENETC
3333

3434
If compiled as module (M), the module name is fsl-enetc.
3535

36+
config NXP_ENETC4
37+
tristate "ENETC4 PF driver"
38+
depends on PCI_MSI
39+
select MDIO_DEVRES
40+
select FSL_ENETC_CORE
41+
select FSL_ENETC_MDIO
42+
select NXP_ENETC_PF_COMMON
43+
select PHYLINK
44+
select DIMLIB
45+
help
46+
This driver supports NXP ENETC devices with major revision 4. ENETC is
47+
as the NIC functionality in NETC, it supports virtualization/isolation
48+
based on PCIe Single Root IO Virtualization (SR-IOV) and a full range
49+
of TSN standards and NIC offload capabilities.
50+
51+
If compiled as module (M), the module name is nxp-enetc4.
52+
3653
config FSL_ENETC_VF
3754
tristate "ENETC VF driver"
3855
depends on PCI_MSI

drivers/net/ethernet/freescale/enetc/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ fsl-enetc-y := enetc_pf.o
1111
fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o
1212
fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o
1313

14+
obj-$(CONFIG_NXP_ENETC4) += nxp-enetc4.o
15+
nxp-enetc4-y := enetc4_pf.o
16+
1417
obj-$(CONFIG_FSL_ENETC_VF) += fsl-enetc-vf.o
1518
fsl-enetc-vf-y := enetc_vf.o
1619

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

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "enetc.h"
55
#include <linux/bpf_trace.h>
6+
#include <linux/clk.h>
67
#include <linux/tcp.h>
78
#include <linux/udp.h>
89
#include <linux/vmalloc.h>
@@ -21,7 +22,7 @@ void enetc_port_mac_wr(struct enetc_si *si, u32 reg, u32 val)
2122
{
2223
enetc_port_wr(&si->hw, reg, val);
2324
if (si->hw_features & ENETC_SI_F_QBU)
24-
enetc_port_wr(&si->hw, reg + ENETC_PMAC_OFFSET, val);
25+
enetc_port_wr(&si->hw, reg + si->drvdata->pmac_offset, val);
2526
}
2627
EXPORT_SYMBOL_GPL(enetc_port_mac_wr);
2728

@@ -700,8 +701,9 @@ static void enetc_rx_dim_work(struct work_struct *w)
700701
net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
701702
struct enetc_int_vector *v =
702703
container_of(dim, struct enetc_int_vector, rx_dim);
704+
struct enetc_ndev_priv *priv = netdev_priv(v->rx_ring.ndev);
703705

704-
v->rx_ictt = enetc_usecs_to_cycles(moder.usec);
706+
v->rx_ictt = enetc_usecs_to_cycles(moder.usec, priv->sysclk_freq);
705707
dim->state = DIM_START_MEASURE;
706708
}
707709

@@ -1736,9 +1738,15 @@ void enetc_get_si_caps(struct enetc_si *si)
17361738
si->num_rx_rings = (val >> 16) & 0xff;
17371739
si->num_tx_rings = val & 0xff;
17381740

1739-
val = enetc_rd(hw, ENETC_SIRFSCAPR);
1740-
si->num_fs_entries = ENETC_SIRFSCAPR_GET_NUM_RFS(val);
1741-
si->num_fs_entries = min(si->num_fs_entries, ENETC_MAX_RFS_SIZE);
1741+
val = enetc_rd(hw, ENETC_SIPCAPR0);
1742+
if (val & ENETC_SIPCAPR0_RFS) {
1743+
val = enetc_rd(hw, ENETC_SIRFSCAPR);
1744+
si->num_fs_entries = ENETC_SIRFSCAPR_GET_NUM_RFS(val);
1745+
si->num_fs_entries = min(si->num_fs_entries, ENETC_MAX_RFS_SIZE);
1746+
} else {
1747+
/* ENETC which not supports RFS */
1748+
si->num_fs_entries = 0;
1749+
}
17421750

17431751
si->num_rss = 0;
17441752
val = enetc_rd(hw, ENETC_SIPCAPR0);
@@ -2066,7 +2074,10 @@ int enetc_configure_si(struct enetc_ndev_priv *priv)
20662074
/* enable SI */
20672075
enetc_wr(hw, ENETC_SIMR, ENETC_SIMR_EN);
20682076

2069-
if (si->num_rss) {
2077+
/* TODO: RSS support for i.MX95 will be supported later, and the
2078+
* is_enetc_rev1() condition will be removed
2079+
*/
2080+
if (si->num_rss && is_enetc_rev1(si)) {
20702081
err = enetc_setup_default_rss_table(si, priv->num_rx_rings);
20712082
if (err)
20722083
return err;
@@ -2090,9 +2101,9 @@ void enetc_init_si_rings_params(struct enetc_ndev_priv *priv)
20902101
*/
20912102
priv->num_rx_rings = min_t(int, cpus, si->num_rx_rings);
20922103
priv->num_tx_rings = si->num_tx_rings;
2093-
priv->bdr_int_num = cpus;
2104+
priv->bdr_int_num = priv->num_rx_rings;
20942105
priv->ic_mode = ENETC_IC_RX_ADAPTIVE | ENETC_IC_TX_MANUAL;
2095-
priv->tx_ictt = ENETC_TXIC_TIMETHR;
2106+
priv->tx_ictt = enetc_usecs_to_cycles(600, priv->sysclk_freq);
20962107
}
20972108
EXPORT_SYMBOL_GPL(enetc_init_si_rings_params);
20982109

@@ -2501,10 +2512,14 @@ int enetc_open(struct net_device *ndev)
25012512

25022513
extended = !!(priv->active_offloads & ENETC_F_RX_TSTAMP);
25032514

2504-
err = enetc_setup_irqs(priv);
2515+
err = clk_prepare_enable(priv->ref_clk);
25052516
if (err)
25062517
return err;
25072518

2519+
err = enetc_setup_irqs(priv);
2520+
if (err)
2521+
goto err_setup_irqs;
2522+
25082523
err = enetc_phylink_connect(ndev);
25092524
if (err)
25102525
goto err_phy_connect;
@@ -2536,6 +2551,8 @@ int enetc_open(struct net_device *ndev)
25362551
phylink_disconnect_phy(priv->phylink);
25372552
err_phy_connect:
25382553
enetc_free_irqs(priv);
2554+
err_setup_irqs:
2555+
clk_disable_unprepare(priv->ref_clk);
25392556

25402557
return err;
25412558
}
@@ -2589,6 +2606,7 @@ int enetc_close(struct net_device *ndev)
25892606
enetc_assign_tx_resources(priv, NULL);
25902607

25912608
enetc_free_irqs(priv);
2609+
clk_disable_unprepare(priv->ref_clk);
25922610

25932611
return 0;
25942612
}
@@ -3254,5 +3272,55 @@ void enetc_pci_remove(struct pci_dev *pdev)
32543272
}
32553273
EXPORT_SYMBOL_GPL(enetc_pci_remove);
32563274

3275+
static const struct enetc_drvdata enetc_pf_data = {
3276+
.sysclk_freq = ENETC_CLK_400M,
3277+
.pmac_offset = ENETC_PMAC_OFFSET,
3278+
.eth_ops = &enetc_pf_ethtool_ops,
3279+
};
3280+
3281+
static const struct enetc_drvdata enetc4_pf_data = {
3282+
.sysclk_freq = ENETC_CLK_333M,
3283+
.pmac_offset = ENETC4_PMAC_OFFSET,
3284+
.eth_ops = &enetc4_pf_ethtool_ops,
3285+
};
3286+
3287+
static const struct enetc_drvdata enetc_vf_data = {
3288+
.sysclk_freq = ENETC_CLK_400M,
3289+
.eth_ops = &enetc_vf_ethtool_ops,
3290+
};
3291+
3292+
static const struct enetc_platform_info enetc_info[] = {
3293+
{ .revision = ENETC_REV_1_0,
3294+
.dev_id = ENETC_DEV_ID_PF,
3295+
.data = &enetc_pf_data,
3296+
},
3297+
{ .revision = ENETC_REV_4_1,
3298+
.dev_id = NXP_ENETC_PF_DEV_ID,
3299+
.data = &enetc4_pf_data,
3300+
},
3301+
{ .revision = ENETC_REV_1_0,
3302+
.dev_id = ENETC_DEV_ID_VF,
3303+
.data = &enetc_vf_data,
3304+
},
3305+
};
3306+
3307+
int enetc_get_driver_data(struct enetc_si *si)
3308+
{
3309+
u16 dev_id = si->pdev->device;
3310+
int i;
3311+
3312+
for (i = 0; i < ARRAY_SIZE(enetc_info); i++) {
3313+
if (si->revision == enetc_info[i].revision &&
3314+
dev_id == enetc_info[i].dev_id) {
3315+
si->drvdata = enetc_info[i].data;
3316+
3317+
return 0;
3318+
}
3319+
}
3320+
3321+
return -ERANGE;
3322+
}
3323+
EXPORT_SYMBOL_GPL(enetc_get_driver_data);
3324+
32573325
MODULE_DESCRIPTION("NXP ENETC Ethernet driver");
32583326
MODULE_LICENSE("Dual BSD/GPL");

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <net/xdp.h>
1515

1616
#include "enetc_hw.h"
17+
#include "enetc4_hw.h"
1718

1819
#define ENETC_MAC_MAXFRM_SIZE 9600
1920
#define ENETC_MAX_MTU (ENETC_MAC_MAXFRM_SIZE - \
@@ -231,6 +232,18 @@ enum enetc_errata {
231232
#define ENETC_SI_F_QBV BIT(1)
232233
#define ENETC_SI_F_QBU BIT(2)
233234

235+
struct enetc_drvdata {
236+
u32 pmac_offset; /* Only valid for PSI which supports 802.1Qbu */
237+
u64 sysclk_freq;
238+
const struct ethtool_ops *eth_ops;
239+
};
240+
241+
struct enetc_platform_info {
242+
u16 revision;
243+
u16 dev_id;
244+
const struct enetc_drvdata *data;
245+
};
246+
234247
/* PCI IEP device data */
235248
struct enetc_si {
236249
struct pci_dev *pdev;
@@ -246,11 +259,18 @@ struct enetc_si {
246259
int num_fs_entries;
247260
int num_rss; /* number of RSS buckets */
248261
unsigned short pad;
262+
u16 revision;
249263
int hw_features;
264+
const struct enetc_drvdata *drvdata;
250265
};
251266

252267
#define ENETC_SI_ALIGN 32
253268

269+
static inline bool is_enetc_rev1(struct enetc_si *si)
270+
{
271+
return si->pdev->revision == ENETC_REV1;
272+
}
273+
254274
static inline void *enetc_si_priv(const struct enetc_si *si)
255275
{
256276
return (char *)si + ALIGN(sizeof(struct enetc_si), ENETC_SI_ALIGN);
@@ -302,7 +322,7 @@ struct enetc_cls_rule {
302322
int used;
303323
};
304324

305-
#define ENETC_MAX_BDR_INT 2 /* fixed to max # of available cpus */
325+
#define ENETC_MAX_BDR_INT 6 /* fixed to max # of available cpus */
306326
struct psfp_cap {
307327
u32 max_streamid;
308328
u32 max_psfp_filter;
@@ -341,7 +361,6 @@ enum enetc_ic_mode {
341361

342362
#define ENETC_RXIC_PKTTHR min_t(u32, 256, ENETC_RX_RING_DEFAULT_SIZE / 2)
343363
#define ENETC_TXIC_PKTTHR min_t(u32, 128, ENETC_TX_RING_DEFAULT_SIZE / 2)
344-
#define ENETC_TXIC_TIMETHR enetc_usecs_to_cycles(600)
345364

346365
struct enetc_ndev_priv {
347366
struct net_device *ndev;
@@ -389,6 +408,9 @@ struct enetc_ndev_priv {
389408
* and link state updates
390409
*/
391410
struct mutex mm_lock;
411+
412+
struct clk *ref_clk; /* RGMII/RMII reference clock */
413+
u64 sysclk_freq; /* NETC system clock frequency */
392414
};
393415

394416
/* Messaging */
@@ -418,6 +440,7 @@ void enetc_init_si_rings_params(struct enetc_ndev_priv *priv);
418440
int enetc_alloc_si_resources(struct enetc_ndev_priv *priv);
419441
void enetc_free_si_resources(struct enetc_ndev_priv *priv);
420442
int enetc_configure_si(struct enetc_ndev_priv *priv);
443+
int enetc_get_driver_data(struct enetc_si *si);
421444

422445
int enetc_open(struct net_device *ndev);
423446
int enetc_close(struct net_device *ndev);
@@ -434,6 +457,9 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
434457
struct xdp_frame **frames, u32 flags);
435458

436459
/* ethtool */
460+
extern const struct ethtool_ops enetc_pf_ethtool_ops;
461+
extern const struct ethtool_ops enetc4_pf_ethtool_ops;
462+
extern const struct ethtool_ops enetc_vf_ethtool_ops;
437463
void enetc_set_ethtool_ops(struct net_device *ndev);
438464
void enetc_mm_link_state_update(struct enetc_ndev_priv *priv, bool link);
439465
void enetc_mm_commit_preemptible_tcs(struct enetc_ndev_priv *priv);

0 commit comments

Comments
 (0)