Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*******************************************************************************
3 : : This contains the functions to handle the pci driver.
4 : :
5 : : Copyright (C) 2011-2012 Vayavya Labs Pvt Ltd
6 : :
7 : :
8 : : Author: Rayagond Kokatanur <rayagond@vayavyalabs.com>
9 : : Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
10 : : *******************************************************************************/
11 : :
12 : : #include <linux/clk-provider.h>
13 : : #include <linux/pci.h>
14 : : #include <linux/dmi.h>
15 : :
16 : : #include "stmmac.h"
17 : :
18 : : /*
19 : : * This struct is used to associate PCI Function of MAC controller on a board,
20 : : * discovered via DMI, with the address of PHY connected to the MAC. The
21 : : * negative value of the address means that MAC controller is not connected
22 : : * with PHY.
23 : : */
24 : : struct stmmac_pci_func_data {
25 : : unsigned int func;
26 : : int phy_addr;
27 : : };
28 : :
29 : : struct stmmac_pci_dmi_data {
30 : : const struct stmmac_pci_func_data *func;
31 : : size_t nfuncs;
32 : : };
33 : :
34 : : struct stmmac_pci_info {
35 : : int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
36 : : };
37 : :
38 : : static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
39 : : const struct dmi_system_id *dmi_list)
40 : : {
41 : : const struct stmmac_pci_func_data *func_data;
42 : : const struct stmmac_pci_dmi_data *dmi_data;
43 : : const struct dmi_system_id *dmi_id;
44 : : int func = PCI_FUNC(pdev->devfn);
45 : : size_t n;
46 : :
47 : : dmi_id = dmi_first_match(dmi_list);
48 : : if (!dmi_id)
49 : : return -ENODEV;
50 : :
51 : : dmi_data = dmi_id->driver_data;
52 : : func_data = dmi_data->func;
53 : :
54 : : for (n = 0; n < dmi_data->nfuncs; n++, func_data++)
55 : : if (func_data->func == func)
56 : : return func_data->phy_addr;
57 : :
58 : : return -ENODEV;
59 : : }
60 : :
61 : 21 : static void common_default_data(struct plat_stmmacenet_data *plat)
62 : : {
63 : 21 : plat->clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
64 : 21 : plat->has_gmac = 1;
65 : 21 : plat->force_sf_dma_mode = 1;
66 : :
67 : 21 : plat->mdio_bus_data->needs_reset = true;
68 : :
69 : : /* Set default value for multicast hash bins */
70 : 21 : plat->multicast_filter_bins = HASH_TABLE_SIZE;
71 : :
72 : : /* Set default value for unicast filter entries */
73 : 21 : plat->unicast_filter_entries = 1;
74 : :
75 : : /* Set the maxmtu to a default of JUMBO_LEN */
76 : 21 : plat->maxmtu = JUMBO_LEN;
77 : :
78 : : /* Set default number of RX and TX queues to use */
79 : 21 : plat->tx_queues_to_use = 1;
80 : 21 : plat->rx_queues_to_use = 1;
81 : :
82 : : /* Disable Priority config by default */
83 : 21 : plat->tx_queues_cfg[0].use_prio = false;
84 : 21 : plat->rx_queues_cfg[0].use_prio = false;
85 : :
86 : : /* Disable RX queues routing by default */
87 : 21 : plat->rx_queues_cfg[0].pkt_route = 0x0;
88 : : }
89 : :
90 : 0 : static int stmmac_default_data(struct pci_dev *pdev,
91 : : struct plat_stmmacenet_data *plat)
92 : : {
93 : : /* Set common default data first */
94 : 0 : common_default_data(plat);
95 : :
96 : 0 : plat->bus_id = 1;
97 : 0 : plat->phy_addr = 0;
98 : 0 : plat->phy_interface = PHY_INTERFACE_MODE_GMII;
99 : :
100 : 0 : plat->dma_cfg->pbl = 32;
101 : 0 : plat->dma_cfg->pblx8 = true;
102 : : /* TODO: AXI */
103 : :
104 : 0 : return 0;
105 : : }
106 : :
107 : : static const struct stmmac_pci_info stmmac_pci_info = {
108 : : .setup = stmmac_default_data,
109 : : };
110 : :
111 : 0 : static int intel_mgbe_common_data(struct pci_dev *pdev,
112 : : struct plat_stmmacenet_data *plat)
113 : : {
114 : 0 : int i;
115 : :
116 : 0 : plat->clk_csr = 5;
117 : 0 : plat->has_gmac = 0;
118 : 0 : plat->has_gmac4 = 1;
119 : 0 : plat->force_sf_dma_mode = 0;
120 : 0 : plat->tso_en = 1;
121 : :
122 : 0 : plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
123 : :
124 [ # # ]: 0 : for (i = 0; i < plat->rx_queues_to_use; i++) {
125 : 0 : plat->rx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
126 : 0 : plat->rx_queues_cfg[i].chan = i;
127 : :
128 : : /* Disable Priority config by default */
129 : 0 : plat->rx_queues_cfg[i].use_prio = false;
130 : :
131 : : /* Disable RX queues routing by default */
132 : 0 : plat->rx_queues_cfg[i].pkt_route = 0x0;
133 : : }
134 : :
135 [ # # ]: 0 : for (i = 0; i < plat->tx_queues_to_use; i++) {
136 : 0 : plat->tx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
137 : :
138 : : /* Disable Priority config by default */
139 : 0 : plat->tx_queues_cfg[i].use_prio = false;
140 : : }
141 : :
142 : : /* FIFO size is 4096 bytes for 1 tx/rx queue */
143 : 0 : plat->tx_fifo_size = plat->tx_queues_to_use * 4096;
144 : 0 : plat->rx_fifo_size = plat->rx_queues_to_use * 4096;
145 : :
146 : 0 : plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WRR;
147 : 0 : plat->tx_queues_cfg[0].weight = 0x09;
148 : 0 : plat->tx_queues_cfg[1].weight = 0x0A;
149 : 0 : plat->tx_queues_cfg[2].weight = 0x0B;
150 : 0 : plat->tx_queues_cfg[3].weight = 0x0C;
151 : 0 : plat->tx_queues_cfg[4].weight = 0x0D;
152 : 0 : plat->tx_queues_cfg[5].weight = 0x0E;
153 : 0 : plat->tx_queues_cfg[6].weight = 0x0F;
154 : 0 : plat->tx_queues_cfg[7].weight = 0x10;
155 : :
156 : 0 : plat->dma_cfg->pbl = 32;
157 : 0 : plat->dma_cfg->pblx8 = true;
158 : 0 : plat->dma_cfg->fixed_burst = 0;
159 : 0 : plat->dma_cfg->mixed_burst = 0;
160 : 0 : plat->dma_cfg->aal = 0;
161 : :
162 : 0 : plat->axi = devm_kzalloc(&pdev->dev, sizeof(*plat->axi),
163 : : GFP_KERNEL);
164 [ # # ]: 0 : if (!plat->axi)
165 : : return -ENOMEM;
166 : :
167 : 0 : plat->axi->axi_lpi_en = 0;
168 : 0 : plat->axi->axi_xit_frm = 0;
169 : 0 : plat->axi->axi_wr_osr_lmt = 1;
170 : 0 : plat->axi->axi_rd_osr_lmt = 1;
171 : 0 : plat->axi->axi_blen[0] = 4;
172 : 0 : plat->axi->axi_blen[1] = 8;
173 : 0 : plat->axi->axi_blen[2] = 16;
174 : :
175 : 0 : plat->ptp_max_adj = plat->clk_ptp_rate;
176 : :
177 : : /* Set system clock */
178 : 0 : plat->stmmac_clk = clk_register_fixed_rate(&pdev->dev,
179 : : "stmmac-clk", NULL, 0,
180 : : plat->clk_ptp_rate);
181 : :
182 [ # # ]: 0 : if (IS_ERR(plat->stmmac_clk)) {
183 : 0 : dev_warn(&pdev->dev, "Fail to register stmmac-clk\n");
184 : 0 : plat->stmmac_clk = NULL;
185 : : }
186 : 0 : clk_prepare_enable(plat->stmmac_clk);
187 : :
188 : : /* Set default value for multicast hash bins */
189 : 0 : plat->multicast_filter_bins = HASH_TABLE_SIZE;
190 : :
191 : : /* Set default value for unicast filter entries */
192 : 0 : plat->unicast_filter_entries = 1;
193 : :
194 : : /* Set the maxmtu to a default of JUMBO_LEN */
195 : 0 : plat->maxmtu = JUMBO_LEN;
196 : :
197 : 0 : return 0;
198 : : }
199 : :
200 : 0 : static int ehl_common_data(struct pci_dev *pdev,
201 : : struct plat_stmmacenet_data *plat)
202 : : {
203 : 0 : int ret;
204 : :
205 : 0 : plat->rx_queues_to_use = 8;
206 : 0 : plat->tx_queues_to_use = 8;
207 : 0 : plat->clk_ptp_rate = 200000000;
208 : 0 : ret = intel_mgbe_common_data(pdev, plat);
209 [ # # # # ]: 0 : if (ret)
210 : 0 : return ret;
211 : :
212 : : return 0;
213 : : }
214 : :
215 : 0 : static int ehl_sgmii_data(struct pci_dev *pdev,
216 : : struct plat_stmmacenet_data *plat)
217 : : {
218 : 0 : plat->bus_id = 1;
219 : 0 : plat->phy_addr = 0;
220 : 0 : plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
221 : :
222 : 0 : return ehl_common_data(pdev, plat);
223 : : }
224 : :
225 : : static struct stmmac_pci_info ehl_sgmii1g_pci_info = {
226 : : .setup = ehl_sgmii_data,
227 : : };
228 : :
229 : 0 : static int ehl_rgmii_data(struct pci_dev *pdev,
230 : : struct plat_stmmacenet_data *plat)
231 : : {
232 : 0 : plat->bus_id = 1;
233 : 0 : plat->phy_addr = 0;
234 : 0 : plat->phy_interface = PHY_INTERFACE_MODE_RGMII;
235 : :
236 : 0 : return ehl_common_data(pdev, plat);
237 : : }
238 : :
239 : : static struct stmmac_pci_info ehl_rgmii1g_pci_info = {
240 : : .setup = ehl_rgmii_data,
241 : : };
242 : :
243 : 0 : static int tgl_common_data(struct pci_dev *pdev,
244 : : struct plat_stmmacenet_data *plat)
245 : : {
246 : 0 : int ret;
247 : :
248 : 0 : plat->rx_queues_to_use = 6;
249 : 0 : plat->tx_queues_to_use = 4;
250 : 0 : plat->clk_ptp_rate = 200000000;
251 : 0 : ret = intel_mgbe_common_data(pdev, plat);
252 [ # # ]: 0 : if (ret)
253 : 0 : return ret;
254 : :
255 : : return 0;
256 : : }
257 : :
258 : 0 : static int tgl_sgmii_data(struct pci_dev *pdev,
259 : : struct plat_stmmacenet_data *plat)
260 : : {
261 : 0 : plat->bus_id = 1;
262 : 0 : plat->phy_addr = 0;
263 : 0 : plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
264 : 0 : return tgl_common_data(pdev, plat);
265 : : }
266 : :
267 : : static struct stmmac_pci_info tgl_sgmii1g_pci_info = {
268 : : .setup = tgl_sgmii_data,
269 : : };
270 : :
271 : : static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = {
272 : : {
273 : : .func = 6,
274 : : .phy_addr = 1,
275 : : },
276 : : };
277 : :
278 : : static const struct stmmac_pci_dmi_data galileo_stmmac_dmi_data = {
279 : : .func = galileo_stmmac_func_data,
280 : : .nfuncs = ARRAY_SIZE(galileo_stmmac_func_data),
281 : : };
282 : :
283 : : static const struct stmmac_pci_func_data iot2040_stmmac_func_data[] = {
284 : : {
285 : : .func = 6,
286 : : .phy_addr = 1,
287 : : },
288 : : {
289 : : .func = 7,
290 : : .phy_addr = 1,
291 : : },
292 : : };
293 : :
294 : : static const struct stmmac_pci_dmi_data iot2040_stmmac_dmi_data = {
295 : : .func = iot2040_stmmac_func_data,
296 : : .nfuncs = ARRAY_SIZE(iot2040_stmmac_func_data),
297 : : };
298 : :
299 : : static const struct dmi_system_id quark_pci_dmi[] = {
300 : : {
301 : : .matches = {
302 : : DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"),
303 : : },
304 : : .driver_data = (void *)&galileo_stmmac_dmi_data,
305 : : },
306 : : {
307 : : .matches = {
308 : : DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"),
309 : : },
310 : : .driver_data = (void *)&galileo_stmmac_dmi_data,
311 : : },
312 : : /*
313 : : * There are 2 types of SIMATIC IOT2000: IOT2020 and IOT2040.
314 : : * The asset tag "6ES7647-0AA00-0YA2" is only for IOT2020 which
315 : : * has only one pci network device while other asset tags are
316 : : * for IOT2040 which has two.
317 : : */
318 : : {
319 : : .matches = {
320 : : DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
321 : : DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
322 : : "6ES7647-0AA00-0YA2"),
323 : : },
324 : : .driver_data = (void *)&galileo_stmmac_dmi_data,
325 : : },
326 : : {
327 : : .matches = {
328 : : DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
329 : : },
330 : : .driver_data = (void *)&iot2040_stmmac_dmi_data,
331 : : },
332 : : {}
333 : : };
334 : :
335 : 21 : static int quark_default_data(struct pci_dev *pdev,
336 : : struct plat_stmmacenet_data *plat)
337 : : {
338 : 21 : int ret;
339 : :
340 : : /* Set common default data first */
341 : 21 : common_default_data(plat);
342 : :
343 : : /*
344 : : * Refuse to load the driver and register net device if MAC controller
345 : : * does not connect to any PHY interface.
346 : : */
347 : 21 : ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi);
348 [ + - ]: 21 : if (ret < 0) {
349 : : /* Return error to the caller on DMI enabled boards. */
350 [ + - ]: 21 : if (dmi_get_system_info(DMI_BOARD_NAME))
351 : : return ret;
352 : :
353 : : /*
354 : : * Galileo boards with old firmware don't support DMI. We always
355 : : * use 1 here as PHY address, so at least the first found MAC
356 : : * controller would be probed.
357 : : */
358 : : ret = 1;
359 : : }
360 : :
361 : 21 : plat->bus_id = pci_dev_id(pdev);
362 : 21 : plat->phy_addr = ret;
363 : 21 : plat->phy_interface = PHY_INTERFACE_MODE_RMII;
364 : :
365 : 21 : plat->dma_cfg->pbl = 16;
366 : 21 : plat->dma_cfg->pblx8 = true;
367 : 21 : plat->dma_cfg->fixed_burst = 1;
368 : : /* AXI (TODO) */
369 : :
370 : 21 : return 0;
371 : : }
372 : :
373 : : static const struct stmmac_pci_info quark_pci_info = {
374 : : .setup = quark_default_data,
375 : : };
376 : :
377 : 0 : static int snps_gmac5_default_data(struct pci_dev *pdev,
378 : : struct plat_stmmacenet_data *plat)
379 : : {
380 : 0 : int i;
381 : :
382 : 0 : plat->clk_csr = 5;
383 : 0 : plat->has_gmac4 = 1;
384 : 0 : plat->force_sf_dma_mode = 1;
385 : 0 : plat->tso_en = 1;
386 : 0 : plat->pmt = 1;
387 : :
388 : : /* Set default value for multicast hash bins */
389 : 0 : plat->multicast_filter_bins = HASH_TABLE_SIZE;
390 : :
391 : : /* Set default value for unicast filter entries */
392 : 0 : plat->unicast_filter_entries = 1;
393 : :
394 : : /* Set the maxmtu to a default of JUMBO_LEN */
395 : 0 : plat->maxmtu = JUMBO_LEN;
396 : :
397 : : /* Set default number of RX and TX queues to use */
398 : 0 : plat->tx_queues_to_use = 4;
399 : 0 : plat->rx_queues_to_use = 4;
400 : :
401 : 0 : plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WRR;
402 [ # # ]: 0 : for (i = 0; i < plat->tx_queues_to_use; i++) {
403 : 0 : plat->tx_queues_cfg[i].use_prio = false;
404 : 0 : plat->tx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
405 : 0 : plat->tx_queues_cfg[i].weight = 25;
406 [ # # ]: 0 : if (i > 0)
407 : 0 : plat->tx_queues_cfg[i].tbs_en = 1;
408 : : }
409 : :
410 : 0 : plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
411 [ # # ]: 0 : for (i = 0; i < plat->rx_queues_to_use; i++) {
412 : 0 : plat->rx_queues_cfg[i].use_prio = false;
413 : 0 : plat->rx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
414 : 0 : plat->rx_queues_cfg[i].pkt_route = 0x0;
415 : 0 : plat->rx_queues_cfg[i].chan = i;
416 : : }
417 : :
418 : 0 : plat->bus_id = 1;
419 : 0 : plat->phy_addr = -1;
420 : 0 : plat->phy_interface = PHY_INTERFACE_MODE_GMII;
421 : :
422 : 0 : plat->dma_cfg->pbl = 32;
423 : 0 : plat->dma_cfg->pblx8 = true;
424 : :
425 : : /* Axi Configuration */
426 : 0 : plat->axi = devm_kzalloc(&pdev->dev, sizeof(*plat->axi), GFP_KERNEL);
427 [ # # ]: 0 : if (!plat->axi)
428 : : return -ENOMEM;
429 : :
430 : 0 : plat->axi->axi_wr_osr_lmt = 31;
431 : 0 : plat->axi->axi_rd_osr_lmt = 31;
432 : :
433 : 0 : plat->axi->axi_fb = false;
434 : 0 : plat->axi->axi_blen[0] = 4;
435 : 0 : plat->axi->axi_blen[1] = 8;
436 : 0 : plat->axi->axi_blen[2] = 16;
437 : 0 : plat->axi->axi_blen[3] = 32;
438 : :
439 : 0 : return 0;
440 : : }
441 : :
442 : : static const struct stmmac_pci_info snps_gmac5_pci_info = {
443 : : .setup = snps_gmac5_default_data,
444 : : };
445 : :
446 : : /**
447 : : * stmmac_pci_probe
448 : : *
449 : : * @pdev: pci device pointer
450 : : * @id: pointer to table of device id/id's.
451 : : *
452 : : * Description: This probing function gets called for all PCI devices which
453 : : * match the ID table and are not "owned" by other driver yet. This function
454 : : * gets passed a "struct pci_dev *" for each device whose entry in the ID table
455 : : * matches the device. The probe functions returns zero when the driver choose
456 : : * to take "ownership" of the device or an error code(-ve no) otherwise.
457 : : */
458 : 21 : static int stmmac_pci_probe(struct pci_dev *pdev,
459 : : const struct pci_device_id *id)
460 : : {
461 : 21 : struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data;
462 : 21 : struct plat_stmmacenet_data *plat;
463 : 21 : struct stmmac_resources res;
464 : 21 : int i;
465 : 21 : int ret;
466 : :
467 : 21 : plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
468 [ + - ]: 21 : if (!plat)
469 : : return -ENOMEM;
470 : :
471 : 21 : plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
472 : : sizeof(*plat->mdio_bus_data),
473 : : GFP_KERNEL);
474 [ + - ]: 21 : if (!plat->mdio_bus_data)
475 : : return -ENOMEM;
476 : :
477 : 21 : plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg),
478 : : GFP_KERNEL);
479 [ + - ]: 21 : if (!plat->dma_cfg)
480 : : return -ENOMEM;
481 : :
482 : : /* Enable pci device */
483 : 21 : ret = pci_enable_device(pdev);
484 [ - + ]: 21 : if (ret) {
485 : 0 : dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n",
486 : : __func__);
487 : 0 : return ret;
488 : : }
489 : :
490 : : /* Get the base address of device */
491 [ + - ]: 21 : for (i = 0; i < PCI_STD_NUM_BARS; i++) {
492 [ - + - - : 21 : if (pci_resource_len(pdev, i) == 0)
- + ]
493 : 0 : continue;
494 [ + - ]: 42 : ret = pcim_iomap_regions(pdev, BIT(i), pci_name(pdev));
495 [ + - ]: 21 : if (ret)
496 : : return ret;
497 : : break;
498 : : }
499 : :
500 : 21 : pci_set_master(pdev);
501 : :
502 : 21 : ret = info->setup(pdev, plat);
503 [ + - ]: 21 : if (ret)
504 : : return ret;
505 : :
506 : 21 : pci_enable_msi(pdev);
507 : :
508 : 21 : memset(&res, 0, sizeof(res));
509 : 21 : res.addr = pcim_iomap_table(pdev)[i];
510 : 21 : res.wol_irq = pdev->irq;
511 : 21 : res.irq = pdev->irq;
512 : :
513 : 21 : return stmmac_dvr_probe(&pdev->dev, plat, &res);
514 : : }
515 : :
516 : : /**
517 : : * stmmac_pci_remove
518 : : *
519 : : * @pdev: platform device pointer
520 : : * Description: this function calls the main to free the net resources
521 : : * and releases the PCI resources.
522 : : */
523 : 0 : static void stmmac_pci_remove(struct pci_dev *pdev)
524 : : {
525 : 0 : struct net_device *ndev = dev_get_drvdata(&pdev->dev);
526 : 0 : struct stmmac_priv *priv = netdev_priv(ndev);
527 : 0 : int i;
528 : :
529 : 0 : stmmac_dvr_remove(&pdev->dev);
530 : :
531 [ # # ]: 0 : if (priv->plat->stmmac_clk)
532 : 0 : clk_unregister_fixed_rate(priv->plat->stmmac_clk);
533 : :
534 [ # # ]: 0 : for (i = 0; i < PCI_STD_NUM_BARS; i++) {
535 [ # # # # : 0 : if (pci_resource_len(pdev, i) == 0)
# # ]
536 : 0 : continue;
537 : 0 : pcim_iounmap_regions(pdev, BIT(i));
538 : 0 : break;
539 : : }
540 : :
541 : 0 : pci_disable_device(pdev);
542 : 0 : }
543 : :
544 : 0 : static int __maybe_unused stmmac_pci_suspend(struct device *dev)
545 : : {
546 : 0 : struct pci_dev *pdev = to_pci_dev(dev);
547 : 0 : int ret;
548 : :
549 : 0 : ret = stmmac_suspend(dev);
550 [ # # ]: 0 : if (ret)
551 : : return ret;
552 : :
553 : 0 : ret = pci_save_state(pdev);
554 [ # # ]: 0 : if (ret)
555 : : return ret;
556 : :
557 : 0 : pci_disable_device(pdev);
558 : 0 : pci_wake_from_d3(pdev, true);
559 : 0 : return 0;
560 : : }
561 : :
562 : 0 : static int __maybe_unused stmmac_pci_resume(struct device *dev)
563 : : {
564 : 0 : struct pci_dev *pdev = to_pci_dev(dev);
565 : 0 : int ret;
566 : :
567 : 0 : pci_restore_state(pdev);
568 : 0 : pci_set_power_state(pdev, PCI_D0);
569 : :
570 : 0 : ret = pci_enable_device(pdev);
571 [ # # ]: 0 : if (ret)
572 : : return ret;
573 : :
574 : 0 : pci_set_master(pdev);
575 : :
576 : 0 : return stmmac_resume(dev);
577 : : }
578 : :
579 : : static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume);
580 : :
581 : : /* synthetic ID, no official vendor */
582 : : #define PCI_VENDOR_ID_STMMAC 0x700
583 : :
584 : : #define STMMAC_QUARK_ID 0x0937
585 : : #define STMMAC_DEVICE_ID 0x1108
586 : : #define STMMAC_EHL_RGMII1G_ID 0x4b30
587 : : #define STMMAC_EHL_SGMII1G_ID 0x4b31
588 : : #define STMMAC_TGL_SGMII1G_ID 0xa0ac
589 : : #define STMMAC_GMAC5_ID 0x7102
590 : :
591 : : #define STMMAC_DEVICE(vendor_id, dev_id, info) { \
592 : : PCI_VDEVICE(vendor_id, dev_id), \
593 : : .driver_data = (kernel_ulong_t)&info \
594 : : }
595 : :
596 : : static const struct pci_device_id stmmac_id_table[] = {
597 : : STMMAC_DEVICE(STMMAC, STMMAC_DEVICE_ID, stmmac_pci_info),
598 : : STMMAC_DEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_MAC, stmmac_pci_info),
599 : : STMMAC_DEVICE(INTEL, STMMAC_QUARK_ID, quark_pci_info),
600 : : STMMAC_DEVICE(INTEL, STMMAC_EHL_RGMII1G_ID, ehl_rgmii1g_pci_info),
601 : : STMMAC_DEVICE(INTEL, STMMAC_EHL_SGMII1G_ID, ehl_sgmii1g_pci_info),
602 : : STMMAC_DEVICE(INTEL, STMMAC_TGL_SGMII1G_ID, tgl_sgmii1g_pci_info),
603 : : STMMAC_DEVICE(SYNOPSYS, STMMAC_GMAC5_ID, snps_gmac5_pci_info),
604 : : {}
605 : : };
606 : :
607 : : MODULE_DEVICE_TABLE(pci, stmmac_id_table);
608 : :
609 : : static struct pci_driver stmmac_pci_driver = {
610 : : .name = STMMAC_RESOURCE_NAME,
611 : : .id_table = stmmac_id_table,
612 : : .probe = stmmac_pci_probe,
613 : : .remove = stmmac_pci_remove,
614 : : .driver = {
615 : : .pm = &stmmac_pm_ops,
616 : : },
617 : : };
618 : :
619 : 21 : module_pci_driver(stmmac_pci_driver);
620 : :
621 : : MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver");
622 : : MODULE_AUTHOR("Rayagond Kokatanur <rayagond.kokatanur@vayavyalabs.com>");
623 : : MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
624 : : MODULE_LICENSE("GPL");
|