1 /******************************************************************************* 2 This contains the functions to handle the pci driver. 3 4 Copyright (C) 2011-2012 Vayavya Labs Pvt Ltd 5 6 This program is free software; you can redistribute it and/or modify it 7 under the terms and conditions of the GNU General Public License, 8 version 2, as published by the Free Software Foundation. 9 10 This program is distributed in the hope it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 more details. 14 15 You should have received a copy of the GNU General Public License along with 16 this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 19 The full GNU General Public License is included in this distribution in 20 the file called "COPYING". 21 22 Author: Rayagond Kokatanur <rayagond@vayavyalabs.com> 23 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 24 *******************************************************************************/ 25 26 #include <linux/pci.h> 27 #include "stmmac.h" 28 29 static struct plat_stmmacenet_data plat_dat; 30 static struct stmmac_mdio_bus_data mdio_data; 31 static struct stmmac_dma_cfg dma_cfg; 32 33 static void stmmac_default_data(void) 34 { 35 memset(&plat_dat, 0, sizeof(struct plat_stmmacenet_data)); 36 37 plat_dat.bus_id = 1; 38 plat_dat.phy_addr = 0; 39 plat_dat.interface = PHY_INTERFACE_MODE_GMII; 40 plat_dat.clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ 41 plat_dat.has_gmac = 1; 42 plat_dat.force_sf_dma_mode = 1; 43 44 mdio_data.phy_reset = NULL; 45 mdio_data.phy_mask = 0; 46 plat_dat.mdio_bus_data = &mdio_data; 47 48 dma_cfg.pbl = 32; 49 dma_cfg.burst_len = DMA_AXI_BLEN_256; 50 plat_dat.dma_cfg = &dma_cfg; 51 52 /* Set default value for multicast hash bins */ 53 plat_dat.multicast_filter_bins = HASH_TABLE_SIZE; 54 55 /* Set default value for unicast filter entries */ 56 plat_dat.unicast_filter_entries = 1; 57 } 58 59 /** 60 * stmmac_pci_probe 61 * 62 * @pdev: pci device pointer 63 * @id: pointer to table of device id/id's. 64 * 65 * Description: This probing function gets called for all PCI devices which 66 * match the ID table and are not "owned" by other driver yet. This function 67 * gets passed a "struct pci_dev *" for each device whose entry in the ID table 68 * matches the device. The probe functions returns zero when the driver choose 69 * to take "ownership" of the device or an error code(-ve no) otherwise. 70 */ 71 static int stmmac_pci_probe(struct pci_dev *pdev, 72 const struct pci_device_id *id) 73 { 74 int ret = 0; 75 void __iomem *addr = NULL; 76 struct stmmac_priv *priv = NULL; 77 int i; 78 79 /* Enable pci device */ 80 ret = pci_enable_device(pdev); 81 if (ret) { 82 pr_err("%s : ERROR: failed to enable %s device\n", __func__, 83 pci_name(pdev)); 84 return ret; 85 } 86 if (pci_request_regions(pdev, STMMAC_RESOURCE_NAME)) { 87 pr_err("%s: ERROR: failed to get PCI region\n", __func__); 88 ret = -ENODEV; 89 goto err_out_req_reg_failed; 90 } 91 92 /* Get the base address of device */ 93 for (i = 0; i <= 5; i++) { 94 if (pci_resource_len(pdev, i) == 0) 95 continue; 96 addr = pci_iomap(pdev, i, 0); 97 if (addr == NULL) { 98 pr_err("%s: ERROR: cannot map register memory aborting", 99 __func__); 100 ret = -EIO; 101 goto err_out_map_failed; 102 } 103 break; 104 } 105 pci_set_master(pdev); 106 107 stmmac_default_data(); 108 109 priv = stmmac_dvr_probe(&(pdev->dev), &plat_dat, addr); 110 if (IS_ERR(priv)) { 111 pr_err("%s: main driver probe failed", __func__); 112 ret = PTR_ERR(priv); 113 goto err_out; 114 } 115 priv->dev->irq = pdev->irq; 116 priv->wol_irq = pdev->irq; 117 118 pci_set_drvdata(pdev, priv->dev); 119 120 pr_debug("STMMAC platform driver registration completed"); 121 122 return 0; 123 124 err_out: 125 pci_clear_master(pdev); 126 err_out_map_failed: 127 pci_release_regions(pdev); 128 err_out_req_reg_failed: 129 pci_disable_device(pdev); 130 131 return ret; 132 } 133 134 /** 135 * stmmac_pci_remove 136 * 137 * @pdev: platform device pointer 138 * Description: this function calls the main to free the net resources 139 * and releases the PCI resources. 140 */ 141 static void stmmac_pci_remove(struct pci_dev *pdev) 142 { 143 struct net_device *ndev = pci_get_drvdata(pdev); 144 struct stmmac_priv *priv = netdev_priv(ndev); 145 146 stmmac_dvr_remove(ndev); 147 148 pci_iounmap(pdev, priv->ioaddr); 149 pci_release_regions(pdev); 150 pci_disable_device(pdev); 151 } 152 153 #ifdef CONFIG_PM 154 static int stmmac_pci_suspend(struct pci_dev *pdev, pm_message_t state) 155 { 156 struct net_device *ndev = pci_get_drvdata(pdev); 157 int ret; 158 159 ret = stmmac_suspend(ndev); 160 pci_save_state(pdev); 161 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 162 163 return ret; 164 } 165 166 static int stmmac_pci_resume(struct pci_dev *pdev) 167 { 168 struct net_device *ndev = pci_get_drvdata(pdev); 169 170 pci_set_power_state(pdev, PCI_D0); 171 pci_restore_state(pdev); 172 173 return stmmac_resume(ndev); 174 } 175 #endif 176 177 #define STMMAC_VENDOR_ID 0x700 178 #define STMMAC_DEVICE_ID 0x1108 179 180 static const struct pci_device_id stmmac_id_table[] = { 181 {PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)}, 182 {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)}, 183 {} 184 }; 185 186 MODULE_DEVICE_TABLE(pci, stmmac_id_table); 187 188 struct pci_driver stmmac_pci_driver = { 189 .name = STMMAC_RESOURCE_NAME, 190 .id_table = stmmac_id_table, 191 .probe = stmmac_pci_probe, 192 .remove = stmmac_pci_remove, 193 #ifdef CONFIG_PM 194 .suspend = stmmac_pci_suspend, 195 .resume = stmmac_pci_resume, 196 #endif 197 }; 198 199 MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver"); 200 MODULE_AUTHOR("Rayagond Kokatanur <rayagond.kokatanur@vayavyalabs.com>"); 201 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 202 MODULE_LICENSE("GPL"); 203