cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xgbe-pci.c (18278B)


      1/*
      2 * AMD 10Gb Ethernet driver
      3 *
      4 * This file is available to you under your choice of the following two
      5 * licenses:
      6 *
      7 * License 1: GPLv2
      8 *
      9 * Copyright (c) 2016 Advanced Micro Devices, Inc.
     10 *
     11 * This file is free software; you may copy, redistribute and/or modify
     12 * it under the terms of the GNU General Public License as published by
     13 * the Free Software Foundation, either version 2 of the License, or (at
     14 * your option) any later version.
     15 *
     16 * This file is distributed in the hope that it will be useful, but
     17 * WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     19 * General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU General Public License
     22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     23 *
     24 * This file incorporates work covered by the following copyright and
     25 * permission notice:
     26 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
     27 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
     28 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
     29 *     and you.
     30 *
     31 *     The Software IS NOT an item of Licensed Software or Licensed Product
     32 *     under any End User Software License Agreement or Agreement for Licensed
     33 *     Product with Synopsys or any supplement thereto.  Permission is hereby
     34 *     granted, free of charge, to any person obtaining a copy of this software
     35 *     annotated with this license and the Software, to deal in the Software
     36 *     without restriction, including without limitation the rights to use,
     37 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     38 *     of the Software, and to permit persons to whom the Software is furnished
     39 *     to do so, subject to the following conditions:
     40 *
     41 *     The above copyright notice and this permission notice shall be included
     42 *     in all copies or substantial portions of the Software.
     43 *
     44 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
     45 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     46 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     47 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
     48 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     49 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     50 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     51 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     52 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     53 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     54 *     THE POSSIBILITY OF SUCH DAMAGE.
     55 *
     56 *
     57 * License 2: Modified BSD
     58 *
     59 * Copyright (c) 2016 Advanced Micro Devices, Inc.
     60 * All rights reserved.
     61 *
     62 * Redistribution and use in source and binary forms, with or without
     63 * modification, are permitted provided that the following conditions are met:
     64 *     * Redistributions of source code must retain the above copyright
     65 *       notice, this list of conditions and the following disclaimer.
     66 *     * Redistributions in binary form must reproduce the above copyright
     67 *       notice, this list of conditions and the following disclaimer in the
     68 *       documentation and/or other materials provided with the distribution.
     69 *     * Neither the name of Advanced Micro Devices, Inc. nor the
     70 *       names of its contributors may be used to endorse or promote products
     71 *       derived from this software without specific prior written permission.
     72 *
     73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     74 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     76 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
     77 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     79 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     80 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     81 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     82 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     83 *
     84 * This file incorporates work covered by the following copyright and
     85 * permission notice:
     86 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
     87 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
     88 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
     89 *     and you.
     90 *
     91 *     The Software IS NOT an item of Licensed Software or Licensed Product
     92 *     under any End User Software License Agreement or Agreement for Licensed
     93 *     Product with Synopsys or any supplement thereto.  Permission is hereby
     94 *     granted, free of charge, to any person obtaining a copy of this software
     95 *     annotated with this license and the Software, to deal in the Software
     96 *     without restriction, including without limitation the rights to use,
     97 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     98 *     of the Software, and to permit persons to whom the Software is furnished
     99 *     to do so, subject to the following conditions:
    100 *
    101 *     The above copyright notice and this permission notice shall be included
    102 *     in all copies or substantial portions of the Software.
    103 *
    104 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
    105 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
    106 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    107 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
    108 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    109 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    110 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    111 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    112 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    113 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
    114 *     THE POSSIBILITY OF SUCH DAMAGE.
    115 */
    116
    117#include <linux/module.h>
    118#include <linux/device.h>
    119#include <linux/pci.h>
    120#include <linux/log2.h>
    121
    122#include "xgbe.h"
    123#include "xgbe-common.h"
    124
    125static int xgbe_config_multi_msi(struct xgbe_prv_data *pdata)
    126{
    127	unsigned int vector_count;
    128	unsigned int i, j;
    129	int ret;
    130
    131	vector_count = XGBE_MSI_BASE_COUNT;
    132	vector_count += max(pdata->rx_ring_count,
    133			    pdata->tx_ring_count);
    134
    135	ret = pci_alloc_irq_vectors(pdata->pcidev, XGBE_MSI_MIN_COUNT,
    136				    vector_count, PCI_IRQ_MSI | PCI_IRQ_MSIX);
    137	if (ret < 0) {
    138		dev_info(pdata->dev, "multi MSI/MSI-X enablement failed\n");
    139		return ret;
    140	}
    141
    142	pdata->isr_as_tasklet = 1;
    143	pdata->irq_count = ret;
    144
    145	pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
    146	pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 1);
    147	pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 2);
    148	pdata->an_irq = pci_irq_vector(pdata->pcidev, 3);
    149
    150	for (i = XGBE_MSI_BASE_COUNT, j = 0; i < ret; i++, j++)
    151		pdata->channel_irq[j] = pci_irq_vector(pdata->pcidev, i);
    152	pdata->channel_irq_count = j;
    153
    154	pdata->per_channel_irq = 1;
    155	pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL;
    156
    157	if (netif_msg_probe(pdata))
    158		dev_dbg(pdata->dev, "multi %s interrupts enabled\n",
    159			pdata->pcidev->msix_enabled ? "MSI-X" : "MSI");
    160
    161	return 0;
    162}
    163
    164static int xgbe_config_irqs(struct xgbe_prv_data *pdata)
    165{
    166	int ret;
    167
    168	ret = xgbe_config_multi_msi(pdata);
    169	if (!ret)
    170		goto out;
    171
    172	ret = pci_alloc_irq_vectors(pdata->pcidev, 1, 1,
    173				    PCI_IRQ_LEGACY | PCI_IRQ_MSI);
    174	if (ret < 0) {
    175		dev_info(pdata->dev, "single IRQ enablement failed\n");
    176		return ret;
    177	}
    178
    179	pdata->isr_as_tasklet = pdata->pcidev->msi_enabled ? 1 : 0;
    180	pdata->irq_count = 1;
    181	pdata->channel_irq_count = 1;
    182
    183	pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
    184	pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 0);
    185	pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 0);
    186	pdata->an_irq = pci_irq_vector(pdata->pcidev, 0);
    187
    188	if (netif_msg_probe(pdata))
    189		dev_dbg(pdata->dev, "single %s interrupt enabled\n",
    190			pdata->pcidev->msi_enabled ?  "MSI" : "legacy");
    191
    192out:
    193	if (netif_msg_probe(pdata)) {
    194		unsigned int i;
    195
    196		dev_dbg(pdata->dev, " dev irq=%d\n", pdata->dev_irq);
    197		dev_dbg(pdata->dev, " ecc irq=%d\n", pdata->ecc_irq);
    198		dev_dbg(pdata->dev, " i2c irq=%d\n", pdata->i2c_irq);
    199		dev_dbg(pdata->dev, "  an irq=%d\n", pdata->an_irq);
    200		for (i = 0; i < pdata->channel_irq_count; i++)
    201			dev_dbg(pdata->dev, " dma%u irq=%d\n",
    202				i, pdata->channel_irq[i]);
    203	}
    204
    205	return 0;
    206}
    207
    208static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
    209{
    210	struct xgbe_prv_data *pdata;
    211	struct device *dev = &pdev->dev;
    212	void __iomem * const *iomap_table;
    213	struct pci_dev *rdev;
    214	unsigned int ma_lo, ma_hi;
    215	unsigned int reg;
    216	int bar_mask;
    217	int ret;
    218
    219	pdata = xgbe_alloc_pdata(dev);
    220	if (IS_ERR(pdata)) {
    221		ret = PTR_ERR(pdata);
    222		goto err_alloc;
    223	}
    224
    225	pdata->pcidev = pdev;
    226	pci_set_drvdata(pdev, pdata);
    227
    228	/* Get the version data */
    229	pdata->vdata = (struct xgbe_version_data *)id->driver_data;
    230
    231	ret = pcim_enable_device(pdev);
    232	if (ret) {
    233		dev_err(dev, "pcim_enable_device failed\n");
    234		goto err_pci_enable;
    235	}
    236
    237	/* Obtain the mmio areas for the device */
    238	bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
    239	ret = pcim_iomap_regions(pdev, bar_mask, XGBE_DRV_NAME);
    240	if (ret) {
    241		dev_err(dev, "pcim_iomap_regions failed\n");
    242		goto err_pci_enable;
    243	}
    244
    245	iomap_table = pcim_iomap_table(pdev);
    246	if (!iomap_table) {
    247		dev_err(dev, "pcim_iomap_table failed\n");
    248		ret = -ENOMEM;
    249		goto err_pci_enable;
    250	}
    251
    252	pdata->xgmac_regs = iomap_table[XGBE_XGMAC_BAR];
    253	if (!pdata->xgmac_regs) {
    254		dev_err(dev, "xgmac ioremap failed\n");
    255		ret = -ENOMEM;
    256		goto err_pci_enable;
    257	}
    258	pdata->xprop_regs = pdata->xgmac_regs + XGBE_MAC_PROP_OFFSET;
    259	pdata->xi2c_regs = pdata->xgmac_regs + XGBE_I2C_CTRL_OFFSET;
    260	if (netif_msg_probe(pdata)) {
    261		dev_dbg(dev, "xgmac_regs = %p\n", pdata->xgmac_regs);
    262		dev_dbg(dev, "xprop_regs = %p\n", pdata->xprop_regs);
    263		dev_dbg(dev, "xi2c_regs  = %p\n", pdata->xi2c_regs);
    264	}
    265
    266	pdata->xpcs_regs = iomap_table[XGBE_XPCS_BAR];
    267	if (!pdata->xpcs_regs) {
    268		dev_err(dev, "xpcs ioremap failed\n");
    269		ret = -ENOMEM;
    270		goto err_pci_enable;
    271	}
    272	if (netif_msg_probe(pdata))
    273		dev_dbg(dev, "xpcs_regs  = %p\n", pdata->xpcs_regs);
    274
    275	/* Set the PCS indirect addressing definition registers */
    276	rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
    277	if (rdev &&
    278	    (rdev->vendor == PCI_VENDOR_ID_AMD) && (rdev->device == 0x15d0)) {
    279		pdata->xpcs_window_def_reg = PCS_V2_RV_WINDOW_DEF;
    280		pdata->xpcs_window_sel_reg = PCS_V2_RV_WINDOW_SELECT;
    281	} else if (rdev && (rdev->vendor == PCI_VENDOR_ID_AMD) &&
    282		   (rdev->device == 0x14b5)) {
    283		pdata->xpcs_window_def_reg = PCS_V2_YC_WINDOW_DEF;
    284		pdata->xpcs_window_sel_reg = PCS_V2_YC_WINDOW_SELECT;
    285
    286		/* Yellow Carp devices do not need cdr workaround */
    287		pdata->vdata->an_cdr_workaround = 0;
    288	} else {
    289		pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
    290		pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
    291	}
    292	pci_dev_put(rdev);
    293
    294	/* Configure the PCS indirect addressing support */
    295	reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
    296	pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET);
    297	pdata->xpcs_window <<= 6;
    298	pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
    299	pdata->xpcs_window_size = 1 << (pdata->xpcs_window_size + 7);
    300	pdata->xpcs_window_mask = pdata->xpcs_window_size - 1;
    301	if (netif_msg_probe(pdata)) {
    302		dev_dbg(dev, "xpcs window def  = %#010x\n",
    303			pdata->xpcs_window_def_reg);
    304		dev_dbg(dev, "xpcs window sel  = %#010x\n",
    305			pdata->xpcs_window_sel_reg);
    306		dev_dbg(dev, "xpcs window      = %#010x\n",
    307			pdata->xpcs_window);
    308		dev_dbg(dev, "xpcs window size = %#010x\n",
    309			pdata->xpcs_window_size);
    310		dev_dbg(dev, "xpcs window mask = %#010x\n",
    311			pdata->xpcs_window_mask);
    312	}
    313
    314	pci_set_master(pdev);
    315
    316	/* Enable all interrupts in the hardware */
    317	XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff);
    318
    319	/* Retrieve the MAC address */
    320	ma_lo = XP_IOREAD(pdata, XP_MAC_ADDR_LO);
    321	ma_hi = XP_IOREAD(pdata, XP_MAC_ADDR_HI);
    322	pdata->mac_addr[0] = ma_lo & 0xff;
    323	pdata->mac_addr[1] = (ma_lo >> 8) & 0xff;
    324	pdata->mac_addr[2] = (ma_lo >> 16) & 0xff;
    325	pdata->mac_addr[3] = (ma_lo >> 24) & 0xff;
    326	pdata->mac_addr[4] = ma_hi & 0xff;
    327	pdata->mac_addr[5] = (ma_hi >> 8) & 0xff;
    328	if (!XP_GET_BITS(ma_hi, XP_MAC_ADDR_HI, VALID) ||
    329	    !is_valid_ether_addr(pdata->mac_addr)) {
    330		dev_err(dev, "invalid mac address\n");
    331		ret = -EINVAL;
    332		goto err_pci_enable;
    333	}
    334
    335	/* Clock settings */
    336	pdata->sysclk_rate = XGBE_V2_DMA_CLOCK_FREQ;
    337	pdata->ptpclk_rate = XGBE_V2_PTP_CLOCK_FREQ;
    338
    339	/* Set the DMA coherency values */
    340	pdata->coherent = 1;
    341	pdata->arcr = XGBE_DMA_PCI_ARCR;
    342	pdata->awcr = XGBE_DMA_PCI_AWCR;
    343	pdata->awarcr = XGBE_DMA_PCI_AWARCR;
    344
    345	/* Read the port property registers */
    346	pdata->pp0 = XP_IOREAD(pdata, XP_PROP_0);
    347	pdata->pp1 = XP_IOREAD(pdata, XP_PROP_1);
    348	pdata->pp2 = XP_IOREAD(pdata, XP_PROP_2);
    349	pdata->pp3 = XP_IOREAD(pdata, XP_PROP_3);
    350	pdata->pp4 = XP_IOREAD(pdata, XP_PROP_4);
    351	if (netif_msg_probe(pdata)) {
    352		dev_dbg(dev, "port property 0 = %#010x\n", pdata->pp0);
    353		dev_dbg(dev, "port property 1 = %#010x\n", pdata->pp1);
    354		dev_dbg(dev, "port property 2 = %#010x\n", pdata->pp2);
    355		dev_dbg(dev, "port property 3 = %#010x\n", pdata->pp3);
    356		dev_dbg(dev, "port property 4 = %#010x\n", pdata->pp4);
    357	}
    358
    359	/* Set the maximum channels and queues */
    360	pdata->tx_max_channel_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
    361						  MAX_TX_DMA);
    362	pdata->rx_max_channel_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
    363						  MAX_RX_DMA);
    364	pdata->tx_max_q_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
    365					    MAX_TX_QUEUES);
    366	pdata->rx_max_q_count = XP_GET_BITS(pdata->pp1, XP_PROP_1,
    367					    MAX_RX_QUEUES);
    368	if (netif_msg_probe(pdata)) {
    369		dev_dbg(dev, "max tx/rx channel count = %u/%u\n",
    370			pdata->tx_max_channel_count,
    371			pdata->rx_max_channel_count);
    372		dev_dbg(dev, "max tx/rx hw queue count = %u/%u\n",
    373			pdata->tx_max_q_count, pdata->rx_max_q_count);
    374	}
    375
    376	/* Set the hardware channel and queue counts */
    377	xgbe_set_counts(pdata);
    378
    379	/* Set the maximum fifo amounts */
    380	pdata->tx_max_fifo_size = XP_GET_BITS(pdata->pp2, XP_PROP_2,
    381					      TX_FIFO_SIZE);
    382	pdata->tx_max_fifo_size *= 16384;
    383	pdata->tx_max_fifo_size = min(pdata->tx_max_fifo_size,
    384				      pdata->vdata->tx_max_fifo_size);
    385	pdata->rx_max_fifo_size = XP_GET_BITS(pdata->pp2, XP_PROP_2,
    386					      RX_FIFO_SIZE);
    387	pdata->rx_max_fifo_size *= 16384;
    388	pdata->rx_max_fifo_size = min(pdata->rx_max_fifo_size,
    389				      pdata->vdata->rx_max_fifo_size);
    390	if (netif_msg_probe(pdata))
    391		dev_dbg(dev, "max tx/rx max fifo size = %u/%u\n",
    392			pdata->tx_max_fifo_size, pdata->rx_max_fifo_size);
    393
    394	/* Configure interrupt support */
    395	ret = xgbe_config_irqs(pdata);
    396	if (ret)
    397		goto err_pci_enable;
    398
    399	/* Configure the netdev resource */
    400	ret = xgbe_config_netdev(pdata);
    401	if (ret)
    402		goto err_irq_vectors;
    403
    404	netdev_notice(pdata->netdev, "net device enabled\n");
    405
    406	return 0;
    407
    408err_irq_vectors:
    409	pci_free_irq_vectors(pdata->pcidev);
    410
    411err_pci_enable:
    412	xgbe_free_pdata(pdata);
    413
    414err_alloc:
    415	dev_notice(dev, "net device not enabled\n");
    416
    417	return ret;
    418}
    419
    420static void xgbe_pci_remove(struct pci_dev *pdev)
    421{
    422	struct xgbe_prv_data *pdata = pci_get_drvdata(pdev);
    423
    424	xgbe_deconfig_netdev(pdata);
    425
    426	pci_free_irq_vectors(pdata->pcidev);
    427
    428	/* Disable all interrupts in the hardware */
    429	XP_IOWRITE(pdata, XP_INT_EN, 0x0);
    430
    431	xgbe_free_pdata(pdata);
    432}
    433
    434static int __maybe_unused xgbe_pci_suspend(struct device *dev)
    435{
    436	struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
    437	struct net_device *netdev = pdata->netdev;
    438	int ret = 0;
    439
    440	if (netif_running(netdev))
    441		ret = xgbe_powerdown(netdev, XGMAC_DRIVER_CONTEXT);
    442
    443	pdata->lpm_ctrl = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
    444	pdata->lpm_ctrl |= MDIO_CTRL1_LPOWER;
    445	XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
    446
    447	return ret;
    448}
    449
    450static int __maybe_unused xgbe_pci_resume(struct device *dev)
    451{
    452	struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
    453	struct net_device *netdev = pdata->netdev;
    454	int ret = 0;
    455
    456	XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff);
    457
    458	pdata->lpm_ctrl &= ~MDIO_CTRL1_LPOWER;
    459	XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
    460
    461	if (netif_running(netdev)) {
    462		ret = xgbe_powerup(netdev, XGMAC_DRIVER_CONTEXT);
    463
    464		/* Schedule a restart in case the link or phy state changed
    465		 * while we were powered down.
    466		 */
    467		schedule_work(&pdata->restart_work);
    468	}
    469
    470	return ret;
    471}
    472
    473static struct xgbe_version_data xgbe_v2a = {
    474	.init_function_ptrs_phy_impl	= xgbe_init_function_ptrs_phy_v2,
    475	.xpcs_access			= XGBE_XPCS_ACCESS_V2,
    476	.mmc_64bit			= 1,
    477	.tx_max_fifo_size		= 229376,
    478	.rx_max_fifo_size		= 229376,
    479	.tx_tstamp_workaround		= 1,
    480	.ecc_support			= 1,
    481	.i2c_support			= 1,
    482	.irq_reissue_support		= 1,
    483	.tx_desc_prefetch		= 5,
    484	.rx_desc_prefetch		= 5,
    485	.an_cdr_workaround		= 1,
    486};
    487
    488static struct xgbe_version_data xgbe_v2b = {
    489	.init_function_ptrs_phy_impl	= xgbe_init_function_ptrs_phy_v2,
    490	.xpcs_access			= XGBE_XPCS_ACCESS_V2,
    491	.mmc_64bit			= 1,
    492	.tx_max_fifo_size		= 65536,
    493	.rx_max_fifo_size		= 65536,
    494	.tx_tstamp_workaround		= 1,
    495	.ecc_support			= 1,
    496	.i2c_support			= 1,
    497	.irq_reissue_support		= 1,
    498	.tx_desc_prefetch		= 5,
    499	.rx_desc_prefetch		= 5,
    500	.an_cdr_workaround		= 1,
    501};
    502
    503static const struct pci_device_id xgbe_pci_table[] = {
    504	{ PCI_VDEVICE(AMD, 0x1458),
    505	  .driver_data = (kernel_ulong_t)&xgbe_v2a },
    506	{ PCI_VDEVICE(AMD, 0x1459),
    507	  .driver_data = (kernel_ulong_t)&xgbe_v2b },
    508	/* Last entry must be zero */
    509	{ 0, }
    510};
    511MODULE_DEVICE_TABLE(pci, xgbe_pci_table);
    512
    513static SIMPLE_DEV_PM_OPS(xgbe_pci_pm_ops, xgbe_pci_suspend, xgbe_pci_resume);
    514
    515static struct pci_driver xgbe_driver = {
    516	.name = XGBE_DRV_NAME,
    517	.id_table = xgbe_pci_table,
    518	.probe = xgbe_pci_probe,
    519	.remove = xgbe_pci_remove,
    520	.driver = {
    521		.pm = &xgbe_pci_pm_ops,
    522	}
    523};
    524
    525int xgbe_pci_init(void)
    526{
    527	return pci_register_driver(&xgbe_driver);
    528}
    529
    530void xgbe_pci_exit(void)
    531{
    532	pci_unregister_driver(&xgbe_driver);
    533}