2 * AMD 10Gb Ethernet driver
4 * This file is available to you under your choice of the following two
9 * Copyright (c) 2016 Advanced Micro Devices, Inc.
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.
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.
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/>.
24 * This file incorporates work covered by the following copyright and
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
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:
41 * The above copyright notice and this permission notice shall be included
42 * in all copies or substantial portions of the Software.
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.
57 * License 2: Modified BSD
59 * Copyright (c) 2016 Advanced Micro Devices, Inc.
60 * All rights reserved.
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.
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.
84 * This file incorporates work covered by the following copyright and
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
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:
101 * The above copyright notice and this permission notice shall be included
102 * in all copies or substantial portions of the Software.
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.
117 #include <linux/module.h>
118 #include <linux/device.h>
119 #include <linux/pci.h>
120 #include <linux/log2.h>
123 #include "xgbe-common.h"
125 static int xgbe_config_multi_msi(struct xgbe_prv_data
*pdata
)
127 unsigned int vector_count
;
131 vector_count
= XGBE_MSI_BASE_COUNT
;
132 vector_count
+= max(pdata
->rx_ring_count
,
133 pdata
->tx_ring_count
);
135 ret
= pci_alloc_irq_vectors(pdata
->pcidev
, XGBE_MSI_MIN_COUNT
,
136 vector_count
, PCI_IRQ_MSI
| PCI_IRQ_MSIX
);
138 dev_info(pdata
->dev
, "multi MSI/MSI-X enablement failed\n");
142 pdata
->isr_as_tasklet
= 1;
143 pdata
->irq_count
= ret
;
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);
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
;
154 pdata
->per_channel_irq
= 1;
155 pdata
->channel_irq_mode
= XGBE_IRQ_MODE_LEVEL
;
157 if (netif_msg_probe(pdata
))
158 dev_dbg(pdata
->dev
, "multi %s interrupts enabled\n",
159 pdata
->pcidev
->msix_enabled
? "MSI-X" : "MSI");
164 static int xgbe_config_irqs(struct xgbe_prv_data
*pdata
)
168 ret
= xgbe_config_multi_msi(pdata
);
172 ret
= pci_alloc_irq_vectors(pdata
->pcidev
, 1, 1,
173 PCI_IRQ_LEGACY
| PCI_IRQ_MSI
);
175 dev_info(pdata
->dev
, "single IRQ enablement failed\n");
179 pdata
->isr_as_tasklet
= pdata
->pcidev
->msi_enabled
? 1 : 0;
180 pdata
->irq_count
= 1;
181 pdata
->channel_irq_count
= 1;
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);
188 if (netif_msg_probe(pdata
))
189 dev_dbg(pdata
->dev
, "single %s interrupt enabled\n",
190 pdata
->pcidev
->msi_enabled
? "MSI" : "legacy");
193 if (netif_msg_probe(pdata
)) {
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
]);
208 static int xgbe_pci_probe(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
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
;
219 pdata
= xgbe_alloc_pdata(dev
);
221 ret
= PTR_ERR(pdata
);
225 pdata
->pcidev
= pdev
;
226 pci_set_drvdata(pdev
, pdata
);
228 /* Get the version data */
229 pdata
->vdata
= (struct xgbe_version_data
*)id
->driver_data
;
231 ret
= pcim_enable_device(pdev
);
233 dev_err(dev
, "pcim_enable_device failed\n");
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
);
241 dev_err(dev
, "pcim_iomap_regions failed\n");
245 iomap_table
= pcim_iomap_table(pdev
);
247 dev_err(dev
, "pcim_iomap_table failed\n");
252 pdata
->xgmac_regs
= iomap_table
[XGBE_XGMAC_BAR
];
253 if (!pdata
->xgmac_regs
) {
254 dev_err(dev
, "xgmac ioremap failed\n");
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
);
266 pdata
->xpcs_regs
= iomap_table
[XGBE_XPCS_BAR
];
267 if (!pdata
->xpcs_regs
) {
268 dev_err(dev
, "xpcs ioremap failed\n");
272 if (netif_msg_probe(pdata
))
273 dev_dbg(dev
, "xpcs_regs = %p\n", pdata
->xpcs_regs
);
275 /* Set the PCS indirect addressing definition registers */
276 rdev
= pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
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
;
282 pdata
->xpcs_window_def_reg
= PCS_V2_WINDOW_DEF
;
283 pdata
->xpcs_window_sel_reg
= PCS_V2_WINDOW_SELECT
;
287 /* Configure the PCS indirect addressing support */
288 reg
= XPCS32_IOREAD(pdata
, pdata
->xpcs_window_def_reg
);
289 pdata
->xpcs_window
= XPCS_GET_BITS(reg
, PCS_V2_WINDOW_DEF
, OFFSET
);
290 pdata
->xpcs_window
<<= 6;
291 pdata
->xpcs_window_size
= XPCS_GET_BITS(reg
, PCS_V2_WINDOW_DEF
, SIZE
);
292 pdata
->xpcs_window_size
= 1 << (pdata
->xpcs_window_size
+ 7);
293 pdata
->xpcs_window_mask
= pdata
->xpcs_window_size
- 1;
294 if (netif_msg_probe(pdata
)) {
295 dev_dbg(dev
, "xpcs window def = %#010x\n",
296 pdata
->xpcs_window_def_reg
);
297 dev_dbg(dev
, "xpcs window sel = %#010x\n",
298 pdata
->xpcs_window_sel_reg
);
299 dev_dbg(dev
, "xpcs window = %#010x\n",
301 dev_dbg(dev
, "xpcs window size = %#010x\n",
302 pdata
->xpcs_window_size
);
303 dev_dbg(dev
, "xpcs window mask = %#010x\n",
304 pdata
->xpcs_window_mask
);
307 pci_set_master(pdev
);
309 /* Enable all interrupts in the hardware */
310 XP_IOWRITE(pdata
, XP_INT_EN
, 0x1fffff);
312 /* Retrieve the MAC address */
313 ma_lo
= XP_IOREAD(pdata
, XP_MAC_ADDR_LO
);
314 ma_hi
= XP_IOREAD(pdata
, XP_MAC_ADDR_HI
);
315 pdata
->mac_addr
[0] = ma_lo
& 0xff;
316 pdata
->mac_addr
[1] = (ma_lo
>> 8) & 0xff;
317 pdata
->mac_addr
[2] = (ma_lo
>> 16) & 0xff;
318 pdata
->mac_addr
[3] = (ma_lo
>> 24) & 0xff;
319 pdata
->mac_addr
[4] = ma_hi
& 0xff;
320 pdata
->mac_addr
[5] = (ma_hi
>> 8) & 0xff;
321 if (!XP_GET_BITS(ma_hi
, XP_MAC_ADDR_HI
, VALID
) ||
322 !is_valid_ether_addr(pdata
->mac_addr
)) {
323 dev_err(dev
, "invalid mac address\n");
329 pdata
->sysclk_rate
= XGBE_V2_DMA_CLOCK_FREQ
;
330 pdata
->ptpclk_rate
= XGBE_V2_PTP_CLOCK_FREQ
;
332 /* Set the DMA coherency values */
334 pdata
->arcr
= XGBE_DMA_PCI_ARCR
;
335 pdata
->awcr
= XGBE_DMA_PCI_AWCR
;
336 pdata
->awarcr
= XGBE_DMA_PCI_AWARCR
;
338 /* Set the maximum channels and queues */
339 reg
= XP_IOREAD(pdata
, XP_PROP_1
);
340 pdata
->tx_max_channel_count
= XP_GET_BITS(reg
, XP_PROP_1
, MAX_TX_DMA
);
341 pdata
->rx_max_channel_count
= XP_GET_BITS(reg
, XP_PROP_1
, MAX_RX_DMA
);
342 pdata
->tx_max_q_count
= XP_GET_BITS(reg
, XP_PROP_1
, MAX_TX_QUEUES
);
343 pdata
->rx_max_q_count
= XP_GET_BITS(reg
, XP_PROP_1
, MAX_RX_QUEUES
);
344 if (netif_msg_probe(pdata
)) {
345 dev_dbg(dev
, "max tx/rx channel count = %u/%u\n",
346 pdata
->tx_max_channel_count
,
347 pdata
->tx_max_channel_count
);
348 dev_dbg(dev
, "max tx/rx hw queue count = %u/%u\n",
349 pdata
->tx_max_q_count
, pdata
->rx_max_q_count
);
352 /* Set the hardware channel and queue counts */
353 xgbe_set_counts(pdata
);
355 /* Set the maximum fifo amounts */
356 reg
= XP_IOREAD(pdata
, XP_PROP_2
);
357 pdata
->tx_max_fifo_size
= XP_GET_BITS(reg
, XP_PROP_2
, TX_FIFO_SIZE
);
358 pdata
->tx_max_fifo_size
*= 16384;
359 pdata
->tx_max_fifo_size
= min(pdata
->tx_max_fifo_size
,
360 pdata
->vdata
->tx_max_fifo_size
);
361 pdata
->rx_max_fifo_size
= XP_GET_BITS(reg
, XP_PROP_2
, RX_FIFO_SIZE
);
362 pdata
->rx_max_fifo_size
*= 16384;
363 pdata
->rx_max_fifo_size
= min(pdata
->rx_max_fifo_size
,
364 pdata
->vdata
->rx_max_fifo_size
);
365 if (netif_msg_probe(pdata
))
366 dev_dbg(dev
, "max tx/rx max fifo size = %u/%u\n",
367 pdata
->tx_max_fifo_size
, pdata
->rx_max_fifo_size
);
369 /* Configure interrupt support */
370 ret
= xgbe_config_irqs(pdata
);
374 /* Configure the netdev resource */
375 ret
= xgbe_config_netdev(pdata
);
377 goto err_irq_vectors
;
379 netdev_notice(pdata
->netdev
, "net device enabled\n");
384 pci_free_irq_vectors(pdata
->pcidev
);
387 xgbe_free_pdata(pdata
);
390 dev_notice(dev
, "net device not enabled\n");
395 static void xgbe_pci_remove(struct pci_dev
*pdev
)
397 struct xgbe_prv_data
*pdata
= pci_get_drvdata(pdev
);
399 xgbe_deconfig_netdev(pdata
);
401 pci_free_irq_vectors(pdata
->pcidev
);
403 xgbe_free_pdata(pdata
);
407 static int xgbe_pci_suspend(struct pci_dev
*pdev
, pm_message_t state
)
409 struct xgbe_prv_data
*pdata
= pci_get_drvdata(pdev
);
410 struct net_device
*netdev
= pdata
->netdev
;
413 if (netif_running(netdev
))
414 ret
= xgbe_powerdown(netdev
, XGMAC_DRIVER_CONTEXT
);
416 pdata
->lpm_ctrl
= XMDIO_READ(pdata
, MDIO_MMD_PCS
, MDIO_CTRL1
);
417 pdata
->lpm_ctrl
|= MDIO_CTRL1_LPOWER
;
418 XMDIO_WRITE(pdata
, MDIO_MMD_PCS
, MDIO_CTRL1
, pdata
->lpm_ctrl
);
423 static int xgbe_pci_resume(struct pci_dev
*pdev
)
425 struct xgbe_prv_data
*pdata
= pci_get_drvdata(pdev
);
426 struct net_device
*netdev
= pdata
->netdev
;
429 pdata
->lpm_ctrl
&= ~MDIO_CTRL1_LPOWER
;
430 XMDIO_WRITE(pdata
, MDIO_MMD_PCS
, MDIO_CTRL1
, pdata
->lpm_ctrl
);
432 if (netif_running(netdev
)) {
433 ret
= xgbe_powerup(netdev
, XGMAC_DRIVER_CONTEXT
);
435 /* Schedule a restart in case the link or phy state changed
436 * while we were powered down.
438 schedule_work(&pdata
->restart_work
);
443 #endif /* CONFIG_PM */
445 static const struct xgbe_version_data xgbe_v2a
= {
446 .init_function_ptrs_phy_impl
= xgbe_init_function_ptrs_phy_v2
,
447 .xpcs_access
= XGBE_XPCS_ACCESS_V2
,
449 .tx_max_fifo_size
= 229376,
450 .rx_max_fifo_size
= 229376,
451 .tx_tstamp_workaround
= 1,
454 .irq_reissue_support
= 1,
455 .tx_desc_prefetch
= 5,
456 .rx_desc_prefetch
= 5,
459 static const struct xgbe_version_data xgbe_v2b
= {
460 .init_function_ptrs_phy_impl
= xgbe_init_function_ptrs_phy_v2
,
461 .xpcs_access
= XGBE_XPCS_ACCESS_V2
,
463 .tx_max_fifo_size
= 65536,
464 .rx_max_fifo_size
= 65536,
465 .tx_tstamp_workaround
= 1,
468 .irq_reissue_support
= 1,
469 .tx_desc_prefetch
= 5,
470 .rx_desc_prefetch
= 5,
473 static const struct pci_device_id xgbe_pci_table
[] = {
474 { PCI_VDEVICE(AMD
, 0x1458),
475 .driver_data
= (kernel_ulong_t
)&xgbe_v2a
},
476 { PCI_VDEVICE(AMD
, 0x1459),
477 .driver_data
= (kernel_ulong_t
)&xgbe_v2b
},
478 /* Last entry must be zero */
481 MODULE_DEVICE_TABLE(pci
, xgbe_pci_table
);
483 static struct pci_driver xgbe_driver
= {
484 .name
= XGBE_DRV_NAME
,
485 .id_table
= xgbe_pci_table
,
486 .probe
= xgbe_pci_probe
,
487 .remove
= xgbe_pci_remove
,
489 .suspend
= xgbe_pci_suspend
,
490 .resume
= xgbe_pci_resume
,
494 int xgbe_pci_init(void)
496 return pci_register_driver(&xgbe_driver
);
499 void xgbe_pci_exit(void)
501 pci_unregister_driver(&xgbe_driver
);