Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2015 - 2022 Beijing WangXun Technology Co., Ltd. */
0003 
0004 #include <linux/types.h>
0005 #include <linux/module.h>
0006 #include <linux/pci.h>
0007 #include <linux/netdevice.h>
0008 #include <linux/string.h>
0009 #include <linux/aer.h>
0010 #include <linux/etherdevice.h>
0011 
0012 #include "txgbe.h"
0013 
0014 char txgbe_driver_name[] = "txgbe";
0015 
0016 /* txgbe_pci_tbl - PCI Device ID Table
0017  *
0018  * Wildcard entries (PCI_ANY_ID) should come last
0019  * Last entry must be all 0s
0020  *
0021  * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
0022  *   Class, Class Mask, private data (not used) }
0023  */
0024 static const struct pci_device_id txgbe_pci_tbl[] = {
0025     { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_SP1000), 0},
0026     { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_WX1820), 0},
0027     /* required last entry */
0028     { .device = 0 }
0029 };
0030 
0031 #define DEFAULT_DEBUG_LEVEL_SHIFT 3
0032 
0033 static void txgbe_dev_shutdown(struct pci_dev *pdev, bool *enable_wake)
0034 {
0035     struct txgbe_adapter *adapter = pci_get_drvdata(pdev);
0036     struct net_device *netdev = adapter->netdev;
0037 
0038     netif_device_detach(netdev);
0039 
0040     pci_disable_device(pdev);
0041 }
0042 
0043 static void txgbe_shutdown(struct pci_dev *pdev)
0044 {
0045     bool wake;
0046 
0047     txgbe_dev_shutdown(pdev, &wake);
0048 
0049     if (system_state == SYSTEM_POWER_OFF) {
0050         pci_wake_from_d3(pdev, wake);
0051         pci_set_power_state(pdev, PCI_D3hot);
0052     }
0053 }
0054 
0055 /**
0056  * txgbe_probe - Device Initialization Routine
0057  * @pdev: PCI device information struct
0058  * @ent: entry in txgbe_pci_tbl
0059  *
0060  * Returns 0 on success, negative on failure
0061  *
0062  * txgbe_probe initializes an adapter identified by a pci_dev structure.
0063  * The OS initialization, configuring of the adapter private structure,
0064  * and a hardware reset occur.
0065  **/
0066 static int txgbe_probe(struct pci_dev *pdev,
0067                const struct pci_device_id __always_unused *ent)
0068 {
0069     struct txgbe_adapter *adapter = NULL;
0070     struct net_device *netdev;
0071     int err;
0072 
0073     err = pci_enable_device_mem(pdev);
0074     if (err)
0075         return err;
0076 
0077     err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
0078     if (err) {
0079         dev_err(&pdev->dev,
0080             "No usable DMA configuration, aborting\n");
0081         goto err_pci_disable_dev;
0082     }
0083 
0084     err = pci_request_selected_regions(pdev,
0085                        pci_select_bars(pdev, IORESOURCE_MEM),
0086                        txgbe_driver_name);
0087     if (err) {
0088         dev_err(&pdev->dev,
0089             "pci_request_selected_regions failed 0x%x\n", err);
0090         goto err_pci_disable_dev;
0091     }
0092 
0093     pci_enable_pcie_error_reporting(pdev);
0094     pci_set_master(pdev);
0095 
0096     netdev = devm_alloc_etherdev_mqs(&pdev->dev,
0097                      sizeof(struct txgbe_adapter),
0098                      TXGBE_MAX_TX_QUEUES,
0099                      TXGBE_MAX_RX_QUEUES);
0100     if (!netdev) {
0101         err = -ENOMEM;
0102         goto err_pci_release_regions;
0103     }
0104 
0105     SET_NETDEV_DEV(netdev, &pdev->dev);
0106 
0107     adapter = netdev_priv(netdev);
0108     adapter->netdev = netdev;
0109     adapter->pdev = pdev;
0110 
0111     adapter->io_addr = devm_ioremap(&pdev->dev,
0112                     pci_resource_start(pdev, 0),
0113                     pci_resource_len(pdev, 0));
0114     if (!adapter->io_addr) {
0115         err = -EIO;
0116         goto err_pci_release_regions;
0117     }
0118 
0119     netdev->features |= NETIF_F_HIGHDMA;
0120 
0121     pci_set_drvdata(pdev, adapter);
0122 
0123     return 0;
0124 
0125 err_pci_release_regions:
0126     pci_disable_pcie_error_reporting(pdev);
0127     pci_release_selected_regions(pdev,
0128                      pci_select_bars(pdev, IORESOURCE_MEM));
0129 err_pci_disable_dev:
0130     pci_disable_device(pdev);
0131     return err;
0132 }
0133 
0134 /**
0135  * txgbe_remove - Device Removal Routine
0136  * @pdev: PCI device information struct
0137  *
0138  * txgbe_remove is called by the PCI subsystem to alert the driver
0139  * that it should release a PCI device.  The could be caused by a
0140  * Hot-Plug event, or because the driver is going to be removed from
0141  * memory.
0142  **/
0143 static void txgbe_remove(struct pci_dev *pdev)
0144 {
0145     pci_release_selected_regions(pdev,
0146                      pci_select_bars(pdev, IORESOURCE_MEM));
0147 
0148     pci_disable_pcie_error_reporting(pdev);
0149 
0150     pci_disable_device(pdev);
0151 }
0152 
0153 static struct pci_driver txgbe_driver = {
0154     .name     = txgbe_driver_name,
0155     .id_table = txgbe_pci_tbl,
0156     .probe    = txgbe_probe,
0157     .remove   = txgbe_remove,
0158     .shutdown = txgbe_shutdown,
0159 };
0160 
0161 module_pci_driver(txgbe_driver);
0162 
0163 MODULE_DEVICE_TABLE(pci, txgbe_pci_tbl);
0164 MODULE_AUTHOR("Beijing WangXun Technology Co., Ltd, <software@trustnetic.com>");
0165 MODULE_DESCRIPTION("WangXun(R) 10 Gigabit PCI Express Network Driver");
0166 MODULE_LICENSE("GPL");