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 The full GNU General Public License is included in this distribution in 16 the file called "COPYING". 17 18 Author: Rayagond Kokatanur <rayagond@vayavyalabs.com> 19 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 20 *******************************************************************************/ 21 22 #include <linux/pci.h> 23 #include <linux/dmi.h> 24 25 #include "stmmac.h" 26 27 /* 28 * This struct is used to associate PCI Function of MAC controller on a board, 29 * discovered via DMI, with the address of PHY connected to the MAC. The 30 * negative value of the address means that MAC controller is not connected 31 * with PHY. 32 */ 33 struct stmmac_pci_dmi_data { 34 const char *name; 35 const char *asset_tag; 36 unsigned int func; 37 int phy_addr; 38 }; 39 40 struct stmmac_pci_info { 41 struct pci_dev *pdev; 42 int (*setup)(struct plat_stmmacenet_data *plat, 43 struct stmmac_pci_info *info); 44 struct stmmac_pci_dmi_data *dmi; 45 }; 46 47 static int stmmac_pci_find_phy_addr(struct stmmac_pci_info *info) 48 { 49 const char *name = dmi_get_system_info(DMI_BOARD_NAME); 50 const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG); 51 unsigned int func = PCI_FUNC(info->pdev->devfn); 52 struct stmmac_pci_dmi_data *dmi; 53 54 /* 55 * Galileo boards with old firmware don't support DMI. We always return 56 * 1 here, so at least first found MAC controller would be probed. 57 */ 58 if (!name) 59 return 1; 60 61 for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) { 62 if (!strcmp(dmi->name, name) && dmi->func == func) { 63 /* If asset tag is provided, match on it as well. */ 64 if (dmi->asset_tag && strcmp(dmi->asset_tag, asset_tag)) 65 continue; 66 return dmi->phy_addr; 67 } 68 } 69 70 return -ENODEV; 71 } 72 73 static void common_default_data(struct plat_stmmacenet_data *plat) 74 { 75 plat->clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ 76 plat->has_gmac = 1; 77 plat->force_sf_dma_mode = 1; 78 79 plat->mdio_bus_data->phy_reset = NULL; 80 plat->mdio_bus_data->phy_mask = 0; 81 82 /* Set default value for multicast hash bins */ 83 plat->multicast_filter_bins = HASH_TABLE_SIZE; 84 85 /* Set default value for unicast filter entries */ 86 plat->unicast_filter_entries = 1; 87 88 /* Set the maxmtu to a default of JUMBO_LEN */ 89 plat->maxmtu = JUMBO_LEN; 90 91 /* Set default number of RX and TX queues to use */ 92 plat->tx_queues_to_use = 1; 93 plat->rx_queues_to_use = 1; 94 95 /* Disable Priority config by default */ 96 plat->tx_queues_cfg[0].use_prio = false; 97 plat->rx_queues_cfg[0].use_prio = false; 98 99 /* Disable RX queues routing by default */ 100 plat->rx_queues_cfg[0].pkt_route = 0x0; 101 } 102 103 static void stmmac_default_data(struct plat_stmmacenet_data *plat) 104 { 105 /* Set common default data first */ 106 common_default_data(plat); 107 108 plat->bus_id = 1; 109 plat->phy_addr = 0; 110 plat->interface = PHY_INTERFACE_MODE_GMII; 111 112 plat->dma_cfg->pbl = 32; 113 plat->dma_cfg->pblx8 = true; 114 /* TODO: AXI */ 115 } 116 117 static int quark_default_data(struct plat_stmmacenet_data *plat, 118 struct stmmac_pci_info *info) 119 { 120 struct pci_dev *pdev = info->pdev; 121 int ret; 122 123 /* Set common default data first */ 124 common_default_data(plat); 125 126 /* 127 * Refuse to load the driver and register net device if MAC controller 128 * does not connect to any PHY interface. 129 */ 130 ret = stmmac_pci_find_phy_addr(info); 131 if (ret < 0) 132 return ret; 133 134 plat->bus_id = PCI_DEVID(pdev->bus->number, pdev->devfn); 135 plat->phy_addr = ret; 136 plat->interface = PHY_INTERFACE_MODE_RMII; 137 138 plat->dma_cfg->pbl = 16; 139 plat->dma_cfg->pblx8 = true; 140 plat->dma_cfg->fixed_burst = 1; 141 /* AXI (TODO) */ 142 143 return 0; 144 } 145 146 static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = { 147 { 148 .name = "Galileo", 149 .func = 6, 150 .phy_addr = 1, 151 }, 152 { 153 .name = "GalileoGen2", 154 .func = 6, 155 .phy_addr = 1, 156 }, 157 { 158 .name = "SIMATIC IOT2000", 159 .asset_tag = "6ES7647-0AA00-0YA2", 160 .func = 6, 161 .phy_addr = 1, 162 }, 163 { 164 .name = "SIMATIC IOT2000", 165 .asset_tag = "6ES7647-0AA00-1YA2", 166 .func = 6, 167 .phy_addr = 1, 168 }, 169 { 170 .name = "SIMATIC IOT2000", 171 .asset_tag = "6ES7647-0AA00-1YA2", 172 .func = 7, 173 .phy_addr = 1, 174 }, 175 {} 176 }; 177 178 static struct stmmac_pci_info quark_pci_info = { 179 .setup = quark_default_data, 180 .dmi = quark_pci_dmi_data, 181 }; 182 183 /** 184 * stmmac_pci_probe 185 * 186 * @pdev: pci device pointer 187 * @id: pointer to table of device id/id's. 188 * 189 * Description: This probing function gets called for all PCI devices which 190 * match the ID table and are not "owned" by other driver yet. This function 191 * gets passed a "struct pci_dev *" for each device whose entry in the ID table 192 * matches the device. The probe functions returns zero when the driver choose 193 * to take "ownership" of the device or an error code(-ve no) otherwise. 194 */ 195 static int stmmac_pci_probe(struct pci_dev *pdev, 196 const struct pci_device_id *id) 197 { 198 struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data; 199 struct plat_stmmacenet_data *plat; 200 struct stmmac_resources res; 201 int i; 202 int ret; 203 204 plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); 205 if (!plat) 206 return -ENOMEM; 207 208 plat->mdio_bus_data = devm_kzalloc(&pdev->dev, 209 sizeof(*plat->mdio_bus_data), 210 GFP_KERNEL); 211 if (!plat->mdio_bus_data) 212 return -ENOMEM; 213 214 plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), 215 GFP_KERNEL); 216 if (!plat->dma_cfg) 217 return -ENOMEM; 218 219 /* Enable pci device */ 220 ret = pcim_enable_device(pdev); 221 if (ret) { 222 dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", 223 __func__); 224 return ret; 225 } 226 227 /* Get the base address of device */ 228 for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { 229 if (pci_resource_len(pdev, i) == 0) 230 continue; 231 ret = pcim_iomap_regions(pdev, BIT(i), pci_name(pdev)); 232 if (ret) 233 return ret; 234 break; 235 } 236 237 pci_set_master(pdev); 238 239 if (info) { 240 info->pdev = pdev; 241 if (info->setup) { 242 ret = info->setup(plat, info); 243 if (ret) 244 return ret; 245 } 246 } else 247 stmmac_default_data(plat); 248 249 pci_enable_msi(pdev); 250 251 memset(&res, 0, sizeof(res)); 252 res.addr = pcim_iomap_table(pdev)[i]; 253 res.wol_irq = pdev->irq; 254 res.irq = pdev->irq; 255 256 return stmmac_dvr_probe(&pdev->dev, plat, &res); 257 } 258 259 /** 260 * stmmac_pci_remove 261 * 262 * @pdev: platform device pointer 263 * Description: this function calls the main to free the net resources 264 * and releases the PCI resources. 265 */ 266 static void stmmac_pci_remove(struct pci_dev *pdev) 267 { 268 stmmac_dvr_remove(&pdev->dev); 269 } 270 271 static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_suspend, stmmac_resume); 272 273 #define STMMAC_VENDOR_ID 0x700 274 #define STMMAC_QUARK_ID 0x0937 275 #define STMMAC_DEVICE_ID 0x1108 276 277 static const struct pci_device_id stmmac_id_table[] = { 278 {PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)}, 279 {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)}, 280 {PCI_VDEVICE(INTEL, STMMAC_QUARK_ID), (kernel_ulong_t)&quark_pci_info}, 281 {} 282 }; 283 284 MODULE_DEVICE_TABLE(pci, stmmac_id_table); 285 286 static struct pci_driver stmmac_pci_driver = { 287 .name = STMMAC_RESOURCE_NAME, 288 .id_table = stmmac_id_table, 289 .probe = stmmac_pci_probe, 290 .remove = stmmac_pci_remove, 291 .driver = { 292 .pm = &stmmac_pm_ops, 293 }, 294 }; 295 296 module_pci_driver(stmmac_pci_driver); 297 298 MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver"); 299 MODULE_AUTHOR("Rayagond Kokatanur <rayagond.kokatanur@vayavyalabs.com>"); 300 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 301 MODULE_LICENSE("GPL"); 302