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