xref: /linux/drivers/net/ethernet/wangxun/ngbevf/ngbevf_main.c (revision a0008a3658a34a54e77f2568bdaa2626233b1459)
1*a0008a36SMengyuan Lou // SPDX-License-Identifier: GPL-2.0
2*a0008a36SMengyuan Lou /* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */
3*a0008a36SMengyuan Lou 
4*a0008a36SMengyuan Lou #include <linux/types.h>
5*a0008a36SMengyuan Lou #include <linux/module.h>
6*a0008a36SMengyuan Lou #include <linux/pci.h>
7*a0008a36SMengyuan Lou #include <linux/netdevice.h>
8*a0008a36SMengyuan Lou #include <linux/string.h>
9*a0008a36SMengyuan Lou #include <linux/etherdevice.h>
10*a0008a36SMengyuan Lou 
11*a0008a36SMengyuan Lou #include "../libwx/wx_type.h"
12*a0008a36SMengyuan Lou #include "../libwx/wx_vf_common.h"
13*a0008a36SMengyuan Lou #include "ngbevf_type.h"
14*a0008a36SMengyuan Lou 
15*a0008a36SMengyuan Lou /* ngbevf_pci_tbl - PCI Device ID Table
16*a0008a36SMengyuan Lou  *
17*a0008a36SMengyuan Lou  * Wildcard entries (PCI_ANY_ID) should come last
18*a0008a36SMengyuan Lou  * Last entry must be all 0s
19*a0008a36SMengyuan Lou  *
20*a0008a36SMengyuan Lou  * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
21*a0008a36SMengyuan Lou  *   Class, Class Mask, private data (not used) }
22*a0008a36SMengyuan Lou  */
23*a0008a36SMengyuan Lou static const struct pci_device_id ngbevf_pci_tbl[] = {
24*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL_W), 0},
25*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A2), 0},
26*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A2S), 0},
27*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A4), 0},
28*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A4S), 0},
29*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL2), 0},
30*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL2S), 0},
31*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL4), 0},
32*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL4S), 0},
33*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860NCSI), 0},
34*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A1), 0},
35*a0008a36SMengyuan Lou 	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL1), 0},
36*a0008a36SMengyuan Lou 	/* required last entry */
37*a0008a36SMengyuan Lou 	{ .device = 0 }
38*a0008a36SMengyuan Lou };
39*a0008a36SMengyuan Lou 
40*a0008a36SMengyuan Lou /**
41*a0008a36SMengyuan Lou  * ngbevf_probe - Device Initialization Routine
42*a0008a36SMengyuan Lou  * @pdev: PCI device information struct
43*a0008a36SMengyuan Lou  * @ent: entry in ngbevf_pci_tbl
44*a0008a36SMengyuan Lou  *
45*a0008a36SMengyuan Lou  * Return: return 0 on success, negative on failure
46*a0008a36SMengyuan Lou  *
47*a0008a36SMengyuan Lou  * ngbevf_probe initializes an adapter identified by a pci_dev structure.
48*a0008a36SMengyuan Lou  * The OS initialization, configuring of the adapter private structure,
49*a0008a36SMengyuan Lou  * and a hardware reset occur.
50*a0008a36SMengyuan Lou  **/
51*a0008a36SMengyuan Lou static int ngbevf_probe(struct pci_dev *pdev,
52*a0008a36SMengyuan Lou 			const struct pci_device_id __always_unused *ent)
53*a0008a36SMengyuan Lou {
54*a0008a36SMengyuan Lou 	struct net_device *netdev;
55*a0008a36SMengyuan Lou 	struct wx *wx = NULL;
56*a0008a36SMengyuan Lou 	int err;
57*a0008a36SMengyuan Lou 
58*a0008a36SMengyuan Lou 	err = pci_enable_device_mem(pdev);
59*a0008a36SMengyuan Lou 	if (err)
60*a0008a36SMengyuan Lou 		return err;
61*a0008a36SMengyuan Lou 
62*a0008a36SMengyuan Lou 	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
63*a0008a36SMengyuan Lou 	if (err) {
64*a0008a36SMengyuan Lou 		dev_err(&pdev->dev,
65*a0008a36SMengyuan Lou 			"No usable DMA configuration, aborting\n");
66*a0008a36SMengyuan Lou 		goto err_pci_disable_dev;
67*a0008a36SMengyuan Lou 	}
68*a0008a36SMengyuan Lou 
69*a0008a36SMengyuan Lou 	err = pci_request_selected_regions(pdev,
70*a0008a36SMengyuan Lou 					   pci_select_bars(pdev, IORESOURCE_MEM),
71*a0008a36SMengyuan Lou 					   dev_driver_string(&pdev->dev));
72*a0008a36SMengyuan Lou 	if (err) {
73*a0008a36SMengyuan Lou 		dev_err(&pdev->dev,
74*a0008a36SMengyuan Lou 			"pci_request_selected_regions failed 0x%x\n", err);
75*a0008a36SMengyuan Lou 		goto err_pci_disable_dev;
76*a0008a36SMengyuan Lou 	}
77*a0008a36SMengyuan Lou 
78*a0008a36SMengyuan Lou 	pci_set_master(pdev);
79*a0008a36SMengyuan Lou 
80*a0008a36SMengyuan Lou 	netdev = devm_alloc_etherdev_mqs(&pdev->dev,
81*a0008a36SMengyuan Lou 					 sizeof(struct wx),
82*a0008a36SMengyuan Lou 					 NGBEVF_MAX_TX_QUEUES,
83*a0008a36SMengyuan Lou 					 NGBEVF_MAX_RX_QUEUES);
84*a0008a36SMengyuan Lou 	if (!netdev) {
85*a0008a36SMengyuan Lou 		err = -ENOMEM;
86*a0008a36SMengyuan Lou 		goto err_pci_release_regions;
87*a0008a36SMengyuan Lou 	}
88*a0008a36SMengyuan Lou 
89*a0008a36SMengyuan Lou 	SET_NETDEV_DEV(netdev, &pdev->dev);
90*a0008a36SMengyuan Lou 
91*a0008a36SMengyuan Lou 	wx = netdev_priv(netdev);
92*a0008a36SMengyuan Lou 	wx->netdev = netdev;
93*a0008a36SMengyuan Lou 	wx->pdev = pdev;
94*a0008a36SMengyuan Lou 
95*a0008a36SMengyuan Lou 	wx->msg_enable = netif_msg_init(-1, NETIF_MSG_DRV |
96*a0008a36SMengyuan Lou 					NETIF_MSG_PROBE | NETIF_MSG_LINK);
97*a0008a36SMengyuan Lou 	wx->hw_addr = devm_ioremap(&pdev->dev,
98*a0008a36SMengyuan Lou 				   pci_resource_start(pdev, 0),
99*a0008a36SMengyuan Lou 				   pci_resource_len(pdev, 0));
100*a0008a36SMengyuan Lou 	if (!wx->hw_addr) {
101*a0008a36SMengyuan Lou 		err = -EIO;
102*a0008a36SMengyuan Lou 		goto err_pci_release_regions;
103*a0008a36SMengyuan Lou 	}
104*a0008a36SMengyuan Lou 
105*a0008a36SMengyuan Lou 	netdev->features |= NETIF_F_HIGHDMA;
106*a0008a36SMengyuan Lou 	pci_set_drvdata(pdev, wx);
107*a0008a36SMengyuan Lou 
108*a0008a36SMengyuan Lou 	return 0;
109*a0008a36SMengyuan Lou 
110*a0008a36SMengyuan Lou err_pci_release_regions:
111*a0008a36SMengyuan Lou 	pci_release_selected_regions(pdev,
112*a0008a36SMengyuan Lou 				     pci_select_bars(pdev, IORESOURCE_MEM));
113*a0008a36SMengyuan Lou err_pci_disable_dev:
114*a0008a36SMengyuan Lou 	pci_disable_device(pdev);
115*a0008a36SMengyuan Lou 	return err;
116*a0008a36SMengyuan Lou }
117*a0008a36SMengyuan Lou 
118*a0008a36SMengyuan Lou /**
119*a0008a36SMengyuan Lou  * ngbevf_remove - Device Removal Routine
120*a0008a36SMengyuan Lou  * @pdev: PCI device information struct
121*a0008a36SMengyuan Lou  *
122*a0008a36SMengyuan Lou  * ngbevf_remove is called by the PCI subsystem to alert the driver
123*a0008a36SMengyuan Lou  * that it should release a PCI device.  The could be caused by a
124*a0008a36SMengyuan Lou  * Hot-Plug event, or because the driver is going to be removed from
125*a0008a36SMengyuan Lou  * memory.
126*a0008a36SMengyuan Lou  **/
127*a0008a36SMengyuan Lou static void ngbevf_remove(struct pci_dev *pdev)
128*a0008a36SMengyuan Lou {
129*a0008a36SMengyuan Lou 	wxvf_remove(pdev);
130*a0008a36SMengyuan Lou }
131*a0008a36SMengyuan Lou 
132*a0008a36SMengyuan Lou static DEFINE_SIMPLE_DEV_PM_OPS(ngbevf_pm_ops, wxvf_suspend, wxvf_resume);
133*a0008a36SMengyuan Lou 
134*a0008a36SMengyuan Lou static struct pci_driver ngbevf_driver = {
135*a0008a36SMengyuan Lou 	.name     = KBUILD_MODNAME,
136*a0008a36SMengyuan Lou 	.id_table = ngbevf_pci_tbl,
137*a0008a36SMengyuan Lou 	.probe    = ngbevf_probe,
138*a0008a36SMengyuan Lou 	.remove   = ngbevf_remove,
139*a0008a36SMengyuan Lou 	.shutdown = wxvf_shutdown,
140*a0008a36SMengyuan Lou 	/* Power Management Hooks */
141*a0008a36SMengyuan Lou 	.driver.pm	= pm_sleep_ptr(&ngbevf_pm_ops)
142*a0008a36SMengyuan Lou };
143*a0008a36SMengyuan Lou 
144*a0008a36SMengyuan Lou module_pci_driver(ngbevf_driver);
145*a0008a36SMengyuan Lou 
146*a0008a36SMengyuan Lou MODULE_DEVICE_TABLE(pci, ngbevf_pci_tbl);
147*a0008a36SMengyuan Lou MODULE_AUTHOR("Beijing WangXun Technology Co., Ltd, <software@trustnetic.com>");
148*a0008a36SMengyuan Lou MODULE_DESCRIPTION("WangXun(R) Gigabit PCI Express Network Driver");
149*a0008a36SMengyuan Lou MODULE_LICENSE("GPL");
150