Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2019 - 2022 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#include <net/ip.h>
 11#include <linux/phy.h>
 12#include <linux/if_vlan.h>
 13
 14#include "../libwx/wx_type.h"
 15#include "../libwx/wx_hw.h"
 16#include "../libwx/wx_lib.h"
 17#include "ngbe_type.h"
 18#include "ngbe_mdio.h"
 19#include "ngbe_hw.h"
 20#include "ngbe_ethtool.h"
 21
 22char ngbe_driver_name[] = "ngbe";
 23
 24/* ngbe_pci_tbl - PCI Device ID Table
 25 *
 26 * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
 27 *   Class, Class Mask, private data (not used) }
 28 */
 29static const struct pci_device_id ngbe_pci_tbl[] = {
 30	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL_W), 0},
 31	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A2), 0},
 32	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A2S), 0},
 33	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A4), 0},
 34	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A4S), 0},
 35	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL2), 0},
 36	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL2S), 0},
 37	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL4), 0},
 38	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL4S), 0},
 39	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860LC), 0},
 40	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A1), 0},
 41	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A1L), 0},
 42	/* required last entry */
 43	{ .device = 0 }
 44};
 45
 
 
 
 
 
 
 
 
 
 
 
 
 
 46/**
 47 *  ngbe_init_type_code - Initialize the shared code
 48 *  @wx: pointer to hardware structure
 49 **/
 50static void ngbe_init_type_code(struct wx *wx)
 51{
 52	int wol_mask = 0, ncsi_mask = 0;
 53	u16 type_mask = 0, val;
 54
 55	wx->mac.type = wx_mac_em;
 56	type_mask = (u16)(wx->subsystem_device_id & NGBE_OEM_MASK);
 57	ncsi_mask = wx->subsystem_device_id & NGBE_NCSI_MASK;
 58	wol_mask = wx->subsystem_device_id & NGBE_WOL_MASK;
 59
 60	val = rd32(wx, WX_CFG_PORT_ST);
 61	wx->mac_type = (val & BIT(7)) >> 7 ?
 62		       em_mac_type_rgmii :
 63		       em_mac_type_mdi;
 64
 65	wx->wol_hw_supported = (wol_mask == NGBE_WOL_SUP) ? 1 : 0;
 66	wx->ncsi_enabled = (ncsi_mask == NGBE_NCSI_MASK ||
 67			   type_mask == NGBE_SUBID_OCP_CARD) ? 1 : 0;
 
 68
 69	switch (type_mask) {
 70	case NGBE_SUBID_LY_YT8521S_SFP:
 71	case NGBE_SUBID_LY_M88E1512_SFP:
 
 
 
 
 
 
 
 
 
 72	case NGBE_SUBID_YT8521S_SFP_GPIO:
 
 
 
 
 73	case NGBE_SUBID_INTERNAL_YT8521S_SFP_GPIO:
 74		wx->gpio_ctrl = 1;
 75		break;
 
 
 
 76	default:
 77		wx->gpio_ctrl = 0;
 78		break;
 79	}
 80}
 81
 82/**
 83 * ngbe_sw_init - Initialize general software structures
 84 * @wx: board private structure to initialize
 85 **/
 86static int ngbe_sw_init(struct wx *wx)
 87{
 88	struct pci_dev *pdev = wx->pdev;
 89	u16 msix_count = 0;
 90	int err = 0;
 91
 92	wx->mac.num_rar_entries = NGBE_RAR_ENTRIES;
 93	wx->mac.max_rx_queues = NGBE_MAX_RX_QUEUES;
 94	wx->mac.max_tx_queues = NGBE_MAX_TX_QUEUES;
 95	wx->mac.mcft_size = NGBE_MC_TBL_SIZE;
 96	wx->mac.vft_size = NGBE_SP_VFT_TBL_SIZE;
 97	wx->mac.rx_pb_size = NGBE_RX_PB_SIZE;
 98	wx->mac.tx_pb_size = NGBE_TDB_PB_SZ;
 99
100	/* PCI config space info */
101	err = wx_sw_init(wx);
102	if (err < 0)
103		return err;
104
105	/* mac type, phy type , oem type */
106	ngbe_init_type_code(wx);
107
108	/* Set common capability flags and settings */
109	wx->max_q_vectors = NGBE_MAX_MSIX_VECTORS;
110	err = wx_get_pcie_msix_counts(wx, &msix_count, NGBE_MAX_MSIX_VECTORS);
111	if (err)
112		dev_err(&pdev->dev, "Do not support MSI-X\n");
113	wx->mac.max_msix_vectors = msix_count;
114
115	wx->ring_feature[RING_F_RSS].limit = min_t(int, NGBE_MAX_RSS_INDICES,
116						   num_online_cpus());
117	wx->rss_enabled = true;
118
119	/* enable itr by default in dynamic mode */
120	wx->rx_itr_setting = 1;
121	wx->tx_itr_setting = 1;
122
123	/* set default ring sizes */
124	wx->tx_ring_count = NGBE_DEFAULT_TXD;
125	wx->rx_ring_count = NGBE_DEFAULT_RXD;
126
127	/* set default work limits */
128	wx->tx_work_limit = NGBE_DEFAULT_TX_WORK;
129	wx->rx_work_limit = NGBE_DEFAULT_RX_WORK;
130
131	return 0;
132}
133
134/**
135 * ngbe_irq_enable - Enable default interrupt generation settings
136 * @wx: board private structure
137 * @queues: enable all queues interrupts
138 **/
139static void ngbe_irq_enable(struct wx *wx, bool queues)
140{
141	u32 mask;
142
143	/* enable misc interrupt */
144	mask = NGBE_PX_MISC_IEN_MASK;
145
146	wr32(wx, WX_GPIO_DDR, WX_GPIO_DDR_0);
147	wr32(wx, WX_GPIO_INTEN, WX_GPIO_INTEN_0 | WX_GPIO_INTEN_1);
148	wr32(wx, WX_GPIO_INTTYPE_LEVEL, 0x0);
149	wr32(wx, WX_GPIO_POLARITY, wx->gpio_ctrl ? 0 : 0x3);
150
151	wr32(wx, WX_PX_MISC_IEN, mask);
152
153	/* mask interrupt */
154	if (queues)
155		wx_intr_enable(wx, NGBE_INTR_ALL);
156	else
157		wx_intr_enable(wx, NGBE_INTR_MISC);
158}
159
160/**
161 * ngbe_intr - msi/legacy mode Interrupt Handler
162 * @irq: interrupt number
163 * @data: pointer to a network interface device structure
164 **/
165static irqreturn_t ngbe_intr(int __always_unused irq, void *data)
166{
167	struct wx_q_vector *q_vector;
168	struct wx *wx  = data;
169	struct pci_dev *pdev;
170	u32 eicr;
171
172	q_vector = wx->q_vector[0];
173	pdev = wx->pdev;
174
175	eicr = wx_misc_isb(wx, WX_ISB_VEC0);
176	if (!eicr) {
177		/* shared interrupt alert!
178		 * the interrupt that we masked before the EICR read.
179		 */
180		if (netif_running(wx->netdev))
181			ngbe_irq_enable(wx, true);
182		return IRQ_NONE;        /* Not our interrupt */
 
 
183	}
184	wx->isb_mem[WX_ISB_VEC0] = 0;
185	if (!(pdev->msi_enabled))
186		wr32(wx, WX_PX_INTA, 1);
187
188	wx->isb_mem[WX_ISB_MISC] = 0;
189	/* would disable interrupts here but it is auto disabled */
190	napi_schedule_irqoff(&q_vector->napi);
191
192	if (netif_running(wx->netdev))
193		ngbe_irq_enable(wx, false);
194
195	return IRQ_HANDLED;
196}
197
198static irqreturn_t ngbe_msix_other(int __always_unused irq, void *data)
199{
200	struct wx *wx = data;
201
202	/* re-enable the original interrupt state, no lsc, no queues */
203	if (netif_running(wx->netdev))
204		ngbe_irq_enable(wx, false);
205
206	return IRQ_HANDLED;
207}
208
209/**
210 * ngbe_request_msix_irqs - Initialize MSI-X interrupts
211 * @wx: board private structure
212 *
213 * ngbe_request_msix_irqs allocates MSI-X vectors and requests
214 * interrupts from the kernel.
215 **/
216static int ngbe_request_msix_irqs(struct wx *wx)
217{
218	struct net_device *netdev = wx->netdev;
219	int vector, err;
220
221	for (vector = 0; vector < wx->num_q_vectors; vector++) {
222		struct wx_q_vector *q_vector = wx->q_vector[vector];
223		struct msix_entry *entry = &wx->msix_q_entries[vector];
224
225		if (q_vector->tx.ring && q_vector->rx.ring)
226			snprintf(q_vector->name, sizeof(q_vector->name) - 1,
227				 "%s-TxRx-%d", netdev->name, entry->entry);
228		else
229			/* skip this unused q_vector */
230			continue;
231
232		err = request_irq(entry->vector, wx_msix_clean_rings, 0,
233				  q_vector->name, q_vector);
234		if (err) {
235			wx_err(wx, "request_irq failed for MSIX interrupt %s Error: %d\n",
236			       q_vector->name, err);
237			goto free_queue_irqs;
238		}
239	}
240
241	err = request_irq(wx->msix_entry->vector,
242			  ngbe_msix_other, 0, netdev->name, wx);
 
 
243
244	if (err) {
245		wx_err(wx, "request_irq for msix_other failed: %d\n", err);
246		goto free_queue_irqs;
247	}
248
249	return 0;
250
251free_queue_irqs:
252	while (vector) {
253		vector--;
254		free_irq(wx->msix_q_entries[vector].vector,
255			 wx->q_vector[vector]);
256	}
257	wx_reset_interrupt_capability(wx);
258	return err;
259}
260
261/**
262 * ngbe_request_irq - initialize interrupts
263 * @wx: board private structure
264 *
265 * Attempts to configure interrupts using the best available
266 * capabilities of the hardware and kernel.
267 **/
268static int ngbe_request_irq(struct wx *wx)
269{
270	struct net_device *netdev = wx->netdev;
271	struct pci_dev *pdev = wx->pdev;
272	int err;
 
 
273
274	if (pdev->msix_enabled)
275		err = ngbe_request_msix_irqs(wx);
276	else if (pdev->msi_enabled)
277		err = request_irq(pdev->irq, ngbe_intr, 0,
278				  netdev->name, wx);
279	else
280		err = request_irq(pdev->irq, ngbe_intr, IRQF_SHARED,
281				  netdev->name, wx);
282
283	if (err)
284		wx_err(wx, "request_irq failed, Error %d\n", err);
 
 
 
 
 
285
286	return err;
287}
288
289static void ngbe_disable_device(struct wx *wx)
290{
291	struct net_device *netdev = wx->netdev;
292	u32 i;
 
293
294	/* disable all enabled rx queues */
295	for (i = 0; i < wx->num_rx_queues; i++)
296		/* this call also flushes the previous write */
297		wx_disable_rx_queue(wx, wx->rx_ring[i]);
298	/* disable receives */
299	wx_disable_rx(wx);
300	wx_napi_disable_all(wx);
301	netif_tx_stop_all_queues(netdev);
302	netif_tx_disable(netdev);
303	if (wx->gpio_ctrl)
304		ngbe_sfp_modules_txrx_powerctl(wx, false);
305	wx_irq_disable(wx);
306	/* disable transmits in the hardware now that interrupts are off */
307	for (i = 0; i < wx->num_tx_queues; i++) {
308		u8 reg_idx = wx->tx_ring[i]->reg_idx;
309
310		wr32(wx, WX_PX_TR_CFG(reg_idx), WX_PX_TR_CFG_SWFLSH);
 
 
 
 
 
311	}
312
313	wx_update_stats(wx);
314}
315
316void ngbe_down(struct wx *wx)
317{
318	phylink_stop(wx->phylink);
319	ngbe_disable_device(wx);
320	wx_clean_all_tx_rings(wx);
321	wx_clean_all_rx_rings(wx);
322}
323
324void ngbe_up(struct wx *wx)
325{
326	wx_configure_vectors(wx);
327
328	/* make sure to complete pre-operations */
329	smp_mb__before_atomic();
330	wx_napi_enable_all(wx);
331	/* enable transmits */
332	netif_tx_start_all_queues(wx->netdev);
333
334	/* clear any pending interrupts, may auto mask */
335	rd32(wx, WX_PX_IC(0));
336	rd32(wx, WX_PX_MISC_IC);
337	ngbe_irq_enable(wx, true);
338	if (wx->gpio_ctrl)
339		ngbe_sfp_modules_txrx_powerctl(wx, true);
340
341	phylink_start(wx->phylink);
342}
343
 
 
 
 
 
 
344/**
345 * ngbe_open - Called when a network interface is made active
346 * @netdev: network interface device structure
347 *
348 * Returns 0 on success, negative value on failure
349 *
350 * The open entry point is called when a network interface is made
351 * active by the system (IFF_UP).
352 **/
353static int ngbe_open(struct net_device *netdev)
354{
355	struct wx *wx = netdev_priv(netdev);
356	int err;
357
358	wx_control_hw(wx, true);
359
360	err = wx_setup_resources(wx);
361	if (err)
362		return err;
363
364	wx_configure(wx);
365
366	err = ngbe_request_irq(wx);
367	if (err)
368		goto err_free_resources;
369
370	err = phylink_connect_phy(wx->phylink, wx->phydev);
371	if (err)
372		goto err_free_irq;
373
374	err = netif_set_real_num_tx_queues(netdev, wx->num_tx_queues);
375	if (err)
376		goto err_dis_phy;
377
378	err = netif_set_real_num_rx_queues(netdev, wx->num_rx_queues);
379	if (err)
380		goto err_dis_phy;
381
382	ngbe_up(wx);
383
384	return 0;
385err_dis_phy:
386	phylink_disconnect_phy(wx->phylink);
387err_free_irq:
388	wx_free_irq(wx);
389err_free_resources:
390	wx_free_resources(wx);
391	return err;
392}
393
394/**
395 * ngbe_close - Disables a network interface
396 * @netdev: network interface device structure
397 *
398 * Returns 0, this is not allowed to fail
399 *
400 * The close entry point is called when an interface is de-activated
401 * by the OS.  The hardware is still under the drivers control, but
402 * needs to be disabled.  A global MAC reset is issued to stop the
403 * hardware, and all transmit and receive resources are freed.
404 **/
405static int ngbe_close(struct net_device *netdev)
406{
407	struct wx *wx = netdev_priv(netdev);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
409	ngbe_down(wx);
410	wx_free_irq(wx);
411	wx_free_resources(wx);
412	phylink_disconnect_phy(wx->phylink);
413	wx_control_hw(wx, false);
414
415	return 0;
416}
417
418static void ngbe_dev_shutdown(struct pci_dev *pdev, bool *enable_wake)
419{
420	struct wx *wx = pci_get_drvdata(pdev);
421	struct net_device *netdev;
422	u32 wufc = wx->wol;
423
424	netdev = wx->netdev;
425	rtnl_lock();
426	netif_device_detach(netdev);
427
 
428	if (netif_running(netdev))
429		ngbe_close(netdev);
430	wx_clear_interrupt_scheme(wx);
431	rtnl_unlock();
432
433	if (wufc) {
434		wx_set_rx_mode(netdev);
435		wx_configure_rx(wx);
436		wr32(wx, NGBE_PSR_WKUP_CTL, wufc);
437	} else {
438		wr32(wx, NGBE_PSR_WKUP_CTL, 0);
439	}
440	pci_wake_from_d3(pdev, !!wufc);
441	*enable_wake = !!wufc;
442	wx_control_hw(wx, false);
443
444	pci_disable_device(pdev);
445}
446
447static void ngbe_shutdown(struct pci_dev *pdev)
448{
449	struct wx *wx = pci_get_drvdata(pdev);
450	bool wake;
451
452	wake = !!wx->wol;
453
454	ngbe_dev_shutdown(pdev, &wake);
455
456	if (system_state == SYSTEM_POWER_OFF) {
457		pci_wake_from_d3(pdev, wake);
458		pci_set_power_state(pdev, PCI_D3hot);
459	}
460}
461
462/**
463 * ngbe_setup_tc - routine to configure net_device for multiple traffic
464 * classes.
465 *
466 * @dev: net device to configure
467 * @tc: number of traffic classes to enable
468 */
469int ngbe_setup_tc(struct net_device *dev, u8 tc)
470{
471	struct wx *wx = netdev_priv(dev);
472
473	/* Hardware has to reinitialize queues and interrupts to
474	 * match packet buffer alignment. Unfortunately, the
475	 * hardware is not flexible enough to do this dynamically.
476	 */
477	if (netif_running(dev))
478		ngbe_close(dev);
479
480	wx_clear_interrupt_scheme(wx);
481
482	if (tc)
483		netdev_set_num_tc(dev, tc);
484	else
485		netdev_reset_tc(dev);
486
487	wx_init_interrupt_scheme(wx);
488
489	if (netif_running(dev))
490		ngbe_open(dev);
491
492	return 0;
493}
494
495static const struct net_device_ops ngbe_netdev_ops = {
496	.ndo_open               = ngbe_open,
497	.ndo_stop               = ngbe_close,
498	.ndo_change_mtu         = wx_change_mtu,
499	.ndo_start_xmit         = wx_xmit_frame,
500	.ndo_set_rx_mode        = wx_set_rx_mode,
501	.ndo_set_features       = wx_set_features,
502	.ndo_validate_addr      = eth_validate_addr,
503	.ndo_set_mac_address    = wx_set_mac,
504	.ndo_get_stats64        = wx_get_stats64,
505	.ndo_vlan_rx_add_vid    = wx_vlan_rx_add_vid,
506	.ndo_vlan_rx_kill_vid   = wx_vlan_rx_kill_vid,
507};
508
509/**
510 * ngbe_probe - Device Initialization Routine
511 * @pdev: PCI device information struct
512 * @ent: entry in ngbe_pci_tbl
513 *
514 * Returns 0 on success, negative on failure
515 *
516 * ngbe_probe initializes an wx identified by a pci_dev structure.
517 * The OS initialization, configuring of the wx private structure,
518 * and a hardware reset occur.
519 **/
520static int ngbe_probe(struct pci_dev *pdev,
521		      const struct pci_device_id __always_unused *ent)
522{
 
 
 
523	struct net_device *netdev;
524	u32 e2rom_cksum_cap = 0;
525	struct wx *wx = NULL;
526	static int func_nums;
527	u16 e2rom_ver = 0;
528	u32 etrack_id = 0;
529	u32 saved_ver = 0;
530	int err;
531
532	err = pci_enable_device_mem(pdev);
533	if (err)
534		return err;
535
536	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
537	if (err) {
538		dev_err(&pdev->dev,
539			"No usable DMA configuration, aborting\n");
540		goto err_pci_disable_dev;
541	}
542
543	err = pci_request_selected_regions(pdev,
544					   pci_select_bars(pdev, IORESOURCE_MEM),
545					   ngbe_driver_name);
546	if (err) {
547		dev_err(&pdev->dev,
548			"pci_request_selected_regions failed %d\n", err);
549		goto err_pci_disable_dev;
550	}
551
 
552	pci_set_master(pdev);
553
554	netdev = devm_alloc_etherdev_mqs(&pdev->dev,
555					 sizeof(struct wx),
556					 NGBE_MAX_TX_QUEUES,
557					 NGBE_MAX_RX_QUEUES);
558	if (!netdev) {
559		err = -ENOMEM;
560		goto err_pci_release_regions;
561	}
562
563	SET_NETDEV_DEV(netdev, &pdev->dev);
564
565	wx = netdev_priv(netdev);
566	wx->netdev = netdev;
567	wx->pdev = pdev;
568	wx->msg_enable = BIT(3) - 1;
569
570	wx->hw_addr = devm_ioremap(&pdev->dev,
571				   pci_resource_start(pdev, 0),
572				   pci_resource_len(pdev, 0));
573	if (!wx->hw_addr) {
 
 
574		err = -EIO;
575		goto err_pci_release_regions;
576	}
577
578	wx->driver_name = ngbe_driver_name;
579	ngbe_set_ethtool_ops(netdev);
580	netdev->netdev_ops = &ngbe_netdev_ops;
581
582	netdev->features = NETIF_F_SG | NETIF_F_IP_CSUM |
583			   NETIF_F_TSO | NETIF_F_TSO6 |
584			   NETIF_F_RXHASH | NETIF_F_RXCSUM;
585	netdev->features |= NETIF_F_SCTP_CRC | NETIF_F_TSO_MANGLEID;
586	netdev->vlan_features |= netdev->features;
587	netdev->features |= NETIF_F_IPV6_CSUM | NETIF_F_VLAN_FEATURES;
588	/* copy netdev features into list of user selectable features */
589	netdev->hw_features |= netdev->features | NETIF_F_RXALL;
590	netdev->hw_features |= NETIF_F_NTUPLE | NETIF_F_HW_TC;
591	netdev->features |= NETIF_F_HIGHDMA;
592	netdev->hw_features |= NETIF_F_GRO;
593	netdev->features |= NETIF_F_GRO;
594
595	netdev->priv_flags |= IFF_UNICAST_FLT;
596	netdev->priv_flags |= IFF_SUPP_NOFCS;
597	netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
598
599	netdev->min_mtu = ETH_MIN_MTU;
600	netdev->max_mtu = WX_MAX_JUMBO_FRAME_SIZE -
601			  (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
602
603	wx->bd_number = func_nums;
604	/* setup the private structure */
605	err = ngbe_sw_init(wx);
606	if (err)
607		goto err_free_mac_table;
608
609	/* check if flash load is done after hw power up */
610	err = wx_check_flash_load(wx, NGBE_SPI_ILDR_STATUS_PERST);
611	if (err)
612		goto err_free_mac_table;
613	err = wx_check_flash_load(wx, NGBE_SPI_ILDR_STATUS_PWRRST);
614	if (err)
615		goto err_free_mac_table;
616
617	err = wx_mng_present(wx);
618	if (err) {
619		dev_err(&pdev->dev, "Management capability is not present\n");
620		goto err_free_mac_table;
621	}
622
623	err = ngbe_reset_hw(wx);
624	if (err) {
625		dev_err(&pdev->dev, "HW Init failed: %d\n", err);
626		goto err_free_mac_table;
627	}
628
629	if (wx->bus.func == 0) {
630		wr32(wx, NGBE_CALSUM_CAP_STATUS, 0x0);
631		wr32(wx, NGBE_EEPROM_VERSION_STORE_REG, 0x0);
632	} else {
633		e2rom_cksum_cap = rd32(wx, NGBE_CALSUM_CAP_STATUS);
634		saved_ver = rd32(wx, NGBE_EEPROM_VERSION_STORE_REG);
635	}
636
637	wx_init_eeprom_params(wx);
638	if (wx->bus.func == 0 || e2rom_cksum_cap == 0) {
639		/* make sure the EEPROM is ready */
640		err = ngbe_eeprom_chksum_hostif(wx);
641		if (err) {
642			dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
643			err = -EIO;
644			goto err_free_mac_table;
645		}
646	}
647
648	wx->wol = 0;
649	if (wx->wol_hw_supported)
650		wx->wol = NGBE_PSR_WKUP_CTL_MAG;
651
652	netdev->wol_enabled = !!(wx->wol);
653	wr32(wx, NGBE_PSR_WKUP_CTL, wx->wol);
654	device_set_wakeup_enable(&pdev->dev, wx->wol);
 
655
656	/* Save off EEPROM version number and Option Rom version which
657	 * together make a unique identify for the eeprom
658	 */
659	if (saved_ver) {
660		etrack_id = saved_ver;
661	} else {
662		wx_read_ee_hostif(wx,
663				  wx->eeprom.sw_region_offset + NGBE_EEPROM_VERSION_H,
664				  &e2rom_ver);
665		etrack_id = e2rom_ver << 16;
666		wx_read_ee_hostif(wx,
667				  wx->eeprom.sw_region_offset + NGBE_EEPROM_VERSION_L,
668				  &e2rom_ver);
669		etrack_id |= e2rom_ver;
670		wr32(wx, NGBE_EEPROM_VERSION_STORE_REG, etrack_id);
671	}
672	snprintf(wx->eeprom_id, sizeof(wx->eeprom_id),
673		 "0x%08x", etrack_id);
674
675	eth_hw_addr_set(netdev, wx->mac.perm_addr);
676	wx_mac_set_default_filter(wx, wx->mac.perm_addr);
677
678	err = wx_init_interrupt_scheme(wx);
679	if (err)
680		goto err_free_mac_table;
681
682	/* phy Interface Configuration */
683	err = ngbe_mdio_init(wx);
684	if (err)
685		goto err_clear_interrupt_scheme;
686
687	err = register_netdev(netdev);
688	if (err)
689		goto err_register;
690
691	pci_set_drvdata(pdev, wx);
 
 
 
 
 
692
693	return 0;
694
695err_register:
696	phylink_destroy(wx->phylink);
697	wx_control_hw(wx, false);
698err_clear_interrupt_scheme:
699	wx_clear_interrupt_scheme(wx);
700err_free_mac_table:
701	kfree(wx->mac_table);
702err_pci_release_regions:
 
703	pci_release_selected_regions(pdev,
704				     pci_select_bars(pdev, IORESOURCE_MEM));
705err_pci_disable_dev:
706	pci_disable_device(pdev);
707	return err;
708}
709
710/**
711 * ngbe_remove - Device Removal Routine
712 * @pdev: PCI device information struct
713 *
714 * ngbe_remove is called by the PCI subsystem to alert the driver
715 * that it should release a PCI device.  The could be caused by a
716 * Hot-Plug event, or because the driver is going to be removed from
717 * memory.
718 **/
719static void ngbe_remove(struct pci_dev *pdev)
720{
721	struct wx *wx = pci_get_drvdata(pdev);
722	struct net_device *netdev;
723
724	netdev = wx->netdev;
725	unregister_netdev(netdev);
726	phylink_destroy(wx->phylink);
727	pci_release_selected_regions(pdev,
728				     pci_select_bars(pdev, IORESOURCE_MEM));
729
730	kfree(wx->rss_key);
731	kfree(wx->mac_table);
732	wx_clear_interrupt_scheme(wx);
733
734	pci_disable_device(pdev);
735}
736
737static int ngbe_suspend(struct pci_dev *pdev, pm_message_t state)
738{
739	bool wake;
740
741	ngbe_dev_shutdown(pdev, &wake);
742	device_set_wakeup_enable(&pdev->dev, wake);
743
744	return 0;
745}
746
747static int ngbe_resume(struct pci_dev *pdev)
748{
749	struct net_device *netdev;
750	struct wx *wx;
751	u32 err;
752
753	wx = pci_get_drvdata(pdev);
754	netdev = wx->netdev;
755
756	err = pci_enable_device_mem(pdev);
757	if (err) {
758		wx_err(wx, "Cannot enable PCI device from suspend\n");
759		return err;
760	}
761	pci_set_master(pdev);
762	device_wakeup_disable(&pdev->dev);
763
764	ngbe_reset_hw(wx);
765	rtnl_lock();
766	err = wx_init_interrupt_scheme(wx);
767	if (!err && netif_running(netdev))
768		err = ngbe_open(netdev);
769	if (!err)
770		netif_device_attach(netdev);
771	rtnl_unlock();
772
773	return 0;
774}
775
776static struct pci_driver ngbe_driver = {
777	.name     = ngbe_driver_name,
778	.id_table = ngbe_pci_tbl,
779	.probe    = ngbe_probe,
780	.remove   = ngbe_remove,
781	.suspend  = ngbe_suspend,
782	.resume   = ngbe_resume,
783	.shutdown = ngbe_shutdown,
784};
785
786module_pci_driver(ngbe_driver);
787
788MODULE_DEVICE_TABLE(pci, ngbe_pci_tbl);
789MODULE_AUTHOR("Beijing WangXun Technology Co., Ltd, <software@net-swift.com>");
790MODULE_DESCRIPTION("WangXun(R) Gigabit PCI Express Network Driver");
791MODULE_LICENSE("GPL");
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2019 - 2022 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/aer.h>
 10#include <linux/etherdevice.h>
 11#include <net/ip.h>
 
 
 12
 13#include "../libwx/wx_type.h"
 14#include "../libwx/wx_hw.h"
 
 15#include "ngbe_type.h"
 
 16#include "ngbe_hw.h"
 17#include "ngbe.h"
 
 18char ngbe_driver_name[] = "ngbe";
 19
 20/* ngbe_pci_tbl - PCI Device ID Table
 21 *
 22 * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
 23 *   Class, Class Mask, private data (not used) }
 24 */
 25static const struct pci_device_id ngbe_pci_tbl[] = {
 26	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL_W), 0},
 27	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A2), 0},
 28	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A2S), 0},
 29	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A4), 0},
 30	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A4S), 0},
 31	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL2), 0},
 32	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL2S), 0},
 33	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL4), 0},
 34	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860AL4S), 0},
 35	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860LC), 0},
 36	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A1), 0},
 37	{ PCI_VDEVICE(WANGXUN, NGBE_DEV_ID_EM_WX1860A1L), 0},
 38	/* required last entry */
 39	{ .device = 0 }
 40};
 41
 42static void ngbe_mac_set_default_filter(struct ngbe_adapter *adapter, u8 *addr)
 43{
 44	struct ngbe_hw *hw = &adapter->hw;
 45
 46	memcpy(&adapter->mac_table[0].addr, addr, ETH_ALEN);
 47	adapter->mac_table[0].pools = 1ULL;
 48	adapter->mac_table[0].state = (NGBE_MAC_STATE_DEFAULT |
 49				       NGBE_MAC_STATE_IN_USE);
 50	wx_set_rar(&hw->wxhw, 0, adapter->mac_table[0].addr,
 51		   adapter->mac_table[0].pools,
 52		   WX_PSR_MAC_SWC_AD_H_AV);
 53}
 54
 55/**
 56 *  ngbe_init_type_code - Initialize the shared code
 57 *  @hw: pointer to hardware structure
 58 **/
 59static void ngbe_init_type_code(struct ngbe_hw *hw)
 60{
 61	int wol_mask = 0, ncsi_mask = 0;
 62	struct wx_hw *wxhw = &hw->wxhw;
 63	u16 type_mask = 0;
 
 
 
 
 
 
 
 
 
 64
 65	wxhw->mac.type = wx_mac_em;
 66	type_mask = (u16)(wxhw->subsystem_device_id & NGBE_OEM_MASK);
 67	ncsi_mask = wxhw->subsystem_device_id & NGBE_NCSI_MASK;
 68	wol_mask = wxhw->subsystem_device_id & NGBE_WOL_MASK;
 69
 70	switch (type_mask) {
 71	case NGBE_SUBID_M88E1512_SFP:
 72	case NGBE_SUBID_LY_M88E1512_SFP:
 73		hw->phy.type = ngbe_phy_m88e1512_sfi;
 74		break;
 75	case NGBE_SUBID_M88E1512_RJ45:
 76		hw->phy.type = ngbe_phy_m88e1512;
 77		break;
 78	case NGBE_SUBID_M88E1512_MIX:
 79		hw->phy.type = ngbe_phy_m88e1512_unknown;
 80		break;
 81	case NGBE_SUBID_YT8521S_SFP:
 82	case NGBE_SUBID_YT8521S_SFP_GPIO:
 83	case NGBE_SUBID_LY_YT8521S_SFP:
 84		hw->phy.type = ngbe_phy_yt8521s_sfi;
 85		break;
 86	case NGBE_SUBID_INTERNAL_YT8521S_SFP:
 87	case NGBE_SUBID_INTERNAL_YT8521S_SFP_GPIO:
 88		hw->phy.type = ngbe_phy_internal_yt8521s_sfi;
 89		break;
 90	case NGBE_SUBID_RGMII_FPGA:
 91	case NGBE_SUBID_OCP_CARD:
 92		fallthrough;
 93	default:
 94		hw->phy.type = ngbe_phy_internal;
 95		break;
 96	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 97
 98	if (hw->phy.type == ngbe_phy_internal ||
 99	    hw->phy.type == ngbe_phy_internal_yt8521s_sfi)
100		hw->mac_type = ngbe_mac_type_mdi;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101	else
102		hw->mac_type = ngbe_mac_type_rgmii;
 
103
104	hw->wol_enabled = (wol_mask == NGBE_WOL_SUP) ? 1 : 0;
105	hw->ncsi_enabled = (ncsi_mask == NGBE_NCSI_MASK ||
106			   type_mask == NGBE_SUBID_OCP_CARD) ? 1 : 0;
 
 
 
 
 
 
 
 
 
 
 
107
108	switch (type_mask) {
109	case NGBE_SUBID_LY_YT8521S_SFP:
110	case NGBE_SUBID_LY_M88E1512_SFP:
111	case NGBE_SUBID_YT8521S_SFP_GPIO:
112	case NGBE_SUBID_INTERNAL_YT8521S_SFP_GPIO:
113		hw->gpio_ctrl = 1;
114		break;
115	default:
116		hw->gpio_ctrl = 0;
117		break;
118	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119}
120
121/**
122 * ngbe_init_rss_key - Initialize adapter RSS key
123 * @adapter: device handle
124 *
125 * Allocates and initializes the RSS key if it is not allocated.
 
126 **/
127static inline int ngbe_init_rss_key(struct ngbe_adapter *adapter)
128{
129	u32 *rss_key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
131	if (!adapter->rss_key) {
132		rss_key = kzalloc(NGBE_RSS_KEY_SIZE, GFP_KERNEL);
133		if (unlikely(!rss_key))
134			return -ENOMEM;
135
136		netdev_rss_key_fill(rss_key, NGBE_RSS_KEY_SIZE);
137		adapter->rss_key = rss_key;
 
138	}
139
140	return 0;
 
 
 
 
 
 
 
 
 
141}
142
143/**
144 * ngbe_sw_init - Initialize general software structures
145 * @adapter: board private structure to initialize
 
 
 
146 **/
147static int ngbe_sw_init(struct ngbe_adapter *adapter)
148{
149	struct pci_dev *pdev = adapter->pdev;
150	struct ngbe_hw *hw = &adapter->hw;
151	struct wx_hw *wxhw = &hw->wxhw;
152	u16 msix_count = 0;
153	int err = 0;
154
155	wxhw->hw_addr = adapter->io_addr;
156	wxhw->pdev = pdev;
 
 
 
 
 
 
157
158	/* PCI config space info */
159	err = wx_sw_init(wxhw);
160	if (err < 0) {
161		netif_err(adapter, probe, adapter->netdev,
162			  "Read of internal subsystem device id failed\n");
163		return err;
164	}
165
166	/* mac type, phy type , oem type */
167	ngbe_init_type_code(hw);
168
169	wxhw->mac.max_rx_queues = NGBE_MAX_RX_QUEUES;
170	wxhw->mac.max_tx_queues = NGBE_MAX_TX_QUEUES;
171	wxhw->mac.num_rar_entries = NGBE_RAR_ENTRIES;
172	/* Set common capability flags and settings */
173	adapter->max_q_vectors = NGBE_MAX_MSIX_VECTORS;
174
175	err = wx_get_pcie_msix_counts(wxhw, &msix_count, NGBE_MAX_MSIX_VECTORS);
176	if (err)
177		dev_err(&pdev->dev, "Do not support MSI-X\n");
178	wxhw->mac.max_msix_vectors = msix_count;
 
 
 
 
 
 
 
 
 
 
 
179
180	adapter->mac_table = kcalloc(wxhw->mac.num_rar_entries,
181				     sizeof(struct ngbe_mac_addr),
182				     GFP_KERNEL);
183	if (!adapter->mac_table) {
184		dev_err(&pdev->dev, "mac_table allocation failed: %d\n", err);
185		return -ENOMEM;
186	}
187
188	if (ngbe_init_rss_key(adapter))
189		return -ENOMEM;
190
191	/* enable itr by default in dynamic mode */
192	adapter->rx_itr_setting = 1;
193	adapter->tx_itr_setting = 1;
 
 
 
 
 
 
 
 
194
195	/* set default ring sizes */
196	adapter->tx_ring_count = NGBE_DEFAULT_TXD;
197	adapter->rx_ring_count = NGBE_DEFAULT_RXD;
 
 
198
199	/* set default work limits */
200	adapter->tx_work_limit = NGBE_DEFAULT_TX_WORK;
201	adapter->rx_work_limit = NGBE_DEFAULT_RX_WORK;
 
 
 
202
203	return 0;
204}
205
206static void ngbe_down(struct ngbe_adapter *adapter)
207{
208	netif_carrier_off(adapter->netdev);
209	netif_tx_disable(adapter->netdev);
210};
211
212/**
213 * ngbe_open - Called when a network interface is made active
214 * @netdev: network interface device structure
215 *
216 * Returns 0 on success, negative value on failure
217 *
218 * The open entry point is called when a network interface is made
219 * active by the system (IFF_UP).
220 **/
221static int ngbe_open(struct net_device *netdev)
222{
223	struct ngbe_adapter *adapter = netdev_priv(netdev);
224	struct ngbe_hw *hw = &adapter->hw;
225	struct wx_hw *wxhw = &hw->wxhw;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
227	wx_control_hw(wxhw, true);
228
229	return 0;
 
 
 
 
 
 
 
230}
231
232/**
233 * ngbe_close - Disables a network interface
234 * @netdev: network interface device structure
235 *
236 * Returns 0, this is not allowed to fail
237 *
238 * The close entry point is called when an interface is de-activated
239 * by the OS.  The hardware is still under the drivers control, but
240 * needs to be disabled.  A global MAC reset is issued to stop the
241 * hardware, and all transmit and receive resources are freed.
242 **/
243static int ngbe_close(struct net_device *netdev)
244{
245	struct ngbe_adapter *adapter = netdev_priv(netdev);
246
247	ngbe_down(adapter);
248	wx_control_hw(&adapter->hw.wxhw, false);
249
250	return 0;
251}
252
253static netdev_tx_t ngbe_xmit_frame(struct sk_buff *skb,
254				   struct net_device *netdev)
255{
256	return NETDEV_TX_OK;
257}
258
259/**
260 * ngbe_set_mac - Change the Ethernet Address of the NIC
261 * @netdev: network interface device structure
262 * @p: pointer to an address structure
263 *
264 * Returns 0 on success, negative on failure
265 **/
266static int ngbe_set_mac(struct net_device *netdev, void *p)
267{
268	struct ngbe_adapter *adapter = netdev_priv(netdev);
269	struct wx_hw *wxhw = &adapter->hw.wxhw;
270	struct sockaddr *addr = p;
271
272	if (!is_valid_ether_addr(addr->sa_data))
273		return -EADDRNOTAVAIL;
274
275	eth_hw_addr_set(netdev, addr->sa_data);
276	memcpy(wxhw->mac.addr, addr->sa_data, netdev->addr_len);
277
278	ngbe_mac_set_default_filter(adapter, wxhw->mac.addr);
 
 
 
 
279
280	return 0;
281}
282
283static void ngbe_dev_shutdown(struct pci_dev *pdev, bool *enable_wake)
284{
285	struct ngbe_adapter *adapter = pci_get_drvdata(pdev);
286	struct net_device *netdev = adapter->netdev;
 
287
 
 
288	netif_device_detach(netdev);
289
290	rtnl_lock();
291	if (netif_running(netdev))
292		ngbe_down(adapter);
 
293	rtnl_unlock();
294	wx_control_hw(&adapter->hw.wxhw, false);
 
 
 
 
 
 
 
 
 
 
295
296	pci_disable_device(pdev);
297}
298
299static void ngbe_shutdown(struct pci_dev *pdev)
300{
301	struct ngbe_adapter *adapter = pci_get_drvdata(pdev);
302	bool wake;
303
304	wake = !!adapter->wol;
305
306	ngbe_dev_shutdown(pdev, &wake);
307
308	if (system_state == SYSTEM_POWER_OFF) {
309		pci_wake_from_d3(pdev, wake);
310		pci_set_power_state(pdev, PCI_D3hot);
311	}
312}
313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314static const struct net_device_ops ngbe_netdev_ops = {
315	.ndo_open               = ngbe_open,
316	.ndo_stop               = ngbe_close,
317	.ndo_start_xmit         = ngbe_xmit_frame,
 
 
 
318	.ndo_validate_addr      = eth_validate_addr,
319	.ndo_set_mac_address    = ngbe_set_mac,
 
 
 
320};
321
322/**
323 * ngbe_probe - Device Initialization Routine
324 * @pdev: PCI device information struct
325 * @ent: entry in ngbe_pci_tbl
326 *
327 * Returns 0 on success, negative on failure
328 *
329 * ngbe_probe initializes an adapter identified by a pci_dev structure.
330 * The OS initialization, configuring of the adapter private structure,
331 * and a hardware reset occur.
332 **/
333static int ngbe_probe(struct pci_dev *pdev,
334		      const struct pci_device_id __always_unused *ent)
335{
336	struct ngbe_adapter *adapter = NULL;
337	struct ngbe_hw *hw = NULL;
338	struct wx_hw *wxhw = NULL;
339	struct net_device *netdev;
340	u32 e2rom_cksum_cap = 0;
 
341	static int func_nums;
342	u16 e2rom_ver = 0;
343	u32 etrack_id = 0;
344	u32 saved_ver = 0;
345	int err;
346
347	err = pci_enable_device_mem(pdev);
348	if (err)
349		return err;
350
351	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
352	if (err) {
353		dev_err(&pdev->dev,
354			"No usable DMA configuration, aborting\n");
355		goto err_pci_disable_dev;
356	}
357
358	err = pci_request_selected_regions(pdev,
359					   pci_select_bars(pdev, IORESOURCE_MEM),
360					   ngbe_driver_name);
361	if (err) {
362		dev_err(&pdev->dev,
363			"pci_request_selected_regions failed %d\n", err);
364		goto err_pci_disable_dev;
365	}
366
367	pci_enable_pcie_error_reporting(pdev);
368	pci_set_master(pdev);
369
370	netdev = devm_alloc_etherdev_mqs(&pdev->dev,
371					 sizeof(struct ngbe_adapter),
372					 NGBE_MAX_TX_QUEUES,
373					 NGBE_MAX_RX_QUEUES);
374	if (!netdev) {
375		err = -ENOMEM;
376		goto err_pci_release_regions;
377	}
378
379	SET_NETDEV_DEV(netdev, &pdev->dev);
380
381	adapter = netdev_priv(netdev);
382	adapter->netdev = netdev;
383	adapter->pdev = pdev;
384	hw = &adapter->hw;
385	wxhw = &hw->wxhw;
386	adapter->msg_enable = BIT(3) - 1;
387
388	adapter->io_addr = devm_ioremap(&pdev->dev,
389					pci_resource_start(pdev, 0),
390					pci_resource_len(pdev, 0));
391	if (!adapter->io_addr) {
392		err = -EIO;
393		goto err_pci_release_regions;
394	}
395
 
 
396	netdev->netdev_ops = &ngbe_netdev_ops;
397
 
 
 
 
 
 
 
 
 
398	netdev->features |= NETIF_F_HIGHDMA;
 
 
399
400	adapter->bd_number = func_nums;
 
 
 
 
 
 
 
 
401	/* setup the private structure */
402	err = ngbe_sw_init(adapter);
403	if (err)
404		goto err_free_mac_table;
405
406	/* check if flash load is done after hw power up */
407	err = wx_check_flash_load(wxhw, NGBE_SPI_ILDR_STATUS_PERST);
408	if (err)
409		goto err_free_mac_table;
410	err = wx_check_flash_load(wxhw, NGBE_SPI_ILDR_STATUS_PWRRST);
411	if (err)
412		goto err_free_mac_table;
413
414	err = wx_mng_present(wxhw);
415	if (err) {
416		dev_err(&pdev->dev, "Management capability is not present\n");
417		goto err_free_mac_table;
418	}
419
420	err = ngbe_reset_hw(hw);
421	if (err) {
422		dev_err(&pdev->dev, "HW Init failed: %d\n", err);
423		goto err_free_mac_table;
424	}
425
426	if (wxhw->bus.func == 0) {
427		wr32(wxhw, NGBE_CALSUM_CAP_STATUS, 0x0);
428		wr32(wxhw, NGBE_EEPROM_VERSION_STORE_REG, 0x0);
429	} else {
430		e2rom_cksum_cap = rd32(wxhw, NGBE_CALSUM_CAP_STATUS);
431		saved_ver = rd32(wxhw, NGBE_EEPROM_VERSION_STORE_REG);
432	}
433
434	wx_init_eeprom_params(wxhw);
435	if (wxhw->bus.func == 0 || e2rom_cksum_cap == 0) {
436		/* make sure the EEPROM is ready */
437		err = ngbe_eeprom_chksum_hostif(hw);
438		if (err) {
439			dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
440			err = -EIO;
441			goto err_free_mac_table;
442		}
443	}
444
445	adapter->wol = 0;
446	if (hw->wol_enabled)
447		adapter->wol = NGBE_PSR_WKUP_CTL_MAG;
448
449	hw->wol_enabled = !!(adapter->wol);
450	wr32(wxhw, NGBE_PSR_WKUP_CTL, adapter->wol);
451
452	device_set_wakeup_enable(&pdev->dev, adapter->wol);
453
454	/* Save off EEPROM version number and Option Rom version which
455	 * together make a unique identify for the eeprom
456	 */
457	if (saved_ver) {
458		etrack_id = saved_ver;
459	} else {
460		wx_read_ee_hostif(wxhw,
461				  wxhw->eeprom.sw_region_offset + NGBE_EEPROM_VERSION_H,
462				  &e2rom_ver);
463		etrack_id = e2rom_ver << 16;
464		wx_read_ee_hostif(wxhw,
465				  wxhw->eeprom.sw_region_offset + NGBE_EEPROM_VERSION_L,
466				  &e2rom_ver);
467		etrack_id |= e2rom_ver;
468		wr32(wxhw, NGBE_EEPROM_VERSION_STORE_REG, etrack_id);
469	}
 
 
470
471	eth_hw_addr_set(netdev, wxhw->mac.perm_addr);
472	ngbe_mac_set_default_filter(adapter, wxhw->mac.perm_addr);
 
 
 
 
 
 
 
 
 
473
474	err = register_netdev(netdev);
475	if (err)
476		goto err_register;
477
478	pci_set_drvdata(pdev, adapter);
479
480	netif_info(adapter, probe, netdev,
481		   "PHY: %s, PBA No: Wang Xun GbE Family Controller\n",
482		   hw->phy.type == ngbe_phy_internal ? "Internal" : "External");
483	netif_info(adapter, probe, netdev, "%pM\n", netdev->dev_addr);
484
485	return 0;
486
487err_register:
488	wx_control_hw(wxhw, false);
 
 
 
489err_free_mac_table:
490	kfree(adapter->mac_table);
491err_pci_release_regions:
492	pci_disable_pcie_error_reporting(pdev);
493	pci_release_selected_regions(pdev,
494				     pci_select_bars(pdev, IORESOURCE_MEM));
495err_pci_disable_dev:
496	pci_disable_device(pdev);
497	return err;
498}
499
500/**
501 * ngbe_remove - Device Removal Routine
502 * @pdev: PCI device information struct
503 *
504 * ngbe_remove is called by the PCI subsystem to alert the driver
505 * that it should release a PCI device.  The could be caused by a
506 * Hot-Plug event, or because the driver is going to be removed from
507 * memory.
508 **/
509static void ngbe_remove(struct pci_dev *pdev)
510{
511	struct ngbe_adapter *adapter = pci_get_drvdata(pdev);
512	struct net_device *netdev;
513
514	netdev = adapter->netdev;
515	unregister_netdev(netdev);
 
516	pci_release_selected_regions(pdev,
517				     pci_select_bars(pdev, IORESOURCE_MEM));
518
519	kfree(adapter->mac_table);
520	pci_disable_pcie_error_reporting(pdev);
 
521
522	pci_disable_device(pdev);
523}
524
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525static struct pci_driver ngbe_driver = {
526	.name     = ngbe_driver_name,
527	.id_table = ngbe_pci_tbl,
528	.probe    = ngbe_probe,
529	.remove   = ngbe_remove,
 
 
530	.shutdown = ngbe_shutdown,
531};
532
533module_pci_driver(ngbe_driver);
534
535MODULE_DEVICE_TABLE(pci, ngbe_pci_tbl);
536MODULE_AUTHOR("Beijing WangXun Technology Co., Ltd, <software@net-swift.com>");
537MODULE_DESCRIPTION("WangXun(R) Gigabit PCI Express Network Driver");
538MODULE_LICENSE("GPL");