xref: /linux/drivers/net/ethernet/freescale/enetc/enetc4_pf.c (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
199100d0dSWei Fang // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
299100d0dSWei Fang /* Copyright 2024 NXP */
399100d0dSWei Fang 
499100d0dSWei Fang #include <linux/clk.h>
599100d0dSWei Fang #include <linux/module.h>
699100d0dSWei Fang #include <linux/of_net.h>
799100d0dSWei Fang #include <linux/of_platform.h>
899100d0dSWei Fang #include <linux/unaligned.h>
999100d0dSWei Fang 
1099100d0dSWei Fang #include "enetc_pf_common.h"
1199100d0dSWei Fang 
1299100d0dSWei Fang #define ENETC_SI_MAX_RING_NUM	8
1399100d0dSWei Fang 
1499100d0dSWei Fang static void enetc4_get_port_caps(struct enetc_pf *pf)
1599100d0dSWei Fang {
1699100d0dSWei Fang 	struct enetc_hw *hw = &pf->si->hw;
1799100d0dSWei Fang 	u32 val;
1899100d0dSWei Fang 
1999100d0dSWei Fang 	val = enetc_port_rd(hw, ENETC4_ECAPR1);
2099100d0dSWei Fang 	pf->caps.num_vsi = (val & ECAPR1_NUM_VSI) >> 24;
2199100d0dSWei Fang 	pf->caps.num_msix = ((val & ECAPR1_NUM_MSIX) >> 12) + 1;
2299100d0dSWei Fang 
2399100d0dSWei Fang 	val = enetc_port_rd(hw, ENETC4_ECAPR2);
2499100d0dSWei Fang 	pf->caps.num_rx_bdr = (val & ECAPR2_NUM_RX_BDR) >> 16;
2599100d0dSWei Fang 	pf->caps.num_tx_bdr = val & ECAPR2_NUM_TX_BDR;
2699100d0dSWei Fang 
2799100d0dSWei Fang 	val = enetc_port_rd(hw, ENETC4_PMCAPR);
2899100d0dSWei Fang 	pf->caps.half_duplex = (val & PMCAPR_HD) ? 1 : 0;
2999100d0dSWei Fang }
3099100d0dSWei Fang 
3199100d0dSWei Fang static void enetc4_pf_set_si_primary_mac(struct enetc_hw *hw, int si,
3299100d0dSWei Fang 					 const u8 *addr)
3399100d0dSWei Fang {
3499100d0dSWei Fang 	u16 lower = get_unaligned_le16(addr + 4);
3599100d0dSWei Fang 	u32 upper = get_unaligned_le32(addr);
3699100d0dSWei Fang 
3799100d0dSWei Fang 	if (si != 0) {
3899100d0dSWei Fang 		__raw_writel(upper, hw->port + ENETC4_PSIPMAR0(si));
3999100d0dSWei Fang 		__raw_writew(lower, hw->port + ENETC4_PSIPMAR1(si));
4099100d0dSWei Fang 	} else {
4199100d0dSWei Fang 		__raw_writel(upper, hw->port + ENETC4_PMAR0);
4299100d0dSWei Fang 		__raw_writew(lower, hw->port + ENETC4_PMAR1);
4399100d0dSWei Fang 	}
4499100d0dSWei Fang }
4599100d0dSWei Fang 
4699100d0dSWei Fang static void enetc4_pf_get_si_primary_mac(struct enetc_hw *hw, int si,
4799100d0dSWei Fang 					 u8 *addr)
4899100d0dSWei Fang {
4999100d0dSWei Fang 	u32 upper;
5099100d0dSWei Fang 	u16 lower;
5199100d0dSWei Fang 
5299100d0dSWei Fang 	upper = __raw_readl(hw->port + ENETC4_PSIPMAR0(si));
5399100d0dSWei Fang 	lower = __raw_readw(hw->port + ENETC4_PSIPMAR1(si));
5499100d0dSWei Fang 
5599100d0dSWei Fang 	put_unaligned_le32(upper, addr);
5699100d0dSWei Fang 	put_unaligned_le16(lower, addr + 4);
5799100d0dSWei Fang }
5899100d0dSWei Fang 
5999100d0dSWei Fang static const struct enetc_pf_ops enetc4_pf_ops = {
6099100d0dSWei Fang 	.set_si_primary_mac = enetc4_pf_set_si_primary_mac,
6199100d0dSWei Fang 	.get_si_primary_mac = enetc4_pf_get_si_primary_mac,
6299100d0dSWei Fang };
6399100d0dSWei Fang 
6499100d0dSWei Fang static int enetc4_pf_struct_init(struct enetc_si *si)
6599100d0dSWei Fang {
6699100d0dSWei Fang 	struct enetc_pf *pf = enetc_si_priv(si);
6799100d0dSWei Fang 
6899100d0dSWei Fang 	pf->si = si;
6999100d0dSWei Fang 	pf->total_vfs = pci_sriov_get_totalvfs(si->pdev);
7099100d0dSWei Fang 	pf->ops = &enetc4_pf_ops;
7199100d0dSWei Fang 
7299100d0dSWei Fang 	enetc4_get_port_caps(pf);
7399100d0dSWei Fang 
7499100d0dSWei Fang 	return 0;
7599100d0dSWei Fang }
7699100d0dSWei Fang 
7799100d0dSWei Fang static u32 enetc4_psicfgr0_val_construct(bool is_vf, u32 num_tx_bdr, u32 num_rx_bdr)
7899100d0dSWei Fang {
7999100d0dSWei Fang 	u32 val;
8099100d0dSWei Fang 
8199100d0dSWei Fang 	val = ENETC_PSICFGR0_SET_TXBDR(num_tx_bdr);
8299100d0dSWei Fang 	val |= ENETC_PSICFGR0_SET_RXBDR(num_rx_bdr);
8399100d0dSWei Fang 	val |= ENETC_PSICFGR0_SIVC(ENETC_VLAN_TYPE_C | ENETC_VLAN_TYPE_S);
8499100d0dSWei Fang 
8599100d0dSWei Fang 	if (is_vf)
8699100d0dSWei Fang 		val |= ENETC_PSICFGR0_VTE | ENETC_PSICFGR0_SIVIE;
8799100d0dSWei Fang 
8899100d0dSWei Fang 	return val;
8999100d0dSWei Fang }
9099100d0dSWei Fang 
9199100d0dSWei Fang static void enetc4_default_rings_allocation(struct enetc_pf *pf)
9299100d0dSWei Fang {
9399100d0dSWei Fang 	struct enetc_hw *hw = &pf->si->hw;
9499100d0dSWei Fang 	u32 num_rx_bdr, num_tx_bdr, val;
9599100d0dSWei Fang 	u32 vf_tx_bdr, vf_rx_bdr;
9699100d0dSWei Fang 	int i, rx_rem, tx_rem;
9799100d0dSWei Fang 
9899100d0dSWei Fang 	if (pf->caps.num_rx_bdr < ENETC_SI_MAX_RING_NUM + pf->caps.num_vsi)
9999100d0dSWei Fang 		num_rx_bdr = pf->caps.num_rx_bdr - pf->caps.num_vsi;
10099100d0dSWei Fang 	else
10199100d0dSWei Fang 		num_rx_bdr = ENETC_SI_MAX_RING_NUM;
10299100d0dSWei Fang 
10399100d0dSWei Fang 	if (pf->caps.num_tx_bdr < ENETC_SI_MAX_RING_NUM + pf->caps.num_vsi)
10499100d0dSWei Fang 		num_tx_bdr = pf->caps.num_tx_bdr - pf->caps.num_vsi;
10599100d0dSWei Fang 	else
10699100d0dSWei Fang 		num_tx_bdr = ENETC_SI_MAX_RING_NUM;
10799100d0dSWei Fang 
10899100d0dSWei Fang 	val = enetc4_psicfgr0_val_construct(false, num_tx_bdr, num_rx_bdr);
10999100d0dSWei Fang 	enetc_port_wr(hw, ENETC4_PSICFGR0(0), val);
11099100d0dSWei Fang 
11199100d0dSWei Fang 	num_rx_bdr = pf->caps.num_rx_bdr - num_rx_bdr;
11299100d0dSWei Fang 	rx_rem = num_rx_bdr % pf->caps.num_vsi;
11399100d0dSWei Fang 	num_rx_bdr = num_rx_bdr / pf->caps.num_vsi;
11499100d0dSWei Fang 
11599100d0dSWei Fang 	num_tx_bdr = pf->caps.num_tx_bdr - num_tx_bdr;
11699100d0dSWei Fang 	tx_rem = num_tx_bdr % pf->caps.num_vsi;
11799100d0dSWei Fang 	num_tx_bdr = num_tx_bdr / pf->caps.num_vsi;
11899100d0dSWei Fang 
11999100d0dSWei Fang 	for (i = 0; i < pf->caps.num_vsi; i++) {
12099100d0dSWei Fang 		vf_tx_bdr = (i < tx_rem) ? num_tx_bdr + 1 : num_tx_bdr;
12199100d0dSWei Fang 		vf_rx_bdr = (i < rx_rem) ? num_rx_bdr + 1 : num_rx_bdr;
12299100d0dSWei Fang 		val = enetc4_psicfgr0_val_construct(true, vf_tx_bdr, vf_rx_bdr);
12399100d0dSWei Fang 		enetc_port_wr(hw, ENETC4_PSICFGR0(i + 1), val);
12499100d0dSWei Fang 	}
12599100d0dSWei Fang }
12699100d0dSWei Fang 
12799100d0dSWei Fang static void enetc4_allocate_si_rings(struct enetc_pf *pf)
12899100d0dSWei Fang {
12999100d0dSWei Fang 	enetc4_default_rings_allocation(pf);
13099100d0dSWei Fang }
13199100d0dSWei Fang 
13299100d0dSWei Fang static void enetc4_pf_set_si_vlan_promisc(struct enetc_hw *hw, int si, bool en)
13399100d0dSWei Fang {
13499100d0dSWei Fang 	u32 val = enetc_port_rd(hw, ENETC4_PSIPVMR);
13599100d0dSWei Fang 
13699100d0dSWei Fang 	if (en)
13799100d0dSWei Fang 		val |= BIT(si);
13899100d0dSWei Fang 	else
13999100d0dSWei Fang 		val &= ~BIT(si);
14099100d0dSWei Fang 
14199100d0dSWei Fang 	enetc_port_wr(hw, ENETC4_PSIPVMR, val);
14299100d0dSWei Fang }
14399100d0dSWei Fang 
14499100d0dSWei Fang static void enetc4_set_default_si_vlan_promisc(struct enetc_pf *pf)
14599100d0dSWei Fang {
14699100d0dSWei Fang 	struct enetc_hw *hw = &pf->si->hw;
14799100d0dSWei Fang 	int num_si = pf->caps.num_vsi + 1;
14899100d0dSWei Fang 	int i;
14999100d0dSWei Fang 
15099100d0dSWei Fang 	/* enforce VLAN promiscuous mode for all SIs */
15199100d0dSWei Fang 	for (i = 0; i < num_si; i++)
15299100d0dSWei Fang 		enetc4_pf_set_si_vlan_promisc(hw, i, true);
15399100d0dSWei Fang }
15499100d0dSWei Fang 
15599100d0dSWei Fang /* Allocate the number of MSI-X vectors for per SI. */
15699100d0dSWei Fang static void enetc4_set_si_msix_num(struct enetc_pf *pf)
15799100d0dSWei Fang {
15899100d0dSWei Fang 	struct enetc_hw *hw = &pf->si->hw;
15999100d0dSWei Fang 	int i, num_msix, total_si;
16099100d0dSWei Fang 	u32 val;
16199100d0dSWei Fang 
16299100d0dSWei Fang 	total_si = pf->caps.num_vsi + 1;
16399100d0dSWei Fang 
16499100d0dSWei Fang 	num_msix = pf->caps.num_msix / total_si +
16599100d0dSWei Fang 		   pf->caps.num_msix % total_si - 1;
16699100d0dSWei Fang 	val = num_msix & PSICFGR2_NUM_MSIX;
16799100d0dSWei Fang 	enetc_port_wr(hw, ENETC4_PSICFGR2(0), val);
16899100d0dSWei Fang 
16999100d0dSWei Fang 	num_msix = pf->caps.num_msix / total_si - 1;
17099100d0dSWei Fang 	val = num_msix & PSICFGR2_NUM_MSIX;
17199100d0dSWei Fang 	for (i = 0; i < pf->caps.num_vsi; i++)
17299100d0dSWei Fang 		enetc_port_wr(hw, ENETC4_PSICFGR2(i + 1), val);
17399100d0dSWei Fang }
17499100d0dSWei Fang 
17599100d0dSWei Fang static void enetc4_enable_all_si(struct enetc_pf *pf)
17699100d0dSWei Fang {
17799100d0dSWei Fang 	struct enetc_hw *hw = &pf->si->hw;
17899100d0dSWei Fang 	int num_si = pf->caps.num_vsi + 1;
17999100d0dSWei Fang 	u32 si_bitmap = 0;
18099100d0dSWei Fang 	int i;
18199100d0dSWei Fang 
18299100d0dSWei Fang 	/* Master enable for all SIs */
18399100d0dSWei Fang 	for (i = 0; i < num_si; i++)
18499100d0dSWei Fang 		si_bitmap |= PMR_SI_EN(i);
18599100d0dSWei Fang 
18699100d0dSWei Fang 	enetc_port_wr(hw, ENETC4_PMR, si_bitmap);
18799100d0dSWei Fang }
18899100d0dSWei Fang 
18999100d0dSWei Fang static void enetc4_configure_port_si(struct enetc_pf *pf)
19099100d0dSWei Fang {
19199100d0dSWei Fang 	struct enetc_hw *hw = &pf->si->hw;
19299100d0dSWei Fang 
19399100d0dSWei Fang 	enetc4_allocate_si_rings(pf);
19499100d0dSWei Fang 
19599100d0dSWei Fang 	/* Outer VLAN tag will be used for VLAN filtering */
19699100d0dSWei Fang 	enetc_port_wr(hw, ENETC4_PSIVLANFMR, PSIVLANFMR_VS);
19799100d0dSWei Fang 
19899100d0dSWei Fang 	enetc4_set_default_si_vlan_promisc(pf);
19999100d0dSWei Fang 
20099100d0dSWei Fang 	/* Disable SI MAC multicast & unicast promiscuous */
20199100d0dSWei Fang 	enetc_port_wr(hw, ENETC4_PSIPMMR, 0);
20299100d0dSWei Fang 
20399100d0dSWei Fang 	enetc4_set_si_msix_num(pf);
20499100d0dSWei Fang 
20599100d0dSWei Fang 	enetc4_enable_all_si(pf);
20699100d0dSWei Fang }
20799100d0dSWei Fang 
20899100d0dSWei Fang static void enetc4_pf_reset_tc_msdu(struct enetc_hw *hw)
20999100d0dSWei Fang {
21099100d0dSWei Fang 	u32 val = ENETC_MAC_MAXFRM_SIZE;
21199100d0dSWei Fang 	int tc;
21299100d0dSWei Fang 
21399100d0dSWei Fang 	val = u32_replace_bits(val, SDU_TYPE_MPDU, PTCTMSDUR_SDU_TYPE);
21499100d0dSWei Fang 
21599100d0dSWei Fang 	for (tc = 0; tc < ENETC_NUM_TC; tc++)
21699100d0dSWei Fang 		enetc_port_wr(hw, ENETC4_PTCTMSDUR(tc), val);
21799100d0dSWei Fang }
21899100d0dSWei Fang 
21999100d0dSWei Fang static void enetc4_set_trx_frame_size(struct enetc_pf *pf)
22099100d0dSWei Fang {
22199100d0dSWei Fang 	struct enetc_si *si = pf->si;
22299100d0dSWei Fang 
22399100d0dSWei Fang 	enetc_port_mac_wr(si, ENETC4_PM_MAXFRM(0),
22499100d0dSWei Fang 			  ENETC_SET_MAXFRM(ENETC_MAC_MAXFRM_SIZE));
22599100d0dSWei Fang 
22699100d0dSWei Fang 	enetc4_pf_reset_tc_msdu(&si->hw);
22799100d0dSWei Fang }
22899100d0dSWei Fang 
22999100d0dSWei Fang static void enetc4_set_rss_key(struct enetc_hw *hw, const u8 *bytes)
23099100d0dSWei Fang {
23199100d0dSWei Fang 	int i;
23299100d0dSWei Fang 
23399100d0dSWei Fang 	for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++)
23499100d0dSWei Fang 		enetc_port_wr(hw, ENETC4_PRSSKR(i), ((u32 *)bytes)[i]);
23599100d0dSWei Fang }
23699100d0dSWei Fang 
23799100d0dSWei Fang static void enetc4_set_default_rss_key(struct enetc_pf *pf)
23899100d0dSWei Fang {
23999100d0dSWei Fang 	u8 hash_key[ENETC_RSSHASH_KEY_SIZE] = {0};
24099100d0dSWei Fang 	struct enetc_hw *hw = &pf->si->hw;
24199100d0dSWei Fang 
24299100d0dSWei Fang 	/* set up hash key */
24399100d0dSWei Fang 	get_random_bytes(hash_key, ENETC_RSSHASH_KEY_SIZE);
24499100d0dSWei Fang 	enetc4_set_rss_key(hw, hash_key);
24599100d0dSWei Fang }
24699100d0dSWei Fang 
24799100d0dSWei Fang static void enetc4_enable_trx(struct enetc_pf *pf)
24899100d0dSWei Fang {
24999100d0dSWei Fang 	struct enetc_hw *hw = &pf->si->hw;
25099100d0dSWei Fang 
25199100d0dSWei Fang 	/* Enable port transmit/receive */
25299100d0dSWei Fang 	enetc_port_wr(hw, ENETC4_POR, 0);
25399100d0dSWei Fang }
25499100d0dSWei Fang 
25599100d0dSWei Fang static void enetc4_configure_port(struct enetc_pf *pf)
25699100d0dSWei Fang {
25799100d0dSWei Fang 	enetc4_configure_port_si(pf);
25899100d0dSWei Fang 	enetc4_set_trx_frame_size(pf);
25999100d0dSWei Fang 	enetc4_set_default_rss_key(pf);
26099100d0dSWei Fang 	enetc4_enable_trx(pf);
26199100d0dSWei Fang }
26299100d0dSWei Fang 
26399100d0dSWei Fang static int enetc4_pf_init(struct enetc_pf *pf)
26499100d0dSWei Fang {
26599100d0dSWei Fang 	struct device *dev = &pf->si->pdev->dev;
26699100d0dSWei Fang 	int err;
26799100d0dSWei Fang 
26899100d0dSWei Fang 	/* Initialize the MAC address for PF and VFs */
26999100d0dSWei Fang 	err = enetc_setup_mac_addresses(dev->of_node, pf);
27099100d0dSWei Fang 	if (err) {
27199100d0dSWei Fang 		dev_err(dev, "Failed to set MAC addresses\n");
27299100d0dSWei Fang 		return err;
27399100d0dSWei Fang 	}
27499100d0dSWei Fang 
27599100d0dSWei Fang 	enetc4_configure_port(pf);
27699100d0dSWei Fang 
27799100d0dSWei Fang 	return 0;
27899100d0dSWei Fang }
27999100d0dSWei Fang 
28099100d0dSWei Fang static const struct net_device_ops enetc4_ndev_ops = {
28199100d0dSWei Fang 	.ndo_open		= enetc_open,
28299100d0dSWei Fang 	.ndo_stop		= enetc_close,
28399100d0dSWei Fang 	.ndo_start_xmit		= enetc_xmit,
28499100d0dSWei Fang 	.ndo_get_stats		= enetc_get_stats,
28599100d0dSWei Fang 	.ndo_set_mac_address	= enetc_pf_set_mac_addr,
28699100d0dSWei Fang };
28799100d0dSWei Fang 
28899100d0dSWei Fang static struct phylink_pcs *
28999100d0dSWei Fang enetc4_pl_mac_select_pcs(struct phylink_config *config, phy_interface_t iface)
29099100d0dSWei Fang {
29199100d0dSWei Fang 	struct enetc_pf *pf = phylink_to_enetc_pf(config);
29299100d0dSWei Fang 
29399100d0dSWei Fang 	return pf->pcs;
29499100d0dSWei Fang }
29599100d0dSWei Fang 
29699100d0dSWei Fang static void enetc4_mac_config(struct enetc_pf *pf, unsigned int mode,
29799100d0dSWei Fang 			      phy_interface_t phy_mode)
29899100d0dSWei Fang {
29999100d0dSWei Fang 	struct enetc_ndev_priv *priv = netdev_priv(pf->si->ndev);
30099100d0dSWei Fang 	struct enetc_si *si = pf->si;
30199100d0dSWei Fang 	u32 val;
30299100d0dSWei Fang 
30399100d0dSWei Fang 	val = enetc_port_mac_rd(si, ENETC4_PM_IF_MODE(0));
30499100d0dSWei Fang 	val &= ~(PM_IF_MODE_IFMODE | PM_IF_MODE_ENA);
30599100d0dSWei Fang 
30699100d0dSWei Fang 	switch (phy_mode) {
30799100d0dSWei Fang 	case PHY_INTERFACE_MODE_RGMII:
30899100d0dSWei Fang 	case PHY_INTERFACE_MODE_RGMII_ID:
30999100d0dSWei Fang 	case PHY_INTERFACE_MODE_RGMII_RXID:
31099100d0dSWei Fang 	case PHY_INTERFACE_MODE_RGMII_TXID:
31199100d0dSWei Fang 		val |= IFMODE_RGMII;
31299100d0dSWei Fang 		/* We need to enable auto-negotiation for the MAC
31399100d0dSWei Fang 		 * if its RGMII interface support In-Band status.
31499100d0dSWei Fang 		 */
31599100d0dSWei Fang 		if (phylink_autoneg_inband(mode))
31699100d0dSWei Fang 			val |= PM_IF_MODE_ENA;
31799100d0dSWei Fang 		break;
31899100d0dSWei Fang 	case PHY_INTERFACE_MODE_RMII:
31999100d0dSWei Fang 		val |= IFMODE_RMII;
32099100d0dSWei Fang 		break;
32199100d0dSWei Fang 	case PHY_INTERFACE_MODE_SGMII:
32299100d0dSWei Fang 	case PHY_INTERFACE_MODE_2500BASEX:
32399100d0dSWei Fang 		val |= IFMODE_SGMII;
32499100d0dSWei Fang 		break;
32599100d0dSWei Fang 	case PHY_INTERFACE_MODE_10GBASER:
32699100d0dSWei Fang 	case PHY_INTERFACE_MODE_XGMII:
32799100d0dSWei Fang 	case PHY_INTERFACE_MODE_USXGMII:
32899100d0dSWei Fang 		val |= IFMODE_XGMII;
32999100d0dSWei Fang 		break;
33099100d0dSWei Fang 	default:
33199100d0dSWei Fang 		dev_err(priv->dev,
33299100d0dSWei Fang 			"Unsupported PHY mode:%d\n", phy_mode);
33399100d0dSWei Fang 		return;
33499100d0dSWei Fang 	}
33599100d0dSWei Fang 
33699100d0dSWei Fang 	enetc_port_mac_wr(si, ENETC4_PM_IF_MODE(0), val);
33799100d0dSWei Fang }
33899100d0dSWei Fang 
33999100d0dSWei Fang static void enetc4_pl_mac_config(struct phylink_config *config, unsigned int mode,
34099100d0dSWei Fang 				 const struct phylink_link_state *state)
34199100d0dSWei Fang {
34299100d0dSWei Fang 	struct enetc_pf *pf = phylink_to_enetc_pf(config);
34399100d0dSWei Fang 
34499100d0dSWei Fang 	enetc4_mac_config(pf, mode, state->interface);
34599100d0dSWei Fang }
34699100d0dSWei Fang 
34799100d0dSWei Fang static void enetc4_set_port_speed(struct enetc_ndev_priv *priv, int speed)
34899100d0dSWei Fang {
34999100d0dSWei Fang 	u32 old_speed = priv->speed;
35099100d0dSWei Fang 	u32 val;
35199100d0dSWei Fang 
35299100d0dSWei Fang 	if (speed == old_speed)
35399100d0dSWei Fang 		return;
35499100d0dSWei Fang 
35599100d0dSWei Fang 	val = enetc_port_rd(&priv->si->hw, ENETC4_PCR);
35699100d0dSWei Fang 	val &= ~PCR_PSPEED;
35799100d0dSWei Fang 
35899100d0dSWei Fang 	switch (speed) {
35999100d0dSWei Fang 	case SPEED_100:
36099100d0dSWei Fang 	case SPEED_1000:
36199100d0dSWei Fang 	case SPEED_2500:
36299100d0dSWei Fang 	case SPEED_10000:
36399100d0dSWei Fang 		val |= (PCR_PSPEED & PCR_PSPEED_VAL(speed));
36499100d0dSWei Fang 		break;
36599100d0dSWei Fang 	case SPEED_10:
36699100d0dSWei Fang 	default:
36799100d0dSWei Fang 		val |= (PCR_PSPEED & PCR_PSPEED_VAL(SPEED_10));
36899100d0dSWei Fang 	}
36999100d0dSWei Fang 
37099100d0dSWei Fang 	priv->speed = speed;
37199100d0dSWei Fang 	enetc_port_wr(&priv->si->hw, ENETC4_PCR, val);
37299100d0dSWei Fang }
37399100d0dSWei Fang 
37499100d0dSWei Fang static void enetc4_set_rgmii_mac(struct enetc_pf *pf, int speed, int duplex)
37599100d0dSWei Fang {
37699100d0dSWei Fang 	struct enetc_si *si = pf->si;
37799100d0dSWei Fang 	u32 old_val, val;
37899100d0dSWei Fang 
37999100d0dSWei Fang 	old_val = enetc_port_mac_rd(si, ENETC4_PM_IF_MODE(0));
38099100d0dSWei Fang 	val = old_val & ~(PM_IF_MODE_ENA | PM_IF_MODE_M10 | PM_IF_MODE_REVMII);
38199100d0dSWei Fang 
38299100d0dSWei Fang 	switch (speed) {
38399100d0dSWei Fang 	case SPEED_1000:
38499100d0dSWei Fang 		val = u32_replace_bits(val, SSP_1G, PM_IF_MODE_SSP);
38599100d0dSWei Fang 		break;
38699100d0dSWei Fang 	case SPEED_100:
38799100d0dSWei Fang 		val = u32_replace_bits(val, SSP_100M, PM_IF_MODE_SSP);
38899100d0dSWei Fang 		break;
38999100d0dSWei Fang 	case SPEED_10:
39099100d0dSWei Fang 		val = u32_replace_bits(val, SSP_10M, PM_IF_MODE_SSP);
39199100d0dSWei Fang 	}
39299100d0dSWei Fang 
39399100d0dSWei Fang 	val = u32_replace_bits(val, duplex == DUPLEX_FULL ? 0 : 1,
39499100d0dSWei Fang 			       PM_IF_MODE_HD);
39599100d0dSWei Fang 
39699100d0dSWei Fang 	if (val == old_val)
39799100d0dSWei Fang 		return;
39899100d0dSWei Fang 
39999100d0dSWei Fang 	enetc_port_mac_wr(si, ENETC4_PM_IF_MODE(0), val);
40099100d0dSWei Fang }
40199100d0dSWei Fang 
40299100d0dSWei Fang static void enetc4_set_rmii_mac(struct enetc_pf *pf, int speed, int duplex)
40399100d0dSWei Fang {
40499100d0dSWei Fang 	struct enetc_si *si = pf->si;
40599100d0dSWei Fang 	u32 old_val, val;
40699100d0dSWei Fang 
40799100d0dSWei Fang 	old_val = enetc_port_mac_rd(si, ENETC4_PM_IF_MODE(0));
40899100d0dSWei Fang 	val = old_val & ~(PM_IF_MODE_ENA | PM_IF_MODE_SSP);
40999100d0dSWei Fang 
41099100d0dSWei Fang 	switch (speed) {
41199100d0dSWei Fang 	case SPEED_100:
41299100d0dSWei Fang 		val &= ~PM_IF_MODE_M10;
41399100d0dSWei Fang 		break;
41499100d0dSWei Fang 	case SPEED_10:
41599100d0dSWei Fang 		val |= PM_IF_MODE_M10;
41699100d0dSWei Fang 	}
41799100d0dSWei Fang 
41899100d0dSWei Fang 	val = u32_replace_bits(val, duplex == DUPLEX_FULL ? 0 : 1,
41999100d0dSWei Fang 			       PM_IF_MODE_HD);
42099100d0dSWei Fang 
42199100d0dSWei Fang 	if (val == old_val)
42299100d0dSWei Fang 		return;
42399100d0dSWei Fang 
42499100d0dSWei Fang 	enetc_port_mac_wr(si, ENETC4_PM_IF_MODE(0), val);
42599100d0dSWei Fang }
42699100d0dSWei Fang 
42799100d0dSWei Fang static void enetc4_set_hd_flow_control(struct enetc_pf *pf, bool enable)
42899100d0dSWei Fang {
42999100d0dSWei Fang 	struct enetc_si *si = pf->si;
43099100d0dSWei Fang 	u32 old_val, val;
43199100d0dSWei Fang 
43299100d0dSWei Fang 	if (!pf->caps.half_duplex)
43399100d0dSWei Fang 		return;
43499100d0dSWei Fang 
43599100d0dSWei Fang 	old_val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
43699100d0dSWei Fang 	val = u32_replace_bits(old_val, enable ? 1 : 0, PM_CMD_CFG_HD_FCEN);
43799100d0dSWei Fang 	if (val == old_val)
43899100d0dSWei Fang 		return;
43999100d0dSWei Fang 
44099100d0dSWei Fang 	enetc_port_mac_wr(si, ENETC4_PM_CMD_CFG(0), val);
44199100d0dSWei Fang }
44299100d0dSWei Fang 
44399100d0dSWei Fang static void enetc4_set_rx_pause(struct enetc_pf *pf, bool rx_pause)
44499100d0dSWei Fang {
44599100d0dSWei Fang 	struct enetc_si *si = pf->si;
44699100d0dSWei Fang 	u32 old_val, val;
44799100d0dSWei Fang 
44899100d0dSWei Fang 	old_val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
44999100d0dSWei Fang 	val = u32_replace_bits(old_val, rx_pause ? 0 : 1, PM_CMD_CFG_PAUSE_IGN);
45099100d0dSWei Fang 	if (val == old_val)
45199100d0dSWei Fang 		return;
45299100d0dSWei Fang 
45399100d0dSWei Fang 	enetc_port_mac_wr(si, ENETC4_PM_CMD_CFG(0), val);
45499100d0dSWei Fang }
45599100d0dSWei Fang 
45699100d0dSWei Fang static void enetc4_set_tx_pause(struct enetc_pf *pf, int num_rxbdr, bool tx_pause)
45799100d0dSWei Fang {
45899100d0dSWei Fang 	u32 pause_off_thresh = 0, pause_on_thresh = 0;
45999100d0dSWei Fang 	u32 init_quanta = 0, refresh_quanta = 0;
46099100d0dSWei Fang 	struct enetc_hw *hw = &pf->si->hw;
46199100d0dSWei Fang 	u32 rbmr, old_rbmr;
46299100d0dSWei Fang 	int i;
46399100d0dSWei Fang 
46499100d0dSWei Fang 	for (i = 0; i < num_rxbdr; i++) {
46599100d0dSWei Fang 		old_rbmr = enetc_rxbdr_rd(hw, i, ENETC_RBMR);
46699100d0dSWei Fang 		rbmr = u32_replace_bits(old_rbmr, tx_pause ? 1 : 0, ENETC_RBMR_CM);
46799100d0dSWei Fang 		if (rbmr == old_rbmr)
46899100d0dSWei Fang 			continue;
46999100d0dSWei Fang 
47099100d0dSWei Fang 		enetc_rxbdr_wr(hw, i, ENETC_RBMR, rbmr);
47199100d0dSWei Fang 	}
47299100d0dSWei Fang 
47399100d0dSWei Fang 	if (tx_pause) {
47499100d0dSWei Fang 		/* When the port first enters congestion, send a PAUSE request
47599100d0dSWei Fang 		 * with the maximum number of quanta. When the port exits
47699100d0dSWei Fang 		 * congestion, it will automatically send a PAUSE frame with
47799100d0dSWei Fang 		 * zero quanta.
47899100d0dSWei Fang 		 */
47999100d0dSWei Fang 		init_quanta = 0xffff;
48099100d0dSWei Fang 
48199100d0dSWei Fang 		/* Also, set up the refresh timer to send follow-up PAUSE
48299100d0dSWei Fang 		 * frames at half the quanta value, in case the congestion
48399100d0dSWei Fang 		 * condition persists.
48499100d0dSWei Fang 		 */
48599100d0dSWei Fang 		refresh_quanta = 0xffff / 2;
48699100d0dSWei Fang 
48799100d0dSWei Fang 		/* Start emitting PAUSE frames when 3 large frames (or more
48899100d0dSWei Fang 		 * smaller frames) have accumulated in the FIFO waiting to be
48999100d0dSWei Fang 		 * DMAed to the RX ring.
49099100d0dSWei Fang 		 */
49199100d0dSWei Fang 		pause_on_thresh = 3 * ENETC_MAC_MAXFRM_SIZE;
49299100d0dSWei Fang 		pause_off_thresh = 1 * ENETC_MAC_MAXFRM_SIZE;
49399100d0dSWei Fang 	}
49499100d0dSWei Fang 
49599100d0dSWei Fang 	enetc_port_mac_wr(pf->si, ENETC4_PM_PAUSE_QUANTA(0), init_quanta);
49699100d0dSWei Fang 	enetc_port_mac_wr(pf->si, ENETC4_PM_PAUSE_THRESH(0), refresh_quanta);
49799100d0dSWei Fang 	enetc_port_wr(hw, ENETC4_PPAUONTR, pause_on_thresh);
49899100d0dSWei Fang 	enetc_port_wr(hw, ENETC4_PPAUOFFTR, pause_off_thresh);
49999100d0dSWei Fang }
50099100d0dSWei Fang 
50199100d0dSWei Fang static void enetc4_enable_mac(struct enetc_pf *pf, bool en)
50299100d0dSWei Fang {
50399100d0dSWei Fang 	struct enetc_si *si = pf->si;
50499100d0dSWei Fang 	u32 val;
50599100d0dSWei Fang 
50699100d0dSWei Fang 	val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
50799100d0dSWei Fang 	val &= ~(PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN);
50899100d0dSWei Fang 	val |= en ? (PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN) : 0;
50999100d0dSWei Fang 
51099100d0dSWei Fang 	enetc_port_mac_wr(si, ENETC4_PM_CMD_CFG(0), val);
51199100d0dSWei Fang }
51299100d0dSWei Fang 
51399100d0dSWei Fang static void enetc4_pl_mac_link_up(struct phylink_config *config,
51499100d0dSWei Fang 				  struct phy_device *phy, unsigned int mode,
51599100d0dSWei Fang 				  phy_interface_t interface, int speed,
51699100d0dSWei Fang 				  int duplex, bool tx_pause, bool rx_pause)
51799100d0dSWei Fang {
51899100d0dSWei Fang 	struct enetc_pf *pf = phylink_to_enetc_pf(config);
51999100d0dSWei Fang 	struct enetc_si *si = pf->si;
52099100d0dSWei Fang 	struct enetc_ndev_priv *priv;
52199100d0dSWei Fang 	bool hd_fc = false;
52299100d0dSWei Fang 
52399100d0dSWei Fang 	priv = netdev_priv(si->ndev);
52499100d0dSWei Fang 	enetc4_set_port_speed(priv, speed);
52599100d0dSWei Fang 
52699100d0dSWei Fang 	if (!phylink_autoneg_inband(mode) &&
52799100d0dSWei Fang 	    phy_interface_mode_is_rgmii(interface))
52899100d0dSWei Fang 		enetc4_set_rgmii_mac(pf, speed, duplex);
52999100d0dSWei Fang 
53099100d0dSWei Fang 	if (interface == PHY_INTERFACE_MODE_RMII)
53199100d0dSWei Fang 		enetc4_set_rmii_mac(pf, speed, duplex);
53299100d0dSWei Fang 
53399100d0dSWei Fang 	if (duplex == DUPLEX_FULL) {
53499100d0dSWei Fang 		/* When preemption is enabled, generation of PAUSE frames
53599100d0dSWei Fang 		 * must be disabled, as stated in the IEEE 802.3 standard.
53699100d0dSWei Fang 		 */
53799100d0dSWei Fang 		if (priv->active_offloads & ENETC_F_QBU)
53899100d0dSWei Fang 			tx_pause = false;
53999100d0dSWei Fang 	} else { /* DUPLEX_HALF */
54099100d0dSWei Fang 		if (tx_pause || rx_pause)
54199100d0dSWei Fang 			hd_fc = true;
54299100d0dSWei Fang 
54399100d0dSWei Fang 		/* As per 802.3 annex 31B, PAUSE frames are only supported
54499100d0dSWei Fang 		 * when the link is configured for full duplex operation.
54599100d0dSWei Fang 		 */
54699100d0dSWei Fang 		tx_pause = false;
54799100d0dSWei Fang 		rx_pause = false;
54899100d0dSWei Fang 	}
54999100d0dSWei Fang 
55099100d0dSWei Fang 	enetc4_set_hd_flow_control(pf, hd_fc);
55199100d0dSWei Fang 	enetc4_set_tx_pause(pf, priv->num_rx_rings, tx_pause);
55299100d0dSWei Fang 	enetc4_set_rx_pause(pf, rx_pause);
55399100d0dSWei Fang 	enetc4_enable_mac(pf, true);
55499100d0dSWei Fang }
55599100d0dSWei Fang 
55699100d0dSWei Fang static void enetc4_pl_mac_link_down(struct phylink_config *config,
55799100d0dSWei Fang 				    unsigned int mode,
55899100d0dSWei Fang 				    phy_interface_t interface)
55999100d0dSWei Fang {
56099100d0dSWei Fang 	struct enetc_pf *pf = phylink_to_enetc_pf(config);
56199100d0dSWei Fang 
56299100d0dSWei Fang 	enetc4_enable_mac(pf, false);
56399100d0dSWei Fang }
56499100d0dSWei Fang 
56599100d0dSWei Fang static const struct phylink_mac_ops enetc_pl_mac_ops = {
56699100d0dSWei Fang 	.mac_select_pcs = enetc4_pl_mac_select_pcs,
56799100d0dSWei Fang 	.mac_config = enetc4_pl_mac_config,
56899100d0dSWei Fang 	.mac_link_up = enetc4_pl_mac_link_up,
56999100d0dSWei Fang 	.mac_link_down = enetc4_pl_mac_link_down,
57099100d0dSWei Fang };
57199100d0dSWei Fang 
57299100d0dSWei Fang static void enetc4_pci_remove(void *data)
57399100d0dSWei Fang {
57499100d0dSWei Fang 	struct pci_dev *pdev = data;
57599100d0dSWei Fang 
57699100d0dSWei Fang 	enetc_pci_remove(pdev);
57799100d0dSWei Fang }
57899100d0dSWei Fang 
57999100d0dSWei Fang static int enetc4_link_init(struct enetc_ndev_priv *priv,
58099100d0dSWei Fang 			    struct device_node *node)
58199100d0dSWei Fang {
58299100d0dSWei Fang 	struct enetc_pf *pf = enetc_si_priv(priv->si);
58399100d0dSWei Fang 	struct device *dev = priv->dev;
58499100d0dSWei Fang 	int err;
58599100d0dSWei Fang 
58699100d0dSWei Fang 	err = of_get_phy_mode(node, &pf->if_mode);
58799100d0dSWei Fang 	if (err) {
58899100d0dSWei Fang 		dev_err(dev, "Failed to get PHY mode\n");
58999100d0dSWei Fang 		return err;
59099100d0dSWei Fang 	}
59199100d0dSWei Fang 
59299100d0dSWei Fang 	err = enetc_mdiobus_create(pf, node);
59399100d0dSWei Fang 	if (err) {
59499100d0dSWei Fang 		dev_err(dev, "Failed to create MDIO bus\n");
59599100d0dSWei Fang 		return err;
59699100d0dSWei Fang 	}
59799100d0dSWei Fang 
59899100d0dSWei Fang 	err = enetc_phylink_create(priv, node, &enetc_pl_mac_ops);
59999100d0dSWei Fang 	if (err) {
60099100d0dSWei Fang 		dev_err(dev, "Failed to create phylink\n");
60199100d0dSWei Fang 		goto err_phylink_create;
60299100d0dSWei Fang 	}
60399100d0dSWei Fang 
60499100d0dSWei Fang 	return 0;
60599100d0dSWei Fang 
60699100d0dSWei Fang err_phylink_create:
60799100d0dSWei Fang 	enetc_mdiobus_destroy(pf);
60899100d0dSWei Fang 
60999100d0dSWei Fang 	return err;
61099100d0dSWei Fang }
61199100d0dSWei Fang 
61299100d0dSWei Fang static void enetc4_link_deinit(struct enetc_ndev_priv *priv)
61399100d0dSWei Fang {
61499100d0dSWei Fang 	struct enetc_pf *pf = enetc_si_priv(priv->si);
61599100d0dSWei Fang 
61699100d0dSWei Fang 	enetc_phylink_destroy(priv);
61799100d0dSWei Fang 	enetc_mdiobus_destroy(pf);
61899100d0dSWei Fang }
61999100d0dSWei Fang 
62099100d0dSWei Fang static int enetc4_pf_netdev_create(struct enetc_si *si)
62199100d0dSWei Fang {
62299100d0dSWei Fang 	struct device *dev = &si->pdev->dev;
62399100d0dSWei Fang 	struct enetc_ndev_priv *priv;
62499100d0dSWei Fang 	struct net_device *ndev;
62599100d0dSWei Fang 	int err;
62699100d0dSWei Fang 
62799100d0dSWei Fang 	ndev = alloc_etherdev_mqs(sizeof(struct enetc_ndev_priv),
62899100d0dSWei Fang 				  si->num_tx_rings, si->num_rx_rings);
62999100d0dSWei Fang 	if (!ndev)
63099100d0dSWei Fang 		return  -ENOMEM;
63199100d0dSWei Fang 
63299100d0dSWei Fang 	priv = netdev_priv(ndev);
63399100d0dSWei Fang 	priv->ref_clk = devm_clk_get_optional(dev, "ref");
63499100d0dSWei Fang 	if (IS_ERR(priv->ref_clk)) {
6354f19c824SColin Ian King 		dev_err(dev, "Get reference clock failed\n");
63699100d0dSWei Fang 		err = PTR_ERR(priv->ref_clk);
63799100d0dSWei Fang 		goto err_clk_get;
63899100d0dSWei Fang 	}
63999100d0dSWei Fang 
64099100d0dSWei Fang 	enetc_pf_netdev_setup(si, ndev, &enetc4_ndev_ops);
64199100d0dSWei Fang 
64299100d0dSWei Fang 	enetc_init_si_rings_params(priv);
64399100d0dSWei Fang 
64499100d0dSWei Fang 	err = enetc_configure_si(priv);
64599100d0dSWei Fang 	if (err) {
64699100d0dSWei Fang 		dev_err(dev, "Failed to configure SI\n");
64799100d0dSWei Fang 		goto err_config_si;
64899100d0dSWei Fang 	}
64999100d0dSWei Fang 
65099100d0dSWei Fang 	err = enetc_alloc_msix(priv);
65199100d0dSWei Fang 	if (err) {
65299100d0dSWei Fang 		dev_err(dev, "Failed to alloc MSI-X\n");
65399100d0dSWei Fang 		goto err_alloc_msix;
65499100d0dSWei Fang 	}
65599100d0dSWei Fang 
65699100d0dSWei Fang 	err = enetc4_link_init(priv, dev->of_node);
65799100d0dSWei Fang 	if (err)
65899100d0dSWei Fang 		goto err_link_init;
65999100d0dSWei Fang 
66099100d0dSWei Fang 	err = register_netdev(ndev);
66199100d0dSWei Fang 	if (err) {
66299100d0dSWei Fang 		dev_err(dev, "Failed to register netdev\n");
66399100d0dSWei Fang 		goto err_reg_netdev;
66499100d0dSWei Fang 	}
66599100d0dSWei Fang 
66699100d0dSWei Fang 	return 0;
66799100d0dSWei Fang 
66899100d0dSWei Fang err_reg_netdev:
66999100d0dSWei Fang 	enetc4_link_deinit(priv);
67099100d0dSWei Fang err_link_init:
67199100d0dSWei Fang 	enetc_free_msix(priv);
67299100d0dSWei Fang err_alloc_msix:
67399100d0dSWei Fang err_config_si:
67499100d0dSWei Fang err_clk_get:
67599100d0dSWei Fang 	free_netdev(ndev);
67699100d0dSWei Fang 
67799100d0dSWei Fang 	return err;
67899100d0dSWei Fang }
67999100d0dSWei Fang 
68099100d0dSWei Fang static void enetc4_pf_netdev_destroy(struct enetc_si *si)
68199100d0dSWei Fang {
68299100d0dSWei Fang 	struct enetc_ndev_priv *priv = netdev_priv(si->ndev);
68399100d0dSWei Fang 	struct net_device *ndev = si->ndev;
68499100d0dSWei Fang 
68599100d0dSWei Fang 	unregister_netdev(ndev);
686*8e43decdSWei Fang 	enetc4_link_deinit(priv);
68799100d0dSWei Fang 	enetc_free_msix(priv);
68899100d0dSWei Fang 	free_netdev(ndev);
68999100d0dSWei Fang }
69099100d0dSWei Fang 
69199100d0dSWei Fang static int enetc4_pf_probe(struct pci_dev *pdev,
69299100d0dSWei Fang 			   const struct pci_device_id *ent)
69399100d0dSWei Fang {
69499100d0dSWei Fang 	struct device *dev = &pdev->dev;
69599100d0dSWei Fang 	struct enetc_si *si;
69699100d0dSWei Fang 	struct enetc_pf *pf;
69799100d0dSWei Fang 	int err;
69899100d0dSWei Fang 
69999100d0dSWei Fang 	err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(*pf));
70099100d0dSWei Fang 	if (err)
70199100d0dSWei Fang 		return dev_err_probe(dev, err, "PCIe probing failed\n");
70299100d0dSWei Fang 
70399100d0dSWei Fang 	err = devm_add_action_or_reset(dev, enetc4_pci_remove, pdev);
70499100d0dSWei Fang 	if (err)
70599100d0dSWei Fang 		return dev_err_probe(dev, err,
70699100d0dSWei Fang 				     "Add enetc4_pci_remove() action failed\n");
70799100d0dSWei Fang 
70899100d0dSWei Fang 	/* si is the private data. */
70999100d0dSWei Fang 	si = pci_get_drvdata(pdev);
71099100d0dSWei Fang 	if (!si->hw.port || !si->hw.global)
71199100d0dSWei Fang 		return dev_err_probe(dev, -ENODEV,
71299100d0dSWei Fang 				     "Couldn't map PF only space\n");
71399100d0dSWei Fang 
71499100d0dSWei Fang 	si->revision = enetc_get_ip_revision(&si->hw);
71599100d0dSWei Fang 	err = enetc_get_driver_data(si);
71699100d0dSWei Fang 	if (err)
71799100d0dSWei Fang 		return dev_err_probe(dev, err,
71899100d0dSWei Fang 				     "Could not get VF driver data\n");
71999100d0dSWei Fang 
72099100d0dSWei Fang 	err = enetc4_pf_struct_init(si);
72199100d0dSWei Fang 	if (err)
72299100d0dSWei Fang 		return err;
72399100d0dSWei Fang 
72499100d0dSWei Fang 	pf = enetc_si_priv(si);
72599100d0dSWei Fang 	err = enetc4_pf_init(pf);
72699100d0dSWei Fang 	if (err)
72799100d0dSWei Fang 		return err;
72899100d0dSWei Fang 
72999100d0dSWei Fang 	enetc_get_si_caps(si);
73099100d0dSWei Fang 
73199100d0dSWei Fang 	return enetc4_pf_netdev_create(si);
73299100d0dSWei Fang }
73399100d0dSWei Fang 
73499100d0dSWei Fang static void enetc4_pf_remove(struct pci_dev *pdev)
73599100d0dSWei Fang {
73699100d0dSWei Fang 	struct enetc_si *si = pci_get_drvdata(pdev);
73799100d0dSWei Fang 
73899100d0dSWei Fang 	enetc4_pf_netdev_destroy(si);
73999100d0dSWei Fang }
74099100d0dSWei Fang 
74199100d0dSWei Fang static const struct pci_device_id enetc4_pf_id_table[] = {
74299100d0dSWei Fang 	{ PCI_DEVICE(NXP_ENETC_VENDOR_ID, NXP_ENETC_PF_DEV_ID) },
74399100d0dSWei Fang 	{ 0, } /* End of table. */
74499100d0dSWei Fang };
74599100d0dSWei Fang MODULE_DEVICE_TABLE(pci, enetc4_pf_id_table);
74699100d0dSWei Fang 
74799100d0dSWei Fang static struct pci_driver enetc4_pf_driver = {
74899100d0dSWei Fang 	.name = KBUILD_MODNAME,
74999100d0dSWei Fang 	.id_table = enetc4_pf_id_table,
75099100d0dSWei Fang 	.probe = enetc4_pf_probe,
75199100d0dSWei Fang 	.remove = enetc4_pf_remove,
75299100d0dSWei Fang };
75399100d0dSWei Fang module_pci_driver(enetc4_pf_driver);
75499100d0dSWei Fang 
75599100d0dSWei Fang MODULE_DESCRIPTION("ENETC4 PF Driver");
75699100d0dSWei Fang MODULE_LICENSE("Dual BSD/GPL");
757