File Index
Files and directories
Sign in
FILE

ngbevf_main.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/wangxun/ngbevf/ngbevf_main.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */
  3
  4#include <linux/types.h>
  5#include <linux/module.h>
  6#include <linux/pci.h>
  7#include <linux/netdevice.h>
  8#include <linux/string.h>
  9#include <linux/etherdevice.h>
 10
 11#include "../libwx/wx_type.h"
 12#include "../libwx/wx_hw.h"
 13#include "../libwx/wx_lib.h"
 14#include "../libwx/wx_mbx.h"
 15#include "../libwx/wx_vf.h"
 16#include "../libwx/wx_vf_common.h"
 17#include "../libwx/wx_ethtool.h"
 18#include "ngbevf_type.h"
 19
 20/* ngbevf_pci_tbl - PCI Device ID Table
 21 *
 22 * Wildcard entries (PCI_ANY_ID) should come last
 23 * Last entry must be all 0s
 24 *
 25 * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
 26 *   Class, Class Mask, private data (not used) }
 27 */
 28static const struct pci_device_id ngbevf_pci_tbl[] = {
 29	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL_W), 0},
 30	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A2), 0},
 31	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A2S), 0},
 32	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A4), 0},
 33	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A4S), 0},
 34	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL2), 0},
 35	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL2S), 0},
 36	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL4), 0},
 37	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL4S), 0},
 38	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860NCSI), 0},
 39	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860A1), 0},
 40	{ PCI_VDEVICE(WANGXUN, NGBEVF_DEV_ID_EM_WX1860AL1), 0},
 41	/* required last entry */
 42	{ .device = 0 }
 43};
 44
 45static const struct net_device_ops ngbevf_netdev_ops = {
 46	.ndo_open               = wxvf_open,
 47	.ndo_stop               = wxvf_close,
 48	.ndo_start_xmit         = wx_xmit_frame,
 49	.ndo_validate_addr      = eth_validate_addr,
 50	.ndo_set_mac_address    = wx_set_mac_vf,
 51};
 52
 53static void ngbevf_set_num_queues(struct wx *wx)
 54{
 55	/* Start with base case */
 56	wx->num_rx_queues = 1;
 57	wx->num_tx_queues = 1;
 58}
 59
 60static int ngbevf_sw_init(struct wx *wx)
 61{
 62	struct net_device *netdev = wx->netdev;
 63	struct pci_dev *pdev = wx->pdev;
 64	int err;
 65
 66	/* Initialize pcie info and common capability flags */
 67	err = wx_sw_init(wx);
 68	if (err < 0)
 69		goto err_wx_sw_init;
 70
 71	/* Initialize the mailbox */
 72	err = wx_init_mbx_params_vf(wx);
 73	if (err)
 74		goto err_init_mbx_params;
 75
 76	/* Initialize the device type */
 77	wx->mac.type = wx_mac_em;
 78	wx->mac.max_msix_vectors = NGBEVF_MAX_MSIX_VECTORS;
 79	/* lock to protect mailbox accesses */
 80	spin_lock_init(&wx->mbx.mbx_lock);
 81
 82	err = wx_reset_hw_vf(wx);
 83	if (err) {
 84		wx_err(wx, "PF still in reset state. Is the PF interface up?\n");
 85		goto err_reset_hw;
 86	}
 87	wx_init_hw_vf(wx);
 88	wx_negotiate_api_vf(wx);
 89	if (is_zero_ether_addr(wx->mac.addr))
 90		dev_info(&pdev->dev,
 91			 "MAC address not assigned by administrator.\n");
 92	eth_hw_addr_set(netdev, wx->mac.addr);
 93
 94	if (!is_valid_ether_addr(netdev->dev_addr)) {
 95		dev_info(&pdev->dev, "Assigning random MAC address\n");
 96		eth_hw_addr_random(netdev);
 97		ether_addr_copy(wx->mac.addr, netdev->dev_addr);
 98		ether_addr_copy(wx->mac.perm_addr, netdev->dev_addr);
 99	}
100
101	wx->mac.max_tx_queues = NGBEVF_MAX_TX_QUEUES;
102	wx->mac.max_rx_queues = NGBEVF_MAX_RX_QUEUES;
103	/* Enable dynamic interrupt throttling rates */
104	wx->adaptive_itr = true;
105	wx->rx_itr_setting = 1;
106	wx->tx_itr_setting = 1;
107	/* set default ring sizes */
108	wx->tx_ring_count = NGBEVF_DEFAULT_TXD;
109	wx->rx_ring_count = NGBEVF_DEFAULT_RXD;
110	/* set default work limits */
111	wx->tx_work_limit = NGBEVF_DEFAULT_TX_WORK;
112	wx->rx_work_limit = NGBEVF_DEFAULT_RX_WORK;
113	wx->set_num_queues = ngbevf_set_num_queues;
114
115	return 0;
116err_reset_hw:
117	kfree(wx->vfinfo);
118err_init_mbx_params:
119	kfree(wx->rss_key);
120	kfree(wx->mac_table);
121err_wx_sw_init:
122	return err;
123}
124
125/**
126 * ngbevf_probe - Device Initialization Routine
127 * @pdev: PCI device information struct
128 * @ent: entry in ngbevf_pci_tbl
129 *
130 * Return: return 0 on success, negative on failure
131 *
132 * ngbevf_probe initializes an adapter identified by a pci_dev structure.
133 * The OS initialization, configuring of the adapter private structure,
134 * and a hardware reset occur.
135 **/
136static int ngbevf_probe(struct pci_dev *pdev,
137			const struct pci_device_id __always_unused *ent)
138{
139	struct net_device *netdev;
140	struct wx *wx = NULL;
141	int err;
142
143	err = pci_enable_device_mem(pdev);
144	if (err)
145		return err;
146
147	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
148	if (err) {
149		dev_err(&pdev->dev,
150			"No usable DMA configuration, aborting\n");
151		goto err_pci_disable_dev;
152	}
153
154	err = pci_request_selected_regions(pdev,
155					   pci_select_bars(pdev, IORESOURCE_MEM),
156					   dev_driver_string(&pdev->dev));
157	if (err) {
158		dev_err(&pdev->dev,
159			"pci_request_selected_regions failed 0x%x\n", err);
160		goto err_pci_disable_dev;
161	}
162
163	pci_set_master(pdev);
164
165	netdev = devm_alloc_etherdev_mqs(&pdev->dev,
166					 sizeof(struct wx),
167					 NGBEVF_MAX_TX_QUEUES,
168					 NGBEVF_MAX_RX_QUEUES);
169	if (!netdev) {
170		err = -ENOMEM;
171		goto err_pci_release_regions;
172	}
173
174	SET_NETDEV_DEV(netdev, &pdev->dev);
175
176	wx = netdev_priv(netdev);
177	wx->netdev = netdev;
178	wx->pdev = pdev;
179
180	wx->msg_enable = netif_msg_init(-1, NETIF_MSG_DRV |
181					NETIF_MSG_PROBE | NETIF_MSG_LINK);
182	wx->hw_addr = devm_ioremap(&pdev->dev,
183				   pci_resource_start(pdev, 0),
184				   pci_resource_len(pdev, 0));
185	if (!wx->hw_addr) {
186		err = -EIO;
187		goto err_pci_release_regions;
188	}
189
190	wx->driver_name = KBUILD_MODNAME;
191	wx_set_ethtool_ops_vf(netdev);
192	netdev->netdev_ops = &ngbevf_netdev_ops;
193
194	/* setup the private structure */
195	err = ngbevf_sw_init(wx);
196	if (err)
197		goto err_pci_release_regions;
198
199	netdev->features |= NETIF_F_HIGHDMA;
200
201	eth_hw_addr_set(netdev, wx->mac.perm_addr);
202	ether_addr_copy(netdev->perm_addr, wx->mac.addr);
203
204	wxvf_init_service(wx);
205	err = wx_init_interrupt_scheme(wx);
206	if (err)
207		goto err_free_sw_init;
208
209	wx_get_fw_version_vf(wx);
210	err = register_netdev(netdev);
211	if (err)
212		goto err_register;
213
214	pci_set_drvdata(pdev, wx);
215	netif_tx_stop_all_queues(netdev);
216
217	return 0;
218
219err_register:
220	wx_clear_interrupt_scheme(wx);
221err_free_sw_init:
222	timer_delete_sync(&wx->service_timer);
223	cancel_work_sync(&wx->service_task);
224	kfree(wx->vfinfo);
225	kfree(wx->rss_key);
226	kfree(wx->mac_table);
227err_pci_release_regions:
228	pci_release_selected_regions(pdev,
229				     pci_select_bars(pdev, IORESOURCE_MEM));
230err_pci_disable_dev:
231	pci_disable_device(pdev);
232	return err;
233}
234
235/**
236 * ngbevf_remove - Device Removal Routine
237 * @pdev: PCI device information struct
238 *
239 * ngbevf_remove is called by the PCI subsystem to alert the driver
240 * that it should release a PCI device.  The could be caused by a
241 * Hot-Plug event, or because the driver is going to be removed from
242 * memory.
243 **/
244static void ngbevf_remove(struct pci_dev *pdev)
245{
246	wxvf_remove(pdev);
247}
248
249static DEFINE_SIMPLE_DEV_PM_OPS(ngbevf_pm_ops, wxvf_suspend, wxvf_resume);
250
251static struct pci_driver ngbevf_driver = {
252	.name     = KBUILD_MODNAME,
253	.id_table = ngbevf_pci_tbl,
254	.probe    = ngbevf_probe,
255	.remove   = ngbevf_remove,
256	.shutdown = wxvf_shutdown,
257	/* Power Management Hooks */
258	.driver.pm	= pm_sleep_ptr(&ngbevf_pm_ops)
259};
260
261module_pci_driver(ngbevf_driver);
262
263MODULE_DEVICE_TABLE(pci, ngbevf_pci_tbl);
264MODULE_AUTHOR("Beijing WangXun Technology Co., Ltd, <software@trustnetic.com>");
265MODULE_DESCRIPTION("WangXun(R) Gigabit PCI Express Network Driver");
266MODULE_LICENSE("GPL");
~/ Read-only file preview.