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