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