1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2015 - 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 12 #include "txgbe.h" 13 14 char txgbe_driver_name[] = "txgbe"; 15 16 /* txgbe_pci_tbl - PCI Device ID Table 17 * 18 * Wildcard entries (PCI_ANY_ID) should come last 19 * Last entry must be all 0s 20 * 21 * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, 22 * Class, Class Mask, private data (not used) } 23 */ 24 static const struct pci_device_id txgbe_pci_tbl[] = { 25 { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_SP1000), 0}, 26 { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_WX1820), 0}, 27 /* required last entry */ 28 { .device = 0 } 29 }; 30 31 #define DEFAULT_DEBUG_LEVEL_SHIFT 3 32 33 static void txgbe_dev_shutdown(struct pci_dev *pdev, bool *enable_wake) 34 { 35 struct txgbe_adapter *adapter = pci_get_drvdata(pdev); 36 struct net_device *netdev = adapter->netdev; 37 38 netif_device_detach(netdev); 39 40 pci_disable_device(pdev); 41 } 42 43 static void txgbe_shutdown(struct pci_dev *pdev) 44 { 45 bool wake; 46 47 txgbe_dev_shutdown(pdev, &wake); 48 49 if (system_state == SYSTEM_POWER_OFF) { 50 pci_wake_from_d3(pdev, wake); 51 pci_set_power_state(pdev, PCI_D3hot); 52 } 53 } 54 55 /** 56 * txgbe_probe - Device Initialization Routine 57 * @pdev: PCI device information struct 58 * @ent: entry in txgbe_pci_tbl 59 * 60 * Returns 0 on success, negative on failure 61 * 62 * txgbe_probe initializes an adapter identified by a pci_dev structure. 63 * The OS initialization, configuring of the adapter private structure, 64 * and a hardware reset occur. 65 **/ 66 static int txgbe_probe(struct pci_dev *pdev, 67 const struct pci_device_id __always_unused *ent) 68 { 69 struct txgbe_adapter *adapter = NULL; 70 struct net_device *netdev; 71 int err; 72 73 err = pci_enable_device_mem(pdev); 74 if (err) 75 return err; 76 77 err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 78 if (err) { 79 dev_err(&pdev->dev, 80 "No usable DMA configuration, aborting\n"); 81 goto err_pci_disable_dev; 82 } 83 84 err = pci_request_selected_regions(pdev, 85 pci_select_bars(pdev, IORESOURCE_MEM), 86 txgbe_driver_name); 87 if (err) { 88 dev_err(&pdev->dev, 89 "pci_request_selected_regions failed 0x%x\n", err); 90 goto err_pci_disable_dev; 91 } 92 93 pci_enable_pcie_error_reporting(pdev); 94 pci_set_master(pdev); 95 96 netdev = devm_alloc_etherdev_mqs(&pdev->dev, 97 sizeof(struct txgbe_adapter), 98 TXGBE_MAX_TX_QUEUES, 99 TXGBE_MAX_RX_QUEUES); 100 if (!netdev) { 101 err = -ENOMEM; 102 goto err_pci_release_regions; 103 } 104 105 SET_NETDEV_DEV(netdev, &pdev->dev); 106 107 adapter = netdev_priv(netdev); 108 adapter->netdev = netdev; 109 adapter->pdev = pdev; 110 111 adapter->io_addr = devm_ioremap(&pdev->dev, 112 pci_resource_start(pdev, 0), 113 pci_resource_len(pdev, 0)); 114 if (!adapter->io_addr) { 115 err = -EIO; 116 goto err_pci_release_regions; 117 } 118 119 netdev->features |= NETIF_F_HIGHDMA; 120 121 pci_set_drvdata(pdev, adapter); 122 123 return 0; 124 125 err_pci_release_regions: 126 pci_release_selected_regions(pdev, 127 pci_select_bars(pdev, IORESOURCE_MEM)); 128 err_pci_disable_dev: 129 pci_disable_device(pdev); 130 return err; 131 } 132 133 /** 134 * txgbe_remove - Device Removal Routine 135 * @pdev: PCI device information struct 136 * 137 * txgbe_remove is called by the PCI subsystem to alert the driver 138 * that it should release a PCI device. The could be caused by a 139 * Hot-Plug event, or because the driver is going to be removed from 140 * memory. 141 **/ 142 static void txgbe_remove(struct pci_dev *pdev) 143 { 144 pci_release_selected_regions(pdev, 145 pci_select_bars(pdev, IORESOURCE_MEM)); 146 147 pci_disable_pcie_error_reporting(pdev); 148 149 pci_disable_device(pdev); 150 } 151 152 static struct pci_driver txgbe_driver = { 153 .name = txgbe_driver_name, 154 .id_table = txgbe_pci_tbl, 155 .probe = txgbe_probe, 156 .remove = txgbe_remove, 157 .shutdown = txgbe_shutdown, 158 }; 159 160 module_pci_driver(txgbe_driver); 161 162 MODULE_DEVICE_TABLE(pci, txgbe_pci_tbl); 163 MODULE_AUTHOR("Beijing WangXun Technology Co., Ltd, <software@trustnetic.com>"); 164 MODULE_DESCRIPTION("WangXun(R) 10 Gigabit PCI Express Network Driver"); 165 MODULE_LICENSE("GPL"); 166