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
->irq_count
= ret
;
144 pdata
->dev_irq
= pci_irq_vector(pdata
->pcidev
, 0);
145 pdata
->ecc_irq
= pci_irq_vector(pdata
->pcidev
, 1);
146 pdata
->i2c_irq
= pci_irq_vector(pdata
->pcidev
, 2);
147 pdata
->an_irq
= pci_irq_vector(pdata
->pcidev
, 3);
149 for (i
= XGBE_MSI_BASE_COUNT
, j
= 0; i
< ret
; i
++, j
++)
150 pdata
->channel_irq
[j
] = pci_irq_vector(pdata
->pcidev
, i
);
151 pdata
->channel_irq_count
= j
;
153 pdata
->per_channel_irq
= 1;
154 pdata
->channel_irq_mode
= XGBE_IRQ_MODE_LEVEL
;
156 if (netif_msg_probe(pdata
))
157 dev_dbg(pdata
->dev
, "multi %s interrupts enabled\n",
158 pdata
->pcidev
->msix_enabled
? "MSI-X" : "MSI");
163 static int xgbe_config_irqs(struct xgbe_prv_data
*pdata
)
167 ret
= xgbe_config_multi_msi(pdata
);
171 ret
= pci_alloc_irq_vectors(pdata
->pcidev
, 1, 1,
172 PCI_IRQ_LEGACY
| PCI_IRQ_MSI
);
174 dev_info(pdata
->dev
, "single IRQ enablement failed\n");
178 pdata
->irq_count
= 1;
179 pdata
->channel_irq_count
= 1;
181 pdata
->dev_irq
= pci_irq_vector(pdata
->pcidev
, 0);
182 pdata
->ecc_irq
= pci_irq_vector(pdata
->pcidev
, 0);
183 pdata
->i2c_irq
= pci_irq_vector(pdata
->pcidev
, 0);
184 pdata
->an_irq
= pci_irq_vector(pdata
->pcidev
, 0);
186 if (netif_msg_probe(pdata
))
187 dev_dbg(pdata
->dev
, "single %s interrupt enabled\n",
188 pdata
->pcidev
->msi_enabled
? "MSI" : "legacy");
191 if (netif_msg_probe(pdata
)) {
194 dev_dbg(pdata
->dev
, " dev irq=%d\n", pdata
->dev_irq
);
195 dev_dbg(pdata
->dev
, " ecc irq=%d\n", pdata
->ecc_irq
);
196 dev_dbg(pdata
->dev
, " i2c irq=%d\n", pdata
->i2c_irq
);
197 dev_dbg(pdata
->dev
, " an irq=%d\n", pdata
->an_irq
);
198 for (i
= 0; i
< pdata
->channel_irq_count
; i
++)
199 dev_dbg(pdata
->dev
, " dma%u irq=%d\n",
200 i
, pdata
->channel_irq
[i
]);
206 static int xgbe_pci_probe(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
208 struct xgbe_prv_data
*pdata
;
209 struct device
*dev
= &pdev
->dev
;
210 void __iomem
* const *iomap_table
;
211 struct pci_dev
*rdev
;
212 unsigned int ma_lo
, ma_hi
;
217 pdata
= xgbe_alloc_pdata(dev
);
219 ret
= PTR_ERR(pdata
);
223 pdata
->pcidev
= pdev
;
224 pci_set_drvdata(pdev
, pdata
);
226 /* Get the version data */
227 pdata
->vdata
= (struct xgbe_version_data
*)id
->driver_data
;
229 ret
= pcim_enable_device(pdev
);
231 dev_err(dev
, "pcim_enable_device failed\n");
235 /* Obtain the mmio areas for the device */
236 bar_mask
= pci_select_bars(pdev
, IORESOURCE_MEM
);
237 ret
= pcim_iomap_regions(pdev
, bar_mask
, XGBE_DRV_NAME
);
239 dev_err(dev
, "pcim_iomap_regions failed\n");
243 iomap_table
= pcim_iomap_table(pdev
);
245 dev_err(dev
, "pcim_iomap_table failed\n");
250 pdata
->xgmac_regs
= iomap_table
[XGBE_XGMAC_BAR
];
251 if (!pdata
->xgmac_regs
) {
252 dev_err(dev
, "xgmac ioremap failed\n");
256 pdata
->xprop_regs
= pdata
->xgmac_regs
+ XGBE_MAC_PROP_OFFSET
;
257 pdata
->xi2c_regs
= pdata
->xgmac_regs
+ XGBE_I2C_CTRL_OFFSET
;
258 if (netif_msg_probe(pdata
)) {
259 dev_dbg(dev
, "xgmac_regs = %p\n", pdata
->xgmac_regs
);
260 dev_dbg(dev
, "xprop_regs = %p\n", pdata
->xprop_regs
);
261 dev_dbg(dev
, "xi2c_regs = %p\n", pdata
->xi2c_regs
);
264 pdata
->xpcs_regs
= iomap_table
[XGBE_XPCS_BAR
];
265 if (!pdata
->xpcs_regs
) {
266 dev_err(dev
, "xpcs ioremap failed\n");
270 if (netif_msg_probe(pdata
))
271 dev_dbg(dev
, "xpcs_regs = %p\n", pdata
->xpcs_regs
);
273 /* Set the PCS indirect addressing definition registers */
274 rdev
= pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
276 (rdev
->vendor
== PCI_VENDOR_ID_AMD
) && (rdev
->device
== 0x15d0)) {
277 pdata
->xpcs_window_def_reg
= PCS_V2_RV_WINDOW_DEF
;
278 pdata
->xpcs_window_sel_reg
= PCS_V2_RV_WINDOW_SELECT
;
280 pdata
->xpcs_window_def_reg
= PCS_V2_WINDOW_DEF
;
281 pdata
->xpcs_window_sel_reg
= PCS_V2_WINDOW_SELECT
;
285 /* Configure the PCS indirect addressing support */
286 reg
= XPCS32_IOREAD(pdata
, pdata
->xpcs_window_def_reg
);
287 pdata
->xpcs_window
= XPCS_GET_BITS(reg
, PCS_V2_WINDOW_DEF
, OFFSET
);
288 pdata
->xpcs_window
<<= 6;
289 pdata
->xpcs_window_size
= XPCS_GET_BITS(reg
, PCS_V2_WINDOW_DEF
, SIZE
);
290 pdata
->xpcs_window_size
= 1 << (pdata
->xpcs_window_size
+ 7);
291 pdata
->xpcs_window_mask
= pdata
->xpcs_window_size
- 1;
292 if (netif_msg_probe(pdata
)) {
293 dev_dbg(dev
, "xpcs window = %#010x\n",
295 dev_dbg(dev
, "xpcs window size = %#010x\n",
296 pdata
->xpcs_window_size
);
297 dev_dbg(dev
, "xpcs window mask = %#010x\n",
298 pdata
->xpcs_window_mask
);
301 pci_set_master(pdev
);
303 /* Enable all interrupts in the hardware */
304 XP_IOWRITE(pdata
, XP_INT_EN
, 0x1fffff);
306 /* Retrieve the MAC address */
307 ma_lo
= XP_IOREAD(pdata
, XP_MAC_ADDR_LO
);
308 ma_hi
= XP_IOREAD(pdata
, XP_MAC_ADDR_HI
);
309 pdata
->mac_addr
[0] = ma_lo
& 0xff;
310 pdata
->mac_addr
[1] = (ma_lo
>> 8) & 0xff;
311 pdata
->mac_addr
[2] = (ma_lo
>> 16) & 0xff;
312 pdata
->mac_addr
[3] = (ma_lo
>> 24) & 0xff;
313 pdata
->mac_addr
[4] = ma_hi
& 0xff;
314 pdata
->mac_addr
[5] = (ma_hi
>> 8) & 0xff;
315 if (!XP_GET_BITS(ma_hi
, XP_MAC_ADDR_HI
, VALID
) ||
316 !is_valid_ether_addr(pdata
->mac_addr
)) {
317 dev_err(dev
, "invalid mac address\n");
323 pdata
->sysclk_rate
= XGBE_V2_DMA_CLOCK_FREQ
;
324 pdata
->ptpclk_rate
= XGBE_V2_PTP_CLOCK_FREQ
;
326 /* Set the DMA coherency values */
328 pdata
->axdomain
= XGBE_DMA_OS_AXDOMAIN
;
329 pdata
->arcache
= XGBE_DMA_OS_ARCACHE
;
330 pdata
->awcache
= XGBE_DMA_OS_AWCACHE
;
332 /* Set the maximum channels and queues */
333 reg
= XP_IOREAD(pdata
, XP_PROP_1
);
334 pdata
->tx_max_channel_count
= XP_GET_BITS(reg
, XP_PROP_1
, MAX_TX_DMA
);
335 pdata
->rx_max_channel_count
= XP_GET_BITS(reg
, XP_PROP_1
, MAX_RX_DMA
);
336 pdata
->tx_max_q_count
= XP_GET_BITS(reg
, XP_PROP_1
, MAX_TX_QUEUES
);
337 pdata
->rx_max_q_count
= XP_GET_BITS(reg
, XP_PROP_1
, MAX_RX_QUEUES
);
338 if (netif_msg_probe(pdata
)) {
339 dev_dbg(dev
, "max tx/rx channel count = %u/%u\n",
340 pdata
->tx_max_channel_count
,
341 pdata
->tx_max_channel_count
);
342 dev_dbg(dev
, "max tx/rx hw queue count = %u/%u\n",
343 pdata
->tx_max_q_count
, pdata
->rx_max_q_count
);
346 /* Set the hardware channel and queue counts */
347 xgbe_set_counts(pdata
);
349 /* Set the maximum fifo amounts */
350 reg
= XP_IOREAD(pdata
, XP_PROP_2
);
351 pdata
->tx_max_fifo_size
= XP_GET_BITS(reg
, XP_PROP_2
, TX_FIFO_SIZE
);
352 pdata
->tx_max_fifo_size
*= 16384;
353 pdata
->tx_max_fifo_size
= min(pdata
->tx_max_fifo_size
,
354 pdata
->vdata
->tx_max_fifo_size
);
355 pdata
->rx_max_fifo_size
= XP_GET_BITS(reg
, XP_PROP_2
, RX_FIFO_SIZE
);
356 pdata
->rx_max_fifo_size
*= 16384;
357 pdata
->rx_max_fifo_size
= min(pdata
->rx_max_fifo_size
,
358 pdata
->vdata
->rx_max_fifo_size
);
359 if (netif_msg_probe(pdata
))
360 dev_dbg(dev
, "max tx/rx max fifo size = %u/%u\n",
361 pdata
->tx_max_fifo_size
, pdata
->rx_max_fifo_size
);
363 /* Configure interrupt support */
364 ret
= xgbe_config_irqs(pdata
);
368 /* Configure the netdev resource */
369 ret
= xgbe_config_netdev(pdata
);
371 goto err_irq_vectors
;
373 netdev_notice(pdata
->netdev
, "net device enabled\n");
378 pci_free_irq_vectors(pdata
->pcidev
);
381 xgbe_free_pdata(pdata
);
384 dev_notice(dev
, "net device not enabled\n");
389 static void xgbe_pci_remove(struct pci_dev
*pdev
)
391 struct xgbe_prv_data
*pdata
= pci_get_drvdata(pdev
);
393 xgbe_deconfig_netdev(pdata
);
395 pci_free_irq_vectors(pdata
->pcidev
);
397 xgbe_free_pdata(pdata
);
401 static int xgbe_pci_suspend(struct pci_dev
*pdev
, pm_message_t state
)
403 struct xgbe_prv_data
*pdata
= pci_get_drvdata(pdev
);
404 struct net_device
*netdev
= pdata
->netdev
;
407 if (netif_running(netdev
))
408 ret
= xgbe_powerdown(netdev
, XGMAC_DRIVER_CONTEXT
);
410 pdata
->lpm_ctrl
= XMDIO_READ(pdata
, MDIO_MMD_PCS
, MDIO_CTRL1
);
411 pdata
->lpm_ctrl
|= MDIO_CTRL1_LPOWER
;
412 XMDIO_WRITE(pdata
, MDIO_MMD_PCS
, MDIO_CTRL1
, pdata
->lpm_ctrl
);
417 static int xgbe_pci_resume(struct pci_dev
*pdev
)
419 struct xgbe_prv_data
*pdata
= pci_get_drvdata(pdev
);
420 struct net_device
*netdev
= pdata
->netdev
;
423 pdata
->lpm_ctrl
&= ~MDIO_CTRL1_LPOWER
;
424 XMDIO_WRITE(pdata
, MDIO_MMD_PCS
, MDIO_CTRL1
, pdata
->lpm_ctrl
);
426 if (netif_running(netdev
)) {
427 ret
= xgbe_powerup(netdev
, XGMAC_DRIVER_CONTEXT
);
429 /* Schedule a restart in case the link or phy state changed
430 * while we were powered down.
432 schedule_work(&pdata
->restart_work
);
437 #endif /* CONFIG_PM */
439 static const struct xgbe_version_data xgbe_v2a
= {
440 .init_function_ptrs_phy_impl
= xgbe_init_function_ptrs_phy_v2
,
441 .xpcs_access
= XGBE_XPCS_ACCESS_V2
,
443 .tx_max_fifo_size
= 229376,
444 .rx_max_fifo_size
= 229376,
445 .tx_tstamp_workaround
= 1,
450 static const struct xgbe_version_data xgbe_v2b
= {
451 .init_function_ptrs_phy_impl
= xgbe_init_function_ptrs_phy_v2
,
452 .xpcs_access
= XGBE_XPCS_ACCESS_V2
,
454 .tx_max_fifo_size
= 65536,
455 .rx_max_fifo_size
= 65536,
456 .tx_tstamp_workaround
= 1,
461 static const struct pci_device_id xgbe_pci_table
[] = {
462 { PCI_VDEVICE(AMD
, 0x1458),
463 .driver_data
= (kernel_ulong_t
)&xgbe_v2a
},
464 { PCI_VDEVICE(AMD
, 0x1459),
465 .driver_data
= (kernel_ulong_t
)&xgbe_v2b
},
466 /* Last entry must be zero */
469 MODULE_DEVICE_TABLE(pci
, xgbe_pci_table
);
471 static struct pci_driver xgbe_driver
= {
472 .name
= XGBE_DRV_NAME
,
473 .id_table
= xgbe_pci_table
,
474 .probe
= xgbe_pci_probe
,
475 .remove
= xgbe_pci_remove
,
477 .suspend
= xgbe_pci_suspend
,
478 .resume
= xgbe_pci_resume
,
482 int xgbe_pci_init(void)
484 return pci_register_driver(&xgbe_driver
);
487 void xgbe_pci_exit(void)
489 pci_unregister_driver(&xgbe_driver
);