Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * AMD 10Gb Ethernet driver
0003  *
0004  * This file is available to you under your choice of the following two
0005  * licenses:
0006  *
0007  * License 1: GPLv2
0008  *
0009  * Copyright (c) 2016 Advanced Micro Devices, Inc.
0010  *
0011  * This file is free software; you may copy, redistribute and/or modify
0012  * it under the terms of the GNU General Public License as published by
0013  * the Free Software Foundation, either version 2 of the License, or (at
0014  * your option) any later version.
0015  *
0016  * This file is distributed in the hope that it will be useful, but
0017  * WITHOUT ANY WARRANTY; without even the implied warranty of
0018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0019  * General Public License for more details.
0020  *
0021  * You should have received a copy of the GNU General Public License
0022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0023  *
0024  * This file incorporates work covered by the following copyright and
0025  * permission notice:
0026  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
0027  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
0028  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
0029  *     and you.
0030  *
0031  *     The Software IS NOT an item of Licensed Software or Licensed Product
0032  *     under any End User Software License Agreement or Agreement for Licensed
0033  *     Product with Synopsys or any supplement thereto.  Permission is hereby
0034  *     granted, free of charge, to any person obtaining a copy of this software
0035  *     annotated with this license and the Software, to deal in the Software
0036  *     without restriction, including without limitation the rights to use,
0037  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
0038  *     of the Software, and to permit persons to whom the Software is furnished
0039  *     to do so, subject to the following conditions:
0040  *
0041  *     The above copyright notice and this permission notice shall be included
0042  *     in all copies or substantial portions of the Software.
0043  *
0044  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
0045  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
0046  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
0047  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
0048  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0049  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0050  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0051  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0052  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0053  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
0054  *     THE POSSIBILITY OF SUCH DAMAGE.
0055  *
0056  *
0057  * License 2: Modified BSD
0058  *
0059  * Copyright (c) 2016 Advanced Micro Devices, Inc.
0060  * All rights reserved.
0061  *
0062  * Redistribution and use in source and binary forms, with or without
0063  * modification, are permitted provided that the following conditions are met:
0064  *     * Redistributions of source code must retain the above copyright
0065  *       notice, this list of conditions and the following disclaimer.
0066  *     * Redistributions in binary form must reproduce the above copyright
0067  *       notice, this list of conditions and the following disclaimer in the
0068  *       documentation and/or other materials provided with the distribution.
0069  *     * Neither the name of Advanced Micro Devices, Inc. nor the
0070  *       names of its contributors may be used to endorse or promote products
0071  *       derived from this software without specific prior written permission.
0072  *
0073  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0074  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0075  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0076  * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
0077  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0078  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0079  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0080  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0081  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0082  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0083  *
0084  * This file incorporates work covered by the following copyright and
0085  * permission notice:
0086  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
0087  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
0088  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
0089  *     and you.
0090  *
0091  *     The Software IS NOT an item of Licensed Software or Licensed Product
0092  *     under any End User Software License Agreement or Agreement for Licensed
0093  *     Product with Synopsys or any supplement thereto.  Permission is hereby
0094  *     granted, free of charge, to any person obtaining a copy of this software
0095  *     annotated with this license and the Software, to deal in the Software
0096  *     without restriction, including without limitation the rights to use,
0097  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
0098  *     of the Software, and to permit persons to whom the Software is furnished
0099  *     to do so, subject to the following conditions:
0100  *
0101  *     The above copyright notice and this permission notice shall be included
0102  *     in all copies or substantial portions of the Software.
0103  *
0104  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
0105  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
0106  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
0107  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
0108  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0109  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0110  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0111  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0112  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0113  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
0114  *     THE POSSIBILITY OF SUCH DAMAGE.
0115  */
0116 
0117 #include <linux/module.h>
0118 #include <linux/device.h>
0119 #include <linux/pci.h>
0120 #include <linux/log2.h>
0121 
0122 #include "xgbe.h"
0123 #include "xgbe-common.h"
0124 
0125 static int xgbe_config_multi_msi(struct xgbe_prv_data *pdata)
0126 {
0127     unsigned int vector_count;
0128     unsigned int i, j;
0129     int ret;
0130 
0131     vector_count = XGBE_MSI_BASE_COUNT;
0132     vector_count += max(pdata->rx_ring_count,
0133                 pdata->tx_ring_count);
0134 
0135     ret = pci_alloc_irq_vectors(pdata->pcidev, XGBE_MSI_MIN_COUNT,
0136                     vector_count, PCI_IRQ_MSI | PCI_IRQ_MSIX);
0137     if (ret < 0) {
0138         dev_info(pdata->dev, "multi MSI/MSI-X enablement failed\n");
0139         return ret;
0140     }
0141 
0142     pdata->isr_as_tasklet = 1;
0143     pdata->irq_count = ret;
0144 
0145     pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
0146     pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 1);
0147     pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 2);
0148     pdata->an_irq = pci_irq_vector(pdata->pcidev, 3);
0149 
0150     for (i = XGBE_MSI_BASE_COUNT, j = 0; i < ret; i++, j++)
0151         pdata->channel_irq[j] = pci_irq_vector(pdata->pcidev, i);
0152     pdata->channel_irq_count = j;
0153 
0154     pdata->per_channel_irq = 1;
0155     pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL;
0156 
0157     if (netif_msg_probe(pdata))
0158         dev_dbg(pdata->dev, "multi %s interrupts enabled\n",
0159             pdata->pcidev->msix_enabled ? "MSI-X" : "MSI");
0160 
0161     return 0;
0162 }
0163 
0164 static int xgbe_config_irqs(struct xgbe_prv_data *pdata)
0165 {
0166     int ret;
0167 
0168     ret = xgbe_config_multi_msi(pdata);
0169     if (!ret)
0170         goto out;
0171 
0172     ret = pci_alloc_irq_vectors(pdata->pcidev, 1, 1,
0173                     PCI_IRQ_LEGACY | PCI_IRQ_MSI);
0174     if (ret < 0) {
0175         dev_info(pdata->dev, "single IRQ enablement failed\n");
0176         return ret;
0177     }
0178 
0179     pdata->isr_as_tasklet = pdata->pcidev->msi_enabled ? 1 : 0;
0180     pdata->irq_count = 1;
0181     pdata->channel_irq_count = 1;
0182 
0183     pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
0184     pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 0);
0185     pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 0);
0186     pdata->an_irq = pci_irq_vector(pdata->pcidev, 0);
0187 
0188     if (netif_msg_probe(pdata))
0189         dev_dbg(pdata->dev, "single %s interrupt enabled\n",
0190             pdata->pcidev->msi_enabled ?  "MSI" : "legacy");
0191 
0192 out:
0193     if (netif_msg_probe(pdata)) {
0194         unsigned int i;
0195 
0196         dev_dbg(pdata->dev, " dev irq=%d\n", pdata->dev_irq);
0197         dev_dbg(pdata->dev, " ecc irq=%d\n", pdata->ecc_irq);
0198         dev_dbg(pdata->dev, " i2c irq=%d\n", pdata->i2c_irq);
0199         dev_dbg(pdata->dev, "  an irq=%d\n", pdata->an_irq);
0200         for (i = 0; i < pdata->channel_irq_count; i++)
0201             dev_dbg(pdata->dev, " dma%u irq=%d\n",
0202                 i, pdata->channel_irq[i]);
0203     }
0204 
0205     return 0;
0206 }
0207 
0208 static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
0209 {
0210     struct xgbe_prv_data *pdata;
0211     struct device *dev = &pdev->dev;
0212     void __iomem * const *iomap_table;
0213     struct pci_dev *rdev;
0214     unsigned int ma_lo, ma_hi;
0215     unsigned int reg;
0216     int bar_mask;
0217     int ret;
0218 
0219     pdata = xgbe_alloc_pdata(dev);
0220     if (IS_ERR(pdata)) {
0221         ret = PTR_ERR(pdata);
0222         goto err_alloc;
0223     }
0224 
0225     pdata->pcidev = pdev;
0226     pci_set_drvdata(pdev, pdata);
0227 
0228     /* Get the version data */
0229     pdata->vdata = (struct xgbe_version_data *)id->driver_data;
0230 
0231     ret = pcim_enable_device(pdev);
0232     if (ret) {
0233         dev_err(dev, "pcim_enable_device failed\n");
0234         goto err_pci_enable;
0235     }
0236 
0237     /* Obtain the mmio areas for the device */
0238     bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
0239     ret = pcim_iomap_regions(pdev, bar_mask, XGBE_DRV_NAME);
0240     if (ret) {
0241         dev_err(dev, "pcim_iomap_regions failed\n");
0242         goto err_pci_enable;
0243     }
0244 
0245     iomap_table = pcim_iomap_table(pdev);
0246     if (!iomap_table) {
0247         dev_err(dev, "pcim_iomap_table failed\n");
0248         ret = -ENOMEM;
0249         goto err_pci_enable;
0250     }
0251 
0252     pdata->xgmac_regs = iomap_table[XGBE_XGMAC_BAR];
0253     if (!pdata->xgmac_regs) {
0254         dev_err(dev, "xgmac ioremap failed\n");
0255         ret = -ENOMEM;
0256         goto err_pci_enable;
0257     }
0258     pdata->xprop_regs = pdata->xgmac_regs + XGBE_MAC_PROP_OFFSET;
0259     pdata->xi2c_regs = pdata->xgmac_regs + XGBE_I2C_CTRL_OFFSET;
0260     if (netif_msg_probe(pdata)) {
0261         dev_dbg(dev, "xgmac_regs = %p\n", pdata->xgmac_regs);
0262         dev_dbg(dev, "xprop_regs = %p\n", pdata->xprop_regs);
0263         dev_dbg(dev, "xi2c_regs  = %p\n", pdata->xi2c_regs);
0264     }
0265 
0266     pdata->xpcs_regs = iomap_table[XGBE_XPCS_BAR];
0267     if (!pdata->xpcs_regs) {
0268         dev_err(dev, "xpcs ioremap failed\n");
0269         ret = -ENOMEM;
0270         goto err_pci_enable;
0271     }
0272     if (netif_msg_probe(pdata))
0273         dev_dbg(dev, "xpcs_regs  = %p\n", pdata->xpcs_regs);
0274 
0275     /* Set the PCS indirect addressing definition registers */
0276     rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
0277     if (rdev &&
0278         (rdev->vendor == PCI_VENDOR_ID_AMD) && (rdev->device == 0x15d0)) {
0279         pdata->xpcs_window_def_reg = PCS_V2_RV_WINDOW_DEF;
0280         pdata->xpcs_window_sel_reg = PCS_V2_RV_WINDOW_SELECT;
0281     } else if (rdev && (rdev->vendor == PCI_VENDOR_ID_AMD) &&
0282            (rdev->device == 0x14b5)) {
0283         pdata->xpcs_window_def_reg = PCS_V2_YC_WINDOW_DEF;
0284         pdata->xpcs_window_sel_reg = PCS_V2_YC_WINDOW_SELECT;
0285 
0286         /* Yellow Carp devices do not need cdr workaround */
0287         pdata->vdata->an_cdr_workaround = 0;
0288     } else {
0289         pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
0290         pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
0291     }
0292     pci_dev_put(rdev);
0293 
0294     /* Configure the PCS indirect addressing support */
0295     reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
0296     pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET);
0297     pdata->xpcs_window <<= 6;
0298     pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
0299     pdata->xpcs_window_size = 1 << (pdata->xpcs_window_size + 7);
0300     pdata->xpcs_window_mask = pdata->xpcs_window_size - 1;
0301     if (netif_msg_probe(pdata)) {
0302         dev_dbg(dev, "xpcs window def  = %#010x\n",
0303             pdata->xpcs_window_def_reg);
0304         dev_dbg(dev, "xpcs window sel  = %#010x\n",
0305             pdata->xpcs_window_sel_reg);
0306         dev_dbg(dev, "xpcs window      = %#010x\n",
0307             pdata->xpcs_window);
0308         dev_dbg(dev, "xpcs window size = %#010x\n",
0309             pdata->xpcs_window_size);
0310         dev_dbg(dev, "xpcs window mask = %#010x\n",
0311             pdata->xpcs_window_mask);
0312     }
0313 
0314     pci_set_master(pdev);
0315 
0316     /* Enable all interrupts in the hardware */
0317     XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff);
0318 
0319     /* Retrieve the MAC address */
0320     ma_lo = XP_IOREAD(pdata, XP_MAC_ADDR_LO);
0321     ma_hi = XP_IOREAD(pdata, XP_MAC_ADDR_HI);
0322     pdata->mac_addr[0] = ma_lo & 0xff;
0323     pdata->mac_addr[1] = (ma_lo >> 8) & 0xff;
0324     pdata->mac_addr[2] = (ma_lo >> 16) & 0xff;
0325     pdata->mac_addr[3] = (ma_lo >> 24) & 0xff;
0326     pdata->mac_addr[4] = ma_hi & 0xff;
0327     pdata->mac_addr[5] = (ma_hi >> 8) & 0xff;
0328     if (!XP_GET_BITS(ma_hi, XP_MAC_ADDR_HI, VALID) ||
0329         !is_valid_ether_addr(pdata->mac_addr)) {
0330         dev_err(dev, "invalid mac address\n");
0331         ret = -EINVAL;
0332         goto err_pci_enable;
0333     }
0334 
0335     /* Clock settings */
0336     pdata->sysclk_rate = XGBE_V2_DMA_CLOCK_FREQ;
0337     pdata->ptpclk_rate = XGBE_V2_PTP_CLOCK_FREQ;
0338 
0339     /* Set the DMA coherency values */
0340     pdata->coherent = 1;
0341     pdata->arcr = XGBE_DMA_PCI_ARCR;
0342     pdata->awcr = XGBE_DMA_PCI_AWCR;
0343     pdata->awarcr = XGBE_DMA_PCI_AWARCR;
0344 
0345     /* Read the port property registers */
0346     pdata->pp0 = XP_IOREAD(pdata, XP_PROP_0);
0347     pdata->pp1 = XP_IOREAD(pdata, XP_PROP_1);
0348     pdata->pp2 = XP_IOREAD(pdata, XP_PROP_2);
0349     pdata->pp3 = XP_IOREAD(pdata, XP_PROP_3);
0350     pdata->pp4 = XP_IOREAD(pdata, XP_PROP_4);
0351     if (netif_msg_probe(pdata)) {
0352         dev_dbg(dev, "port property 0 = %#010x\n", pdata->pp0);
0353         dev_dbg(dev, "port property 1 = %#010x\n", pdata->pp1);
0354         dev_dbg(dev, "port property 2 = %#010x\n", pdata->pp2);
0355         dev_dbg(dev, "port property 3 = %#010x\n", pdata->pp3);
0356         dev_dbg(dev, "port property 4 = %#010x\n", pdata->pp4);
0357     }
0358 
0359     /* Set the maximum channels and queues */
0360     pdata->tx_max_channel_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
0361                           MAX_TX_DMA);
0362     pdata->rx_max_channel_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
0363                           MAX_RX_DMA);
0364     pdata->tx_max_q_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
0365                         MAX_TX_QUEUES);
0366     pdata->rx_max_q_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
0367                         MAX_RX_QUEUES);
0368     if (netif_msg_probe(pdata)) {
0369         dev_dbg(dev, "max tx/rx channel count = %u/%u\n",
0370             pdata->tx_max_channel_count,
0371             pdata->rx_max_channel_count);
0372         dev_dbg(dev, "max tx/rx hw queue count = %u/%u\n",
0373             pdata->tx_max_q_count, pdata->rx_max_q_count);
0374     }
0375 
0376     /* Set the hardware channel and queue counts */
0377     xgbe_set_counts(pdata);
0378 
0379     /* Set the maximum fifo amounts */
0380     pdata->tx_max_fifo_size = XP_GET_BITS(pdata->pp2, XP_PROP_2,
0381                           TX_FIFO_SIZE);
0382     pdata->tx_max_fifo_size *= 16384;
0383     pdata->tx_max_fifo_size = min(pdata->tx_max_fifo_size,
0384                       pdata->vdata->tx_max_fifo_size);
0385     pdata->rx_max_fifo_size = XP_GET_BITS(pdata->pp2, XP_PROP_2,
0386                           RX_FIFO_SIZE);
0387     pdata->rx_max_fifo_size *= 16384;
0388     pdata->rx_max_fifo_size = min(pdata->rx_max_fifo_size,
0389                       pdata->vdata->rx_max_fifo_size);
0390     if (netif_msg_probe(pdata))
0391         dev_dbg(dev, "max tx/rx max fifo size = %u/%u\n",
0392             pdata->tx_max_fifo_size, pdata->rx_max_fifo_size);
0393 
0394     /* Configure interrupt support */
0395     ret = xgbe_config_irqs(pdata);
0396     if (ret)
0397         goto err_pci_enable;
0398 
0399     /* Configure the netdev resource */
0400     ret = xgbe_config_netdev(pdata);
0401     if (ret)
0402         goto err_irq_vectors;
0403 
0404     netdev_notice(pdata->netdev, "net device enabled\n");
0405 
0406     return 0;
0407 
0408 err_irq_vectors:
0409     pci_free_irq_vectors(pdata->pcidev);
0410 
0411 err_pci_enable:
0412     xgbe_free_pdata(pdata);
0413 
0414 err_alloc:
0415     dev_notice(dev, "net device not enabled\n");
0416 
0417     return ret;
0418 }
0419 
0420 static void xgbe_pci_remove(struct pci_dev *pdev)
0421 {
0422     struct xgbe_prv_data *pdata = pci_get_drvdata(pdev);
0423 
0424     xgbe_deconfig_netdev(pdata);
0425 
0426     pci_free_irq_vectors(pdata->pcidev);
0427 
0428     /* Disable all interrupts in the hardware */
0429     XP_IOWRITE(pdata, XP_INT_EN, 0x0);
0430 
0431     xgbe_free_pdata(pdata);
0432 }
0433 
0434 static int __maybe_unused xgbe_pci_suspend(struct device *dev)
0435 {
0436     struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
0437     struct net_device *netdev = pdata->netdev;
0438     int ret = 0;
0439 
0440     if (netif_running(netdev))
0441         ret = xgbe_powerdown(netdev, XGMAC_DRIVER_CONTEXT);
0442 
0443     pdata->lpm_ctrl = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
0444     pdata->lpm_ctrl |= MDIO_CTRL1_LPOWER;
0445     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
0446 
0447     return ret;
0448 }
0449 
0450 static int __maybe_unused xgbe_pci_resume(struct device *dev)
0451 {
0452     struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
0453     struct net_device *netdev = pdata->netdev;
0454     int ret = 0;
0455 
0456     XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff);
0457 
0458     pdata->lpm_ctrl &= ~MDIO_CTRL1_LPOWER;
0459     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
0460 
0461     if (netif_running(netdev)) {
0462         ret = xgbe_powerup(netdev, XGMAC_DRIVER_CONTEXT);
0463 
0464         /* Schedule a restart in case the link or phy state changed
0465          * while we were powered down.
0466          */
0467         schedule_work(&pdata->restart_work);
0468     }
0469 
0470     return ret;
0471 }
0472 
0473 static struct xgbe_version_data xgbe_v2a = {
0474     .init_function_ptrs_phy_impl    = xgbe_init_function_ptrs_phy_v2,
0475     .xpcs_access            = XGBE_XPCS_ACCESS_V2,
0476     .mmc_64bit          = 1,
0477     .tx_max_fifo_size       = 229376,
0478     .rx_max_fifo_size       = 229376,
0479     .tx_tstamp_workaround       = 1,
0480     .ecc_support            = 1,
0481     .i2c_support            = 1,
0482     .irq_reissue_support        = 1,
0483     .tx_desc_prefetch       = 5,
0484     .rx_desc_prefetch       = 5,
0485     .an_cdr_workaround      = 1,
0486 };
0487 
0488 static struct xgbe_version_data xgbe_v2b = {
0489     .init_function_ptrs_phy_impl    = xgbe_init_function_ptrs_phy_v2,
0490     .xpcs_access            = XGBE_XPCS_ACCESS_V2,
0491     .mmc_64bit          = 1,
0492     .tx_max_fifo_size       = 65536,
0493     .rx_max_fifo_size       = 65536,
0494     .tx_tstamp_workaround       = 1,
0495     .ecc_support            = 1,
0496     .i2c_support            = 1,
0497     .irq_reissue_support        = 1,
0498     .tx_desc_prefetch       = 5,
0499     .rx_desc_prefetch       = 5,
0500     .an_cdr_workaround      = 1,
0501 };
0502 
0503 static const struct pci_device_id xgbe_pci_table[] = {
0504     { PCI_VDEVICE(AMD, 0x1458),
0505       .driver_data = (kernel_ulong_t)&xgbe_v2a },
0506     { PCI_VDEVICE(AMD, 0x1459),
0507       .driver_data = (kernel_ulong_t)&xgbe_v2b },
0508     /* Last entry must be zero */
0509     { 0, }
0510 };
0511 MODULE_DEVICE_TABLE(pci, xgbe_pci_table);
0512 
0513 static SIMPLE_DEV_PM_OPS(xgbe_pci_pm_ops, xgbe_pci_suspend, xgbe_pci_resume);
0514 
0515 static struct pci_driver xgbe_driver = {
0516     .name = XGBE_DRV_NAME,
0517     .id_table = xgbe_pci_table,
0518     .probe = xgbe_pci_probe,
0519     .remove = xgbe_pci_remove,
0520     .driver = {
0521         .pm = &xgbe_pci_pm_ops,
0522     }
0523 };
0524 
0525 int xgbe_pci_init(void)
0526 {
0527     return pci_register_driver(&xgbe_driver);
0528 }
0529 
0530 void xgbe_pci_exit(void)
0531 {
0532     pci_unregister_driver(&xgbe_driver);
0533 }