158da0cfaSVoon Weifeng // SPDX-License-Identifier: GPL-2.0 258da0cfaSVoon Weifeng /* Copyright (c) 2020, Intel Corporation 358da0cfaSVoon Weifeng */ 458da0cfaSVoon Weifeng 558da0cfaSVoon Weifeng #include <linux/clk-provider.h> 658da0cfaSVoon Weifeng #include <linux/pci.h> 758da0cfaSVoon Weifeng #include <linux/dmi.h> 8*b9663b7cSVoon Weifeng #include "dwmac-intel.h" 958da0cfaSVoon Weifeng #include "stmmac.h" 1058da0cfaSVoon Weifeng 11*b9663b7cSVoon Weifeng struct intel_priv_data { 12*b9663b7cSVoon Weifeng int mdio_adhoc_addr; /* mdio address for serdes & etc */ 13*b9663b7cSVoon Weifeng }; 14*b9663b7cSVoon Weifeng 1558da0cfaSVoon Weifeng /* This struct is used to associate PCI Function of MAC controller on a board, 1658da0cfaSVoon Weifeng * discovered via DMI, with the address of PHY connected to the MAC. The 1758da0cfaSVoon Weifeng * negative value of the address means that MAC controller is not connected 1858da0cfaSVoon Weifeng * with PHY. 1958da0cfaSVoon Weifeng */ 2058da0cfaSVoon Weifeng struct stmmac_pci_func_data { 2158da0cfaSVoon Weifeng unsigned int func; 2258da0cfaSVoon Weifeng int phy_addr; 2358da0cfaSVoon Weifeng }; 2458da0cfaSVoon Weifeng 2558da0cfaSVoon Weifeng struct stmmac_pci_dmi_data { 2658da0cfaSVoon Weifeng const struct stmmac_pci_func_data *func; 2758da0cfaSVoon Weifeng size_t nfuncs; 2858da0cfaSVoon Weifeng }; 2958da0cfaSVoon Weifeng 3058da0cfaSVoon Weifeng struct stmmac_pci_info { 3158da0cfaSVoon Weifeng int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat); 3258da0cfaSVoon Weifeng }; 3358da0cfaSVoon Weifeng 3458da0cfaSVoon Weifeng static int stmmac_pci_find_phy_addr(struct pci_dev *pdev, 3558da0cfaSVoon Weifeng const struct dmi_system_id *dmi_list) 3658da0cfaSVoon Weifeng { 3758da0cfaSVoon Weifeng const struct stmmac_pci_func_data *func_data; 3858da0cfaSVoon Weifeng const struct stmmac_pci_dmi_data *dmi_data; 3958da0cfaSVoon Weifeng const struct dmi_system_id *dmi_id; 4058da0cfaSVoon Weifeng int func = PCI_FUNC(pdev->devfn); 4158da0cfaSVoon Weifeng size_t n; 4258da0cfaSVoon Weifeng 4358da0cfaSVoon Weifeng dmi_id = dmi_first_match(dmi_list); 4458da0cfaSVoon Weifeng if (!dmi_id) 4558da0cfaSVoon Weifeng return -ENODEV; 4658da0cfaSVoon Weifeng 4758da0cfaSVoon Weifeng dmi_data = dmi_id->driver_data; 4858da0cfaSVoon Weifeng func_data = dmi_data->func; 4958da0cfaSVoon Weifeng 5058da0cfaSVoon Weifeng for (n = 0; n < dmi_data->nfuncs; n++, func_data++) 5158da0cfaSVoon Weifeng if (func_data->func == func) 5258da0cfaSVoon Weifeng return func_data->phy_addr; 5358da0cfaSVoon Weifeng 5458da0cfaSVoon Weifeng return -ENODEV; 5558da0cfaSVoon Weifeng } 5658da0cfaSVoon Weifeng 57*b9663b7cSVoon Weifeng static int serdes_status_poll(struct stmmac_priv *priv, int phyaddr, 58*b9663b7cSVoon Weifeng int phyreg, u32 mask, u32 val) 59*b9663b7cSVoon Weifeng { 60*b9663b7cSVoon Weifeng unsigned int retries = 10; 61*b9663b7cSVoon Weifeng int val_rd; 62*b9663b7cSVoon Weifeng 63*b9663b7cSVoon Weifeng do { 64*b9663b7cSVoon Weifeng val_rd = mdiobus_read(priv->mii, phyaddr, phyreg); 65*b9663b7cSVoon Weifeng if ((val_rd & mask) == (val & mask)) 66*b9663b7cSVoon Weifeng return 0; 67*b9663b7cSVoon Weifeng udelay(POLL_DELAY_US); 68*b9663b7cSVoon Weifeng } while (--retries); 69*b9663b7cSVoon Weifeng 70*b9663b7cSVoon Weifeng return -ETIMEDOUT; 71*b9663b7cSVoon Weifeng } 72*b9663b7cSVoon Weifeng 73*b9663b7cSVoon Weifeng static int intel_serdes_powerup(struct net_device *ndev, void *priv_data) 74*b9663b7cSVoon Weifeng { 75*b9663b7cSVoon Weifeng struct intel_priv_data *intel_priv = priv_data; 76*b9663b7cSVoon Weifeng struct stmmac_priv *priv = netdev_priv(ndev); 77*b9663b7cSVoon Weifeng int serdes_phy_addr = 0; 78*b9663b7cSVoon Weifeng u32 data = 0; 79*b9663b7cSVoon Weifeng 80*b9663b7cSVoon Weifeng if (!intel_priv->mdio_adhoc_addr) 81*b9663b7cSVoon Weifeng return 0; 82*b9663b7cSVoon Weifeng 83*b9663b7cSVoon Weifeng serdes_phy_addr = intel_priv->mdio_adhoc_addr; 84*b9663b7cSVoon Weifeng 85*b9663b7cSVoon Weifeng /* assert clk_req */ 86*b9663b7cSVoon Weifeng data = mdiobus_read(priv->mii, serdes_phy_addr, 87*b9663b7cSVoon Weifeng SERDES_GCR0); 88*b9663b7cSVoon Weifeng 89*b9663b7cSVoon Weifeng data |= SERDES_PLL_CLK; 90*b9663b7cSVoon Weifeng 91*b9663b7cSVoon Weifeng mdiobus_write(priv->mii, serdes_phy_addr, 92*b9663b7cSVoon Weifeng SERDES_GCR0, data); 93*b9663b7cSVoon Weifeng 94*b9663b7cSVoon Weifeng /* check for clk_ack assertion */ 95*b9663b7cSVoon Weifeng data = serdes_status_poll(priv, serdes_phy_addr, 96*b9663b7cSVoon Weifeng SERDES_GSR0, 97*b9663b7cSVoon Weifeng SERDES_PLL_CLK, 98*b9663b7cSVoon Weifeng SERDES_PLL_CLK); 99*b9663b7cSVoon Weifeng 100*b9663b7cSVoon Weifeng if (data) { 101*b9663b7cSVoon Weifeng dev_err(priv->device, "Serdes PLL clk request timeout\n"); 102*b9663b7cSVoon Weifeng return data; 103*b9663b7cSVoon Weifeng } 104*b9663b7cSVoon Weifeng 105*b9663b7cSVoon Weifeng /* assert lane reset */ 106*b9663b7cSVoon Weifeng data = mdiobus_read(priv->mii, serdes_phy_addr, 107*b9663b7cSVoon Weifeng SERDES_GCR0); 108*b9663b7cSVoon Weifeng 109*b9663b7cSVoon Weifeng data |= SERDES_RST; 110*b9663b7cSVoon Weifeng 111*b9663b7cSVoon Weifeng mdiobus_write(priv->mii, serdes_phy_addr, 112*b9663b7cSVoon Weifeng SERDES_GCR0, data); 113*b9663b7cSVoon Weifeng 114*b9663b7cSVoon Weifeng /* check for assert lane reset reflection */ 115*b9663b7cSVoon Weifeng data = serdes_status_poll(priv, serdes_phy_addr, 116*b9663b7cSVoon Weifeng SERDES_GSR0, 117*b9663b7cSVoon Weifeng SERDES_RST, 118*b9663b7cSVoon Weifeng SERDES_RST); 119*b9663b7cSVoon Weifeng 120*b9663b7cSVoon Weifeng if (data) { 121*b9663b7cSVoon Weifeng dev_err(priv->device, "Serdes assert lane reset timeout\n"); 122*b9663b7cSVoon Weifeng return data; 123*b9663b7cSVoon Weifeng } 124*b9663b7cSVoon Weifeng 125*b9663b7cSVoon Weifeng /* move power state to P0 */ 126*b9663b7cSVoon Weifeng data = mdiobus_read(priv->mii, serdes_phy_addr, 127*b9663b7cSVoon Weifeng SERDES_GCR0); 128*b9663b7cSVoon Weifeng 129*b9663b7cSVoon Weifeng data &= ~SERDES_PWR_ST_MASK; 130*b9663b7cSVoon Weifeng data |= SERDES_PWR_ST_P0 << SERDES_PWR_ST_SHIFT; 131*b9663b7cSVoon Weifeng 132*b9663b7cSVoon Weifeng mdiobus_write(priv->mii, serdes_phy_addr, 133*b9663b7cSVoon Weifeng SERDES_GCR0, data); 134*b9663b7cSVoon Weifeng 135*b9663b7cSVoon Weifeng /* Check for P0 state */ 136*b9663b7cSVoon Weifeng data = serdes_status_poll(priv, serdes_phy_addr, 137*b9663b7cSVoon Weifeng SERDES_GSR0, 138*b9663b7cSVoon Weifeng SERDES_PWR_ST_MASK, 139*b9663b7cSVoon Weifeng SERDES_PWR_ST_P0 << SERDES_PWR_ST_SHIFT); 140*b9663b7cSVoon Weifeng 141*b9663b7cSVoon Weifeng if (data) { 142*b9663b7cSVoon Weifeng dev_err(priv->device, "Serdes power state P0 timeout.\n"); 143*b9663b7cSVoon Weifeng return data; 144*b9663b7cSVoon Weifeng } 145*b9663b7cSVoon Weifeng 146*b9663b7cSVoon Weifeng return 0; 147*b9663b7cSVoon Weifeng } 148*b9663b7cSVoon Weifeng 149*b9663b7cSVoon Weifeng static void intel_serdes_powerdown(struct net_device *ndev, void *intel_data) 150*b9663b7cSVoon Weifeng { 151*b9663b7cSVoon Weifeng struct intel_priv_data *intel_priv = intel_data; 152*b9663b7cSVoon Weifeng struct stmmac_priv *priv = netdev_priv(ndev); 153*b9663b7cSVoon Weifeng int serdes_phy_addr = 0; 154*b9663b7cSVoon Weifeng u32 data = 0; 155*b9663b7cSVoon Weifeng 156*b9663b7cSVoon Weifeng if (!intel_priv->mdio_adhoc_addr) 157*b9663b7cSVoon Weifeng return; 158*b9663b7cSVoon Weifeng 159*b9663b7cSVoon Weifeng serdes_phy_addr = intel_priv->mdio_adhoc_addr; 160*b9663b7cSVoon Weifeng 161*b9663b7cSVoon Weifeng /* move power state to P3 */ 162*b9663b7cSVoon Weifeng data = mdiobus_read(priv->mii, serdes_phy_addr, 163*b9663b7cSVoon Weifeng SERDES_GCR0); 164*b9663b7cSVoon Weifeng 165*b9663b7cSVoon Weifeng data &= ~SERDES_PWR_ST_MASK; 166*b9663b7cSVoon Weifeng data |= SERDES_PWR_ST_P3 << SERDES_PWR_ST_SHIFT; 167*b9663b7cSVoon Weifeng 168*b9663b7cSVoon Weifeng mdiobus_write(priv->mii, serdes_phy_addr, 169*b9663b7cSVoon Weifeng SERDES_GCR0, data); 170*b9663b7cSVoon Weifeng 171*b9663b7cSVoon Weifeng /* Check for P3 state */ 172*b9663b7cSVoon Weifeng data = serdes_status_poll(priv, serdes_phy_addr, 173*b9663b7cSVoon Weifeng SERDES_GSR0, 174*b9663b7cSVoon Weifeng SERDES_PWR_ST_MASK, 175*b9663b7cSVoon Weifeng SERDES_PWR_ST_P3 << SERDES_PWR_ST_SHIFT); 176*b9663b7cSVoon Weifeng 177*b9663b7cSVoon Weifeng if (data) { 178*b9663b7cSVoon Weifeng dev_err(priv->device, "Serdes power state P3 timeout\n"); 179*b9663b7cSVoon Weifeng return; 180*b9663b7cSVoon Weifeng } 181*b9663b7cSVoon Weifeng 182*b9663b7cSVoon Weifeng /* de-assert clk_req */ 183*b9663b7cSVoon Weifeng data = mdiobus_read(priv->mii, serdes_phy_addr, 184*b9663b7cSVoon Weifeng SERDES_GCR0); 185*b9663b7cSVoon Weifeng 186*b9663b7cSVoon Weifeng data &= ~SERDES_PLL_CLK; 187*b9663b7cSVoon Weifeng 188*b9663b7cSVoon Weifeng mdiobus_write(priv->mii, serdes_phy_addr, 189*b9663b7cSVoon Weifeng SERDES_GCR0, data); 190*b9663b7cSVoon Weifeng 191*b9663b7cSVoon Weifeng /* check for clk_ack de-assert */ 192*b9663b7cSVoon Weifeng data = serdes_status_poll(priv, serdes_phy_addr, 193*b9663b7cSVoon Weifeng SERDES_GSR0, 194*b9663b7cSVoon Weifeng SERDES_PLL_CLK, 195*b9663b7cSVoon Weifeng (u32)~SERDES_PLL_CLK); 196*b9663b7cSVoon Weifeng 197*b9663b7cSVoon Weifeng if (data) { 198*b9663b7cSVoon Weifeng dev_err(priv->device, "Serdes PLL clk de-assert timeout\n"); 199*b9663b7cSVoon Weifeng return; 200*b9663b7cSVoon Weifeng } 201*b9663b7cSVoon Weifeng 202*b9663b7cSVoon Weifeng /* de-assert lane reset */ 203*b9663b7cSVoon Weifeng data = mdiobus_read(priv->mii, serdes_phy_addr, 204*b9663b7cSVoon Weifeng SERDES_GCR0); 205*b9663b7cSVoon Weifeng 206*b9663b7cSVoon Weifeng data &= ~SERDES_RST; 207*b9663b7cSVoon Weifeng 208*b9663b7cSVoon Weifeng mdiobus_write(priv->mii, serdes_phy_addr, 209*b9663b7cSVoon Weifeng SERDES_GCR0, data); 210*b9663b7cSVoon Weifeng 211*b9663b7cSVoon Weifeng /* check for de-assert lane reset reflection */ 212*b9663b7cSVoon Weifeng data = serdes_status_poll(priv, serdes_phy_addr, 213*b9663b7cSVoon Weifeng SERDES_GSR0, 214*b9663b7cSVoon Weifeng SERDES_RST, 215*b9663b7cSVoon Weifeng (u32)~SERDES_RST); 216*b9663b7cSVoon Weifeng 217*b9663b7cSVoon Weifeng if (data) { 218*b9663b7cSVoon Weifeng dev_err(priv->device, "Serdes de-assert lane reset timeout\n"); 219*b9663b7cSVoon Weifeng return; 220*b9663b7cSVoon Weifeng } 221*b9663b7cSVoon Weifeng } 222*b9663b7cSVoon Weifeng 22358da0cfaSVoon Weifeng static void common_default_data(struct plat_stmmacenet_data *plat) 22458da0cfaSVoon Weifeng { 22558da0cfaSVoon Weifeng plat->clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ 22658da0cfaSVoon Weifeng plat->has_gmac = 1; 22758da0cfaSVoon Weifeng plat->force_sf_dma_mode = 1; 22858da0cfaSVoon Weifeng 22958da0cfaSVoon Weifeng plat->mdio_bus_data->needs_reset = true; 23058da0cfaSVoon Weifeng 23158da0cfaSVoon Weifeng /* Set default value for multicast hash bins */ 23258da0cfaSVoon Weifeng plat->multicast_filter_bins = HASH_TABLE_SIZE; 23358da0cfaSVoon Weifeng 23458da0cfaSVoon Weifeng /* Set default value for unicast filter entries */ 23558da0cfaSVoon Weifeng plat->unicast_filter_entries = 1; 23658da0cfaSVoon Weifeng 23758da0cfaSVoon Weifeng /* Set the maxmtu to a default of JUMBO_LEN */ 23858da0cfaSVoon Weifeng plat->maxmtu = JUMBO_LEN; 23958da0cfaSVoon Weifeng 24058da0cfaSVoon Weifeng /* Set default number of RX and TX queues to use */ 24158da0cfaSVoon Weifeng plat->tx_queues_to_use = 1; 24258da0cfaSVoon Weifeng plat->rx_queues_to_use = 1; 24358da0cfaSVoon Weifeng 24458da0cfaSVoon Weifeng /* Disable Priority config by default */ 24558da0cfaSVoon Weifeng plat->tx_queues_cfg[0].use_prio = false; 24658da0cfaSVoon Weifeng plat->rx_queues_cfg[0].use_prio = false; 24758da0cfaSVoon Weifeng 24858da0cfaSVoon Weifeng /* Disable RX queues routing by default */ 24958da0cfaSVoon Weifeng plat->rx_queues_cfg[0].pkt_route = 0x0; 25058da0cfaSVoon Weifeng } 25158da0cfaSVoon Weifeng 25258da0cfaSVoon Weifeng static int intel_mgbe_common_data(struct pci_dev *pdev, 25358da0cfaSVoon Weifeng struct plat_stmmacenet_data *plat) 25458da0cfaSVoon Weifeng { 25558da0cfaSVoon Weifeng int i; 25658da0cfaSVoon Weifeng 25758da0cfaSVoon Weifeng plat->clk_csr = 5; 25858da0cfaSVoon Weifeng plat->has_gmac = 0; 25958da0cfaSVoon Weifeng plat->has_gmac4 = 1; 26058da0cfaSVoon Weifeng plat->force_sf_dma_mode = 0; 26158da0cfaSVoon Weifeng plat->tso_en = 1; 26258da0cfaSVoon Weifeng 26358da0cfaSVoon Weifeng plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP; 26458da0cfaSVoon Weifeng 26558da0cfaSVoon Weifeng for (i = 0; i < plat->rx_queues_to_use; i++) { 26658da0cfaSVoon Weifeng plat->rx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB; 26758da0cfaSVoon Weifeng plat->rx_queues_cfg[i].chan = i; 26858da0cfaSVoon Weifeng 26958da0cfaSVoon Weifeng /* Disable Priority config by default */ 27058da0cfaSVoon Weifeng plat->rx_queues_cfg[i].use_prio = false; 27158da0cfaSVoon Weifeng 27258da0cfaSVoon Weifeng /* Disable RX queues routing by default */ 27358da0cfaSVoon Weifeng plat->rx_queues_cfg[i].pkt_route = 0x0; 27458da0cfaSVoon Weifeng } 27558da0cfaSVoon Weifeng 27658da0cfaSVoon Weifeng for (i = 0; i < plat->tx_queues_to_use; i++) { 27758da0cfaSVoon Weifeng plat->tx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB; 27858da0cfaSVoon Weifeng 27958da0cfaSVoon Weifeng /* Disable Priority config by default */ 28058da0cfaSVoon Weifeng plat->tx_queues_cfg[i].use_prio = false; 28158da0cfaSVoon Weifeng } 28258da0cfaSVoon Weifeng 28358da0cfaSVoon Weifeng /* FIFO size is 4096 bytes for 1 tx/rx queue */ 28458da0cfaSVoon Weifeng plat->tx_fifo_size = plat->tx_queues_to_use * 4096; 28558da0cfaSVoon Weifeng plat->rx_fifo_size = plat->rx_queues_to_use * 4096; 28658da0cfaSVoon Weifeng 28758da0cfaSVoon Weifeng plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WRR; 28858da0cfaSVoon Weifeng plat->tx_queues_cfg[0].weight = 0x09; 28958da0cfaSVoon Weifeng plat->tx_queues_cfg[1].weight = 0x0A; 29058da0cfaSVoon Weifeng plat->tx_queues_cfg[2].weight = 0x0B; 29158da0cfaSVoon Weifeng plat->tx_queues_cfg[3].weight = 0x0C; 29258da0cfaSVoon Weifeng plat->tx_queues_cfg[4].weight = 0x0D; 29358da0cfaSVoon Weifeng plat->tx_queues_cfg[5].weight = 0x0E; 29458da0cfaSVoon Weifeng plat->tx_queues_cfg[6].weight = 0x0F; 29558da0cfaSVoon Weifeng plat->tx_queues_cfg[7].weight = 0x10; 29658da0cfaSVoon Weifeng 29758da0cfaSVoon Weifeng plat->dma_cfg->pbl = 32; 29858da0cfaSVoon Weifeng plat->dma_cfg->pblx8 = true; 29958da0cfaSVoon Weifeng plat->dma_cfg->fixed_burst = 0; 30058da0cfaSVoon Weifeng plat->dma_cfg->mixed_burst = 0; 30158da0cfaSVoon Weifeng plat->dma_cfg->aal = 0; 30258da0cfaSVoon Weifeng 30358da0cfaSVoon Weifeng plat->axi = devm_kzalloc(&pdev->dev, sizeof(*plat->axi), 30458da0cfaSVoon Weifeng GFP_KERNEL); 30558da0cfaSVoon Weifeng if (!plat->axi) 30658da0cfaSVoon Weifeng return -ENOMEM; 30758da0cfaSVoon Weifeng 30858da0cfaSVoon Weifeng plat->axi->axi_lpi_en = 0; 30958da0cfaSVoon Weifeng plat->axi->axi_xit_frm = 0; 31058da0cfaSVoon Weifeng plat->axi->axi_wr_osr_lmt = 1; 31158da0cfaSVoon Weifeng plat->axi->axi_rd_osr_lmt = 1; 31258da0cfaSVoon Weifeng plat->axi->axi_blen[0] = 4; 31358da0cfaSVoon Weifeng plat->axi->axi_blen[1] = 8; 31458da0cfaSVoon Weifeng plat->axi->axi_blen[2] = 16; 31558da0cfaSVoon Weifeng 31658da0cfaSVoon Weifeng plat->ptp_max_adj = plat->clk_ptp_rate; 31758da0cfaSVoon Weifeng 31858da0cfaSVoon Weifeng /* Set system clock */ 31958da0cfaSVoon Weifeng plat->stmmac_clk = clk_register_fixed_rate(&pdev->dev, 32058da0cfaSVoon Weifeng "stmmac-clk", NULL, 0, 32158da0cfaSVoon Weifeng plat->clk_ptp_rate); 32258da0cfaSVoon Weifeng 32358da0cfaSVoon Weifeng if (IS_ERR(plat->stmmac_clk)) { 32458da0cfaSVoon Weifeng dev_warn(&pdev->dev, "Fail to register stmmac-clk\n"); 32558da0cfaSVoon Weifeng plat->stmmac_clk = NULL; 32658da0cfaSVoon Weifeng } 32758da0cfaSVoon Weifeng clk_prepare_enable(plat->stmmac_clk); 32858da0cfaSVoon Weifeng 32958da0cfaSVoon Weifeng /* Set default value for multicast hash bins */ 33058da0cfaSVoon Weifeng plat->multicast_filter_bins = HASH_TABLE_SIZE; 33158da0cfaSVoon Weifeng 33258da0cfaSVoon Weifeng /* Set default value for unicast filter entries */ 33358da0cfaSVoon Weifeng plat->unicast_filter_entries = 1; 33458da0cfaSVoon Weifeng 33558da0cfaSVoon Weifeng /* Set the maxmtu to a default of JUMBO_LEN */ 33658da0cfaSVoon Weifeng plat->maxmtu = JUMBO_LEN; 33758da0cfaSVoon Weifeng 33858da0cfaSVoon Weifeng return 0; 33958da0cfaSVoon Weifeng } 34058da0cfaSVoon Weifeng 34158da0cfaSVoon Weifeng static int ehl_common_data(struct pci_dev *pdev, 34258da0cfaSVoon Weifeng struct plat_stmmacenet_data *plat) 34358da0cfaSVoon Weifeng { 34458da0cfaSVoon Weifeng int ret; 34558da0cfaSVoon Weifeng 34658da0cfaSVoon Weifeng plat->rx_queues_to_use = 8; 34758da0cfaSVoon Weifeng plat->tx_queues_to_use = 8; 34858da0cfaSVoon Weifeng plat->clk_ptp_rate = 200000000; 34958da0cfaSVoon Weifeng ret = intel_mgbe_common_data(pdev, plat); 35058da0cfaSVoon Weifeng if (ret) 35158da0cfaSVoon Weifeng return ret; 35258da0cfaSVoon Weifeng 35358da0cfaSVoon Weifeng return 0; 35458da0cfaSVoon Weifeng } 35558da0cfaSVoon Weifeng 35658da0cfaSVoon Weifeng static int ehl_sgmii_data(struct pci_dev *pdev, 35758da0cfaSVoon Weifeng struct plat_stmmacenet_data *plat) 35858da0cfaSVoon Weifeng { 35958da0cfaSVoon Weifeng plat->bus_id = 1; 36058da0cfaSVoon Weifeng plat->phy_addr = 0; 36158da0cfaSVoon Weifeng plat->phy_interface = PHY_INTERFACE_MODE_SGMII; 36258da0cfaSVoon Weifeng 363*b9663b7cSVoon Weifeng plat->serdes_powerup = intel_serdes_powerup; 364*b9663b7cSVoon Weifeng plat->serdes_powerdown = intel_serdes_powerdown; 365*b9663b7cSVoon Weifeng 36658da0cfaSVoon Weifeng return ehl_common_data(pdev, plat); 36758da0cfaSVoon Weifeng } 36858da0cfaSVoon Weifeng 36958da0cfaSVoon Weifeng static struct stmmac_pci_info ehl_sgmii1g_pci_info = { 37058da0cfaSVoon Weifeng .setup = ehl_sgmii_data, 37158da0cfaSVoon Weifeng }; 37258da0cfaSVoon Weifeng 37358da0cfaSVoon Weifeng static int ehl_rgmii_data(struct pci_dev *pdev, 37458da0cfaSVoon Weifeng struct plat_stmmacenet_data *plat) 37558da0cfaSVoon Weifeng { 37658da0cfaSVoon Weifeng plat->bus_id = 1; 37758da0cfaSVoon Weifeng plat->phy_addr = 0; 37858da0cfaSVoon Weifeng plat->phy_interface = PHY_INTERFACE_MODE_RGMII; 37958da0cfaSVoon Weifeng 38058da0cfaSVoon Weifeng return ehl_common_data(pdev, plat); 38158da0cfaSVoon Weifeng } 38258da0cfaSVoon Weifeng 38358da0cfaSVoon Weifeng static struct stmmac_pci_info ehl_rgmii1g_pci_info = { 38458da0cfaSVoon Weifeng .setup = ehl_rgmii_data, 38558da0cfaSVoon Weifeng }; 38658da0cfaSVoon Weifeng 38767c08ac4SVoon Weifeng static int ehl_pse0_common_data(struct pci_dev *pdev, 38867c08ac4SVoon Weifeng struct plat_stmmacenet_data *plat) 38967c08ac4SVoon Weifeng { 39067c08ac4SVoon Weifeng plat->bus_id = 2; 39167c08ac4SVoon Weifeng plat->phy_addr = 1; 39267c08ac4SVoon Weifeng return ehl_common_data(pdev, plat); 39367c08ac4SVoon Weifeng } 39467c08ac4SVoon Weifeng 39567c08ac4SVoon Weifeng static int ehl_pse0_rgmii1g_data(struct pci_dev *pdev, 39667c08ac4SVoon Weifeng struct plat_stmmacenet_data *plat) 39767c08ac4SVoon Weifeng { 39867c08ac4SVoon Weifeng plat->phy_interface = PHY_INTERFACE_MODE_RGMII_ID; 39967c08ac4SVoon Weifeng return ehl_pse0_common_data(pdev, plat); 40067c08ac4SVoon Weifeng } 40167c08ac4SVoon Weifeng 40267c08ac4SVoon Weifeng static struct stmmac_pci_info ehl_pse0_rgmii1g_pci_info = { 40367c08ac4SVoon Weifeng .setup = ehl_pse0_rgmii1g_data, 40467c08ac4SVoon Weifeng }; 40567c08ac4SVoon Weifeng 40667c08ac4SVoon Weifeng static int ehl_pse0_sgmii1g_data(struct pci_dev *pdev, 40767c08ac4SVoon Weifeng struct plat_stmmacenet_data *plat) 40867c08ac4SVoon Weifeng { 40967c08ac4SVoon Weifeng plat->phy_interface = PHY_INTERFACE_MODE_SGMII; 410*b9663b7cSVoon Weifeng plat->serdes_powerup = intel_serdes_powerup; 411*b9663b7cSVoon Weifeng plat->serdes_powerdown = intel_serdes_powerdown; 41267c08ac4SVoon Weifeng return ehl_pse0_common_data(pdev, plat); 41367c08ac4SVoon Weifeng } 41467c08ac4SVoon Weifeng 41567c08ac4SVoon Weifeng static struct stmmac_pci_info ehl_pse0_sgmii1g_pci_info = { 41667c08ac4SVoon Weifeng .setup = ehl_pse0_sgmii1g_data, 41767c08ac4SVoon Weifeng }; 41867c08ac4SVoon Weifeng 41967c08ac4SVoon Weifeng static int ehl_pse1_common_data(struct pci_dev *pdev, 42067c08ac4SVoon Weifeng struct plat_stmmacenet_data *plat) 42167c08ac4SVoon Weifeng { 42267c08ac4SVoon Weifeng plat->bus_id = 3; 42367c08ac4SVoon Weifeng plat->phy_addr = 1; 42467c08ac4SVoon Weifeng return ehl_common_data(pdev, plat); 42567c08ac4SVoon Weifeng } 42667c08ac4SVoon Weifeng 42767c08ac4SVoon Weifeng static int ehl_pse1_rgmii1g_data(struct pci_dev *pdev, 42867c08ac4SVoon Weifeng struct plat_stmmacenet_data *plat) 42967c08ac4SVoon Weifeng { 43067c08ac4SVoon Weifeng plat->phy_interface = PHY_INTERFACE_MODE_RGMII_ID; 43167c08ac4SVoon Weifeng return ehl_pse1_common_data(pdev, plat); 43267c08ac4SVoon Weifeng } 43367c08ac4SVoon Weifeng 43467c08ac4SVoon Weifeng static struct stmmac_pci_info ehl_pse1_rgmii1g_pci_info = { 43567c08ac4SVoon Weifeng .setup = ehl_pse1_rgmii1g_data, 43667c08ac4SVoon Weifeng }; 43767c08ac4SVoon Weifeng 43867c08ac4SVoon Weifeng static int ehl_pse1_sgmii1g_data(struct pci_dev *pdev, 43967c08ac4SVoon Weifeng struct plat_stmmacenet_data *plat) 44067c08ac4SVoon Weifeng { 44167c08ac4SVoon Weifeng plat->phy_interface = PHY_INTERFACE_MODE_SGMII; 442*b9663b7cSVoon Weifeng plat->serdes_powerup = intel_serdes_powerup; 443*b9663b7cSVoon Weifeng plat->serdes_powerdown = intel_serdes_powerdown; 44467c08ac4SVoon Weifeng return ehl_pse1_common_data(pdev, plat); 44567c08ac4SVoon Weifeng } 44667c08ac4SVoon Weifeng 44767c08ac4SVoon Weifeng static struct stmmac_pci_info ehl_pse1_sgmii1g_pci_info = { 44867c08ac4SVoon Weifeng .setup = ehl_pse1_sgmii1g_data, 44967c08ac4SVoon Weifeng }; 45067c08ac4SVoon Weifeng 45158da0cfaSVoon Weifeng static int tgl_common_data(struct pci_dev *pdev, 45258da0cfaSVoon Weifeng struct plat_stmmacenet_data *plat) 45358da0cfaSVoon Weifeng { 45458da0cfaSVoon Weifeng int ret; 45558da0cfaSVoon Weifeng 45658da0cfaSVoon Weifeng plat->rx_queues_to_use = 6; 45758da0cfaSVoon Weifeng plat->tx_queues_to_use = 4; 45858da0cfaSVoon Weifeng plat->clk_ptp_rate = 200000000; 45958da0cfaSVoon Weifeng ret = intel_mgbe_common_data(pdev, plat); 46058da0cfaSVoon Weifeng if (ret) 46158da0cfaSVoon Weifeng return ret; 46258da0cfaSVoon Weifeng 46358da0cfaSVoon Weifeng return 0; 46458da0cfaSVoon Weifeng } 46558da0cfaSVoon Weifeng 46658da0cfaSVoon Weifeng static int tgl_sgmii_data(struct pci_dev *pdev, 46758da0cfaSVoon Weifeng struct plat_stmmacenet_data *plat) 46858da0cfaSVoon Weifeng { 46958da0cfaSVoon Weifeng plat->bus_id = 1; 47058da0cfaSVoon Weifeng plat->phy_addr = 0; 47158da0cfaSVoon Weifeng plat->phy_interface = PHY_INTERFACE_MODE_SGMII; 472*b9663b7cSVoon Weifeng plat->serdes_powerup = intel_serdes_powerup; 473*b9663b7cSVoon Weifeng plat->serdes_powerdown = intel_serdes_powerdown; 47458da0cfaSVoon Weifeng return tgl_common_data(pdev, plat); 47558da0cfaSVoon Weifeng } 47658da0cfaSVoon Weifeng 47758da0cfaSVoon Weifeng static struct stmmac_pci_info tgl_sgmii1g_pci_info = { 47858da0cfaSVoon Weifeng .setup = tgl_sgmii_data, 47958da0cfaSVoon Weifeng }; 48058da0cfaSVoon Weifeng 48158da0cfaSVoon Weifeng static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = { 48258da0cfaSVoon Weifeng { 48358da0cfaSVoon Weifeng .func = 6, 48458da0cfaSVoon Weifeng .phy_addr = 1, 48558da0cfaSVoon Weifeng }, 48658da0cfaSVoon Weifeng }; 48758da0cfaSVoon Weifeng 48858da0cfaSVoon Weifeng static const struct stmmac_pci_dmi_data galileo_stmmac_dmi_data = { 48958da0cfaSVoon Weifeng .func = galileo_stmmac_func_data, 49058da0cfaSVoon Weifeng .nfuncs = ARRAY_SIZE(galileo_stmmac_func_data), 49158da0cfaSVoon Weifeng }; 49258da0cfaSVoon Weifeng 49358da0cfaSVoon Weifeng static const struct stmmac_pci_func_data iot2040_stmmac_func_data[] = { 49458da0cfaSVoon Weifeng { 49558da0cfaSVoon Weifeng .func = 6, 49658da0cfaSVoon Weifeng .phy_addr = 1, 49758da0cfaSVoon Weifeng }, 49858da0cfaSVoon Weifeng { 49958da0cfaSVoon Weifeng .func = 7, 50058da0cfaSVoon Weifeng .phy_addr = 1, 50158da0cfaSVoon Weifeng }, 50258da0cfaSVoon Weifeng }; 50358da0cfaSVoon Weifeng 50458da0cfaSVoon Weifeng static const struct stmmac_pci_dmi_data iot2040_stmmac_dmi_data = { 50558da0cfaSVoon Weifeng .func = iot2040_stmmac_func_data, 50658da0cfaSVoon Weifeng .nfuncs = ARRAY_SIZE(iot2040_stmmac_func_data), 50758da0cfaSVoon Weifeng }; 50858da0cfaSVoon Weifeng 50958da0cfaSVoon Weifeng static const struct dmi_system_id quark_pci_dmi[] = { 51058da0cfaSVoon Weifeng { 51158da0cfaSVoon Weifeng .matches = { 51258da0cfaSVoon Weifeng DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"), 51358da0cfaSVoon Weifeng }, 51458da0cfaSVoon Weifeng .driver_data = (void *)&galileo_stmmac_dmi_data, 51558da0cfaSVoon Weifeng }, 51658da0cfaSVoon Weifeng { 51758da0cfaSVoon Weifeng .matches = { 51858da0cfaSVoon Weifeng DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"), 51958da0cfaSVoon Weifeng }, 52058da0cfaSVoon Weifeng .driver_data = (void *)&galileo_stmmac_dmi_data, 52158da0cfaSVoon Weifeng }, 52258da0cfaSVoon Weifeng /* There are 2 types of SIMATIC IOT2000: IOT2020 and IOT2040. 52358da0cfaSVoon Weifeng * The asset tag "6ES7647-0AA00-0YA2" is only for IOT2020 which 52458da0cfaSVoon Weifeng * has only one pci network device while other asset tags are 52558da0cfaSVoon Weifeng * for IOT2040 which has two. 52658da0cfaSVoon Weifeng */ 52758da0cfaSVoon Weifeng { 52858da0cfaSVoon Weifeng .matches = { 52958da0cfaSVoon Weifeng DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"), 53058da0cfaSVoon Weifeng DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG, 53158da0cfaSVoon Weifeng "6ES7647-0AA00-0YA2"), 53258da0cfaSVoon Weifeng }, 53358da0cfaSVoon Weifeng .driver_data = (void *)&galileo_stmmac_dmi_data, 53458da0cfaSVoon Weifeng }, 53558da0cfaSVoon Weifeng { 53658da0cfaSVoon Weifeng .matches = { 53758da0cfaSVoon Weifeng DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"), 53858da0cfaSVoon Weifeng }, 53958da0cfaSVoon Weifeng .driver_data = (void *)&iot2040_stmmac_dmi_data, 54058da0cfaSVoon Weifeng }, 54158da0cfaSVoon Weifeng {} 54258da0cfaSVoon Weifeng }; 54358da0cfaSVoon Weifeng 54458da0cfaSVoon Weifeng static int quark_default_data(struct pci_dev *pdev, 54558da0cfaSVoon Weifeng struct plat_stmmacenet_data *plat) 54658da0cfaSVoon Weifeng { 54758da0cfaSVoon Weifeng int ret; 54858da0cfaSVoon Weifeng 54958da0cfaSVoon Weifeng /* Set common default data first */ 55058da0cfaSVoon Weifeng common_default_data(plat); 55158da0cfaSVoon Weifeng 55258da0cfaSVoon Weifeng /* Refuse to load the driver and register net device if MAC controller 55358da0cfaSVoon Weifeng * does not connect to any PHY interface. 55458da0cfaSVoon Weifeng */ 55558da0cfaSVoon Weifeng ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi); 55658da0cfaSVoon Weifeng if (ret < 0) { 55758da0cfaSVoon Weifeng /* Return error to the caller on DMI enabled boards. */ 55858da0cfaSVoon Weifeng if (dmi_get_system_info(DMI_BOARD_NAME)) 55958da0cfaSVoon Weifeng return ret; 56058da0cfaSVoon Weifeng 56158da0cfaSVoon Weifeng /* Galileo boards with old firmware don't support DMI. We always 56258da0cfaSVoon Weifeng * use 1 here as PHY address, so at least the first found MAC 56358da0cfaSVoon Weifeng * controller would be probed. 56458da0cfaSVoon Weifeng */ 56558da0cfaSVoon Weifeng ret = 1; 56658da0cfaSVoon Weifeng } 56758da0cfaSVoon Weifeng 56858da0cfaSVoon Weifeng plat->bus_id = pci_dev_id(pdev); 56958da0cfaSVoon Weifeng plat->phy_addr = ret; 57058da0cfaSVoon Weifeng plat->phy_interface = PHY_INTERFACE_MODE_RMII; 57158da0cfaSVoon Weifeng 57258da0cfaSVoon Weifeng plat->dma_cfg->pbl = 16; 57358da0cfaSVoon Weifeng plat->dma_cfg->pblx8 = true; 57458da0cfaSVoon Weifeng plat->dma_cfg->fixed_burst = 1; 57558da0cfaSVoon Weifeng /* AXI (TODO) */ 57658da0cfaSVoon Weifeng 57758da0cfaSVoon Weifeng return 0; 57858da0cfaSVoon Weifeng } 57958da0cfaSVoon Weifeng 58058da0cfaSVoon Weifeng static const struct stmmac_pci_info quark_pci_info = { 58158da0cfaSVoon Weifeng .setup = quark_default_data, 58258da0cfaSVoon Weifeng }; 58358da0cfaSVoon Weifeng 58458da0cfaSVoon Weifeng /** 58558da0cfaSVoon Weifeng * intel_eth_pci_probe 58658da0cfaSVoon Weifeng * 58758da0cfaSVoon Weifeng * @pdev: pci device pointer 58858da0cfaSVoon Weifeng * @id: pointer to table of device id/id's. 58958da0cfaSVoon Weifeng * 59058da0cfaSVoon Weifeng * Description: This probing function gets called for all PCI devices which 59158da0cfaSVoon Weifeng * match the ID table and are not "owned" by other driver yet. This function 59258da0cfaSVoon Weifeng * gets passed a "struct pci_dev *" for each device whose entry in the ID table 59358da0cfaSVoon Weifeng * matches the device. The probe functions returns zero when the driver choose 59458da0cfaSVoon Weifeng * to take "ownership" of the device or an error code(-ve no) otherwise. 59558da0cfaSVoon Weifeng */ 59658da0cfaSVoon Weifeng static int intel_eth_pci_probe(struct pci_dev *pdev, 59758da0cfaSVoon Weifeng const struct pci_device_id *id) 59858da0cfaSVoon Weifeng { 59958da0cfaSVoon Weifeng struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data; 600*b9663b7cSVoon Weifeng struct intel_priv_data *intel_priv; 60158da0cfaSVoon Weifeng struct plat_stmmacenet_data *plat; 60258da0cfaSVoon Weifeng struct stmmac_resources res; 60358da0cfaSVoon Weifeng int i; 60458da0cfaSVoon Weifeng int ret; 60558da0cfaSVoon Weifeng 606*b9663b7cSVoon Weifeng intel_priv = devm_kzalloc(&pdev->dev, sizeof(*intel_priv), 607*b9663b7cSVoon Weifeng GFP_KERNEL); 608*b9663b7cSVoon Weifeng if (!intel_priv) 609*b9663b7cSVoon Weifeng return -ENOMEM; 610*b9663b7cSVoon Weifeng 61158da0cfaSVoon Weifeng plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); 61258da0cfaSVoon Weifeng if (!plat) 61358da0cfaSVoon Weifeng return -ENOMEM; 61458da0cfaSVoon Weifeng 61558da0cfaSVoon Weifeng plat->mdio_bus_data = devm_kzalloc(&pdev->dev, 61658da0cfaSVoon Weifeng sizeof(*plat->mdio_bus_data), 61758da0cfaSVoon Weifeng GFP_KERNEL); 61858da0cfaSVoon Weifeng if (!plat->mdio_bus_data) 61958da0cfaSVoon Weifeng return -ENOMEM; 62058da0cfaSVoon Weifeng 62158da0cfaSVoon Weifeng plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), 62258da0cfaSVoon Weifeng GFP_KERNEL); 62358da0cfaSVoon Weifeng if (!plat->dma_cfg) 62458da0cfaSVoon Weifeng return -ENOMEM; 62558da0cfaSVoon Weifeng 62658da0cfaSVoon Weifeng /* Enable pci device */ 62758da0cfaSVoon Weifeng ret = pci_enable_device(pdev); 62858da0cfaSVoon Weifeng if (ret) { 62958da0cfaSVoon Weifeng dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", 63058da0cfaSVoon Weifeng __func__); 63158da0cfaSVoon Weifeng return ret; 63258da0cfaSVoon Weifeng } 63358da0cfaSVoon Weifeng 63458da0cfaSVoon Weifeng /* Get the base address of device */ 63558da0cfaSVoon Weifeng for (i = 0; i < PCI_STD_NUM_BARS; i++) { 63658da0cfaSVoon Weifeng if (pci_resource_len(pdev, i) == 0) 63758da0cfaSVoon Weifeng continue; 63858da0cfaSVoon Weifeng ret = pcim_iomap_regions(pdev, BIT(i), pci_name(pdev)); 63958da0cfaSVoon Weifeng if (ret) 64058da0cfaSVoon Weifeng return ret; 64158da0cfaSVoon Weifeng break; 64258da0cfaSVoon Weifeng } 64358da0cfaSVoon Weifeng 64458da0cfaSVoon Weifeng pci_set_master(pdev); 64558da0cfaSVoon Weifeng 646*b9663b7cSVoon Weifeng plat->bsp_priv = intel_priv; 647*b9663b7cSVoon Weifeng intel_priv->mdio_adhoc_addr = 0x15; 648*b9663b7cSVoon Weifeng 64958da0cfaSVoon Weifeng ret = info->setup(pdev, plat); 65058da0cfaSVoon Weifeng if (ret) 65158da0cfaSVoon Weifeng return ret; 65258da0cfaSVoon Weifeng 65358da0cfaSVoon Weifeng pci_enable_msi(pdev); 65458da0cfaSVoon Weifeng 65558da0cfaSVoon Weifeng memset(&res, 0, sizeof(res)); 65658da0cfaSVoon Weifeng res.addr = pcim_iomap_table(pdev)[i]; 65758da0cfaSVoon Weifeng res.wol_irq = pdev->irq; 65858da0cfaSVoon Weifeng res.irq = pdev->irq; 65958da0cfaSVoon Weifeng 66058da0cfaSVoon Weifeng return stmmac_dvr_probe(&pdev->dev, plat, &res); 66158da0cfaSVoon Weifeng } 66258da0cfaSVoon Weifeng 66358da0cfaSVoon Weifeng /** 66458da0cfaSVoon Weifeng * intel_eth_pci_remove 66558da0cfaSVoon Weifeng * 66658da0cfaSVoon Weifeng * @pdev: platform device pointer 66758da0cfaSVoon Weifeng * Description: this function calls the main to free the net resources 66858da0cfaSVoon Weifeng * and releases the PCI resources. 66958da0cfaSVoon Weifeng */ 67058da0cfaSVoon Weifeng static void intel_eth_pci_remove(struct pci_dev *pdev) 67158da0cfaSVoon Weifeng { 67258da0cfaSVoon Weifeng struct net_device *ndev = dev_get_drvdata(&pdev->dev); 67358da0cfaSVoon Weifeng struct stmmac_priv *priv = netdev_priv(ndev); 67458da0cfaSVoon Weifeng int i; 67558da0cfaSVoon Weifeng 67658da0cfaSVoon Weifeng stmmac_dvr_remove(&pdev->dev); 67758da0cfaSVoon Weifeng 67858da0cfaSVoon Weifeng if (priv->plat->stmmac_clk) 67958da0cfaSVoon Weifeng clk_unregister_fixed_rate(priv->plat->stmmac_clk); 68058da0cfaSVoon Weifeng 68158da0cfaSVoon Weifeng for (i = 0; i < PCI_STD_NUM_BARS; i++) { 68258da0cfaSVoon Weifeng if (pci_resource_len(pdev, i) == 0) 68358da0cfaSVoon Weifeng continue; 68458da0cfaSVoon Weifeng pcim_iounmap_regions(pdev, BIT(i)); 68558da0cfaSVoon Weifeng break; 68658da0cfaSVoon Weifeng } 68758da0cfaSVoon Weifeng 68858da0cfaSVoon Weifeng pci_disable_device(pdev); 68958da0cfaSVoon Weifeng } 69058da0cfaSVoon Weifeng 69158da0cfaSVoon Weifeng static int __maybe_unused intel_eth_pci_suspend(struct device *dev) 69258da0cfaSVoon Weifeng { 69358da0cfaSVoon Weifeng struct pci_dev *pdev = to_pci_dev(dev); 69458da0cfaSVoon Weifeng int ret; 69558da0cfaSVoon Weifeng 69658da0cfaSVoon Weifeng ret = stmmac_suspend(dev); 69758da0cfaSVoon Weifeng if (ret) 69858da0cfaSVoon Weifeng return ret; 69958da0cfaSVoon Weifeng 70058da0cfaSVoon Weifeng ret = pci_save_state(pdev); 70158da0cfaSVoon Weifeng if (ret) 70258da0cfaSVoon Weifeng return ret; 70358da0cfaSVoon Weifeng 70458da0cfaSVoon Weifeng pci_disable_device(pdev); 70558da0cfaSVoon Weifeng pci_wake_from_d3(pdev, true); 70658da0cfaSVoon Weifeng return 0; 70758da0cfaSVoon Weifeng } 70858da0cfaSVoon Weifeng 70958da0cfaSVoon Weifeng static int __maybe_unused intel_eth_pci_resume(struct device *dev) 71058da0cfaSVoon Weifeng { 71158da0cfaSVoon Weifeng struct pci_dev *pdev = to_pci_dev(dev); 71258da0cfaSVoon Weifeng int ret; 71358da0cfaSVoon Weifeng 71458da0cfaSVoon Weifeng pci_restore_state(pdev); 71558da0cfaSVoon Weifeng pci_set_power_state(pdev, PCI_D0); 71658da0cfaSVoon Weifeng 71758da0cfaSVoon Weifeng ret = pci_enable_device(pdev); 71858da0cfaSVoon Weifeng if (ret) 71958da0cfaSVoon Weifeng return ret; 72058da0cfaSVoon Weifeng 72158da0cfaSVoon Weifeng pci_set_master(pdev); 72258da0cfaSVoon Weifeng 72358da0cfaSVoon Weifeng return stmmac_resume(dev); 72458da0cfaSVoon Weifeng } 72558da0cfaSVoon Weifeng 72658da0cfaSVoon Weifeng static SIMPLE_DEV_PM_OPS(intel_eth_pm_ops, intel_eth_pci_suspend, 72758da0cfaSVoon Weifeng intel_eth_pci_resume); 72858da0cfaSVoon Weifeng 72958da0cfaSVoon Weifeng #define PCI_DEVICE_ID_INTEL_QUARK_ID 0x0937 73058da0cfaSVoon Weifeng #define PCI_DEVICE_ID_INTEL_EHL_RGMII1G_ID 0x4b30 73158da0cfaSVoon Weifeng #define PCI_DEVICE_ID_INTEL_EHL_SGMII1G_ID 0x4b31 732d63439f5SVoon Weifeng #define PCI_DEVICE_ID_INTEL_EHL_SGMII2G5_ID 0x4b32 73367c08ac4SVoon Weifeng /* Intel(R) Programmable Services Engine (Intel(R) PSE) consist of 2 MAC 73467c08ac4SVoon Weifeng * which are named PSE0 and PSE1 73567c08ac4SVoon Weifeng */ 73667c08ac4SVoon Weifeng #define PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G_ID 0x4ba0 73767c08ac4SVoon Weifeng #define PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G_ID 0x4ba1 738d63439f5SVoon Weifeng #define PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G5_ID 0x4ba2 73967c08ac4SVoon Weifeng #define PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G_ID 0x4bb0 74067c08ac4SVoon Weifeng #define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G_ID 0x4bb1 741d63439f5SVoon Weifeng #define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5_ID 0x4bb2 74258da0cfaSVoon Weifeng #define PCI_DEVICE_ID_INTEL_TGL_SGMII1G_ID 0xa0ac 74358da0cfaSVoon Weifeng 74458da0cfaSVoon Weifeng static const struct pci_device_id intel_eth_pci_id_table[] = { 74558da0cfaSVoon Weifeng { PCI_DEVICE_DATA(INTEL, QUARK_ID, &quark_pci_info) }, 74658da0cfaSVoon Weifeng { PCI_DEVICE_DATA(INTEL, EHL_RGMII1G_ID, &ehl_rgmii1g_pci_info) }, 74758da0cfaSVoon Weifeng { PCI_DEVICE_DATA(INTEL, EHL_SGMII1G_ID, &ehl_sgmii1g_pci_info) }, 748d63439f5SVoon Weifeng { PCI_DEVICE_DATA(INTEL, EHL_SGMII2G5_ID, &ehl_sgmii1g_pci_info) }, 74967c08ac4SVoon Weifeng { PCI_DEVICE_DATA(INTEL, EHL_PSE0_RGMII1G_ID, 75067c08ac4SVoon Weifeng &ehl_pse0_rgmii1g_pci_info) }, 75167c08ac4SVoon Weifeng { PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII1G_ID, 75267c08ac4SVoon Weifeng &ehl_pse0_sgmii1g_pci_info) }, 753d63439f5SVoon Weifeng { PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII2G5_ID, 754d63439f5SVoon Weifeng &ehl_pse0_sgmii1g_pci_info) }, 75567c08ac4SVoon Weifeng { PCI_DEVICE_DATA(INTEL, EHL_PSE1_RGMII1G_ID, 75667c08ac4SVoon Weifeng &ehl_pse1_rgmii1g_pci_info) }, 75767c08ac4SVoon Weifeng { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G_ID, 75867c08ac4SVoon Weifeng &ehl_pse1_sgmii1g_pci_info) }, 759d63439f5SVoon Weifeng { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5_ID, 760d63439f5SVoon Weifeng &ehl_pse1_sgmii1g_pci_info) }, 76158da0cfaSVoon Weifeng { PCI_DEVICE_DATA(INTEL, TGL_SGMII1G_ID, &tgl_sgmii1g_pci_info) }, 76258da0cfaSVoon Weifeng {} 76358da0cfaSVoon Weifeng }; 76458da0cfaSVoon Weifeng 76558da0cfaSVoon Weifeng MODULE_DEVICE_TABLE(pci, intel_eth_pci_id_table); 76658da0cfaSVoon Weifeng 76758da0cfaSVoon Weifeng static struct pci_driver intel_eth_pci_driver = { 76858da0cfaSVoon Weifeng .name = "intel-eth-pci", 76958da0cfaSVoon Weifeng .id_table = intel_eth_pci_id_table, 77058da0cfaSVoon Weifeng .probe = intel_eth_pci_probe, 77158da0cfaSVoon Weifeng .remove = intel_eth_pci_remove, 77258da0cfaSVoon Weifeng .driver = { 77358da0cfaSVoon Weifeng .pm = &intel_eth_pm_ops, 77458da0cfaSVoon Weifeng }, 77558da0cfaSVoon Weifeng }; 77658da0cfaSVoon Weifeng 77758da0cfaSVoon Weifeng module_pci_driver(intel_eth_pci_driver); 77858da0cfaSVoon Weifeng 77958da0cfaSVoon Weifeng MODULE_DESCRIPTION("INTEL 10/100/1000 Ethernet PCI driver"); 78058da0cfaSVoon Weifeng MODULE_AUTHOR("Voon Weifeng <weifeng.voon@intel.com>"); 78158da0cfaSVoon Weifeng MODULE_LICENSE("GPL v2"); 782