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_disable_pcie_error_reporting(pdev); 127 pci_release_selected_regions(pdev, 128 pci_select_bars(pdev, IORESOURCE_MEM)); 129 err_pci_disable_dev: 130 pci_disable_device(pdev); 131 return err; 132 } 133 134 /** 135 * txgbe_remove - Device Removal Routine 136 * @pdev: PCI device information struct 137 * 138 * txgbe_remove is called by the PCI subsystem to alert the driver 139 * that it should release a PCI device. The could be caused by a 140 * Hot-Plug event, or because the driver is going to be removed from 141 * memory. 142 **/ 143 static void txgbe_remove(struct pci_dev *pdev) 144 { 145 pci_release_selected_regions(pdev, 146 pci_select_bars(pdev, IORESOURCE_MEM)); 147 148 pci_disable_pcie_error_reporting(pdev); 149 150 pci_disable_device(pdev); 151 } 152 153 static struct pci_driver txgbe_driver = { 154 .name = txgbe_driver_name, 155 .id_table = txgbe_pci_tbl, 156 .probe = txgbe_probe, 157 .remove = txgbe_remove, 158 .shutdown = txgbe_shutdown, 159 }; 160 161 module_pci_driver(txgbe_driver); 162 163 MODULE_DEVICE_TABLE(pci, txgbe_pci_tbl); 164 MODULE_AUTHOR("Beijing WangXun Technology Co., Ltd, <software@trustnetic.com>"); 165 MODULE_DESCRIPTION("WangXun(R) 10 Gigabit PCI Express Network Driver"); 166 MODULE_LICENSE("GPL"); 167