1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (c) 2020, Intel Corporation |
3 | */ |
4 | |
5 | #include <linux/clk-provider.h> |
6 | #include <linux/pci.h> |
7 | #include <linux/dmi.h> |
8 | #include "dwmac-intel.h" |
9 | #include "dwmac4.h" |
10 | #include "stmmac.h" |
11 | #include "stmmac_ptp.h" |
12 | |
13 | struct intel_priv_data { |
14 | int mdio_adhoc_addr; /* mdio address for serdes & etc */ |
15 | unsigned long crossts_adj; |
16 | bool is_pse; |
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(list: 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 | static int serdes_status_poll(struct stmmac_priv *priv, int phyaddr, |
62 | int phyreg, u32 mask, u32 val) |
63 | { |
64 | unsigned int retries = 10; |
65 | int val_rd; |
66 | |
67 | do { |
68 | val_rd = mdiobus_read(bus: priv->mii, addr: phyaddr, regnum: phyreg); |
69 | if ((val_rd & mask) == (val & mask)) |
70 | return 0; |
71 | udelay(POLL_DELAY_US); |
72 | } while (--retries); |
73 | |
74 | return -ETIMEDOUT; |
75 | } |
76 | |
77 | static int intel_serdes_powerup(struct net_device *ndev, void *priv_data) |
78 | { |
79 | struct intel_priv_data *intel_priv = priv_data; |
80 | struct stmmac_priv *priv = netdev_priv(dev: ndev); |
81 | int serdes_phy_addr = 0; |
82 | u32 data = 0; |
83 | |
84 | if (!intel_priv->mdio_adhoc_addr) |
85 | return 0; |
86 | |
87 | serdes_phy_addr = intel_priv->mdio_adhoc_addr; |
88 | |
89 | /* Set the serdes rate and the PCLK rate */ |
90 | data = mdiobus_read(bus: priv->mii, addr: serdes_phy_addr, |
91 | SERDES_GCR0); |
92 | |
93 | data &= ~SERDES_RATE_MASK; |
94 | data &= ~SERDES_PCLK_MASK; |
95 | |
96 | if (priv->plat->max_speed == 2500) |
97 | data |= SERDES_RATE_PCIE_GEN2 << SERDES_RATE_PCIE_SHIFT | |
98 | SERDES_PCLK_37p5MHZ << SERDES_PCLK_SHIFT; |
99 | else |
100 | data |= SERDES_RATE_PCIE_GEN1 << SERDES_RATE_PCIE_SHIFT | |
101 | SERDES_PCLK_70MHZ << SERDES_PCLK_SHIFT; |
102 | |
103 | mdiobus_write(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0, val: data); |
104 | |
105 | /* assert clk_req */ |
106 | data = mdiobus_read(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0); |
107 | data |= SERDES_PLL_CLK; |
108 | mdiobus_write(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0, val: data); |
109 | |
110 | /* check for clk_ack assertion */ |
111 | data = serdes_status_poll(priv, phyaddr: serdes_phy_addr, |
112 | SERDES_GSR0, |
113 | SERDES_PLL_CLK, |
114 | SERDES_PLL_CLK); |
115 | |
116 | if (data) { |
117 | dev_err(priv->device, "Serdes PLL clk request timeout\n" ); |
118 | return data; |
119 | } |
120 | |
121 | /* assert lane reset */ |
122 | data = mdiobus_read(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0); |
123 | data |= SERDES_RST; |
124 | mdiobus_write(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0, val: data); |
125 | |
126 | /* check for assert lane reset reflection */ |
127 | data = serdes_status_poll(priv, phyaddr: serdes_phy_addr, |
128 | SERDES_GSR0, |
129 | SERDES_RST, |
130 | SERDES_RST); |
131 | |
132 | if (data) { |
133 | dev_err(priv->device, "Serdes assert lane reset timeout\n" ); |
134 | return data; |
135 | } |
136 | |
137 | /* move power state to P0 */ |
138 | data = mdiobus_read(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0); |
139 | |
140 | data &= ~SERDES_PWR_ST_MASK; |
141 | data |= SERDES_PWR_ST_P0 << SERDES_PWR_ST_SHIFT; |
142 | |
143 | mdiobus_write(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0, val: data); |
144 | |
145 | /* Check for P0 state */ |
146 | data = serdes_status_poll(priv, phyaddr: serdes_phy_addr, |
147 | SERDES_GSR0, |
148 | SERDES_PWR_ST_MASK, |
149 | SERDES_PWR_ST_P0 << SERDES_PWR_ST_SHIFT); |
150 | |
151 | if (data) { |
152 | dev_err(priv->device, "Serdes power state P0 timeout.\n" ); |
153 | return data; |
154 | } |
155 | |
156 | /* PSE only - ungate SGMII PHY Rx Clock */ |
157 | if (intel_priv->is_pse) |
158 | mdiobus_modify(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0, |
159 | mask: 0, SERDES_PHY_RX_CLK); |
160 | |
161 | return 0; |
162 | } |
163 | |
164 | static void intel_serdes_powerdown(struct net_device *ndev, void *intel_data) |
165 | { |
166 | struct intel_priv_data *intel_priv = intel_data; |
167 | struct stmmac_priv *priv = netdev_priv(dev: ndev); |
168 | int serdes_phy_addr = 0; |
169 | u32 data = 0; |
170 | |
171 | if (!intel_priv->mdio_adhoc_addr) |
172 | return; |
173 | |
174 | serdes_phy_addr = intel_priv->mdio_adhoc_addr; |
175 | |
176 | /* PSE only - gate SGMII PHY Rx Clock */ |
177 | if (intel_priv->is_pse) |
178 | mdiobus_modify(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0, |
179 | SERDES_PHY_RX_CLK, set: 0); |
180 | |
181 | /* move power state to P3 */ |
182 | data = mdiobus_read(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0); |
183 | |
184 | data &= ~SERDES_PWR_ST_MASK; |
185 | data |= SERDES_PWR_ST_P3 << SERDES_PWR_ST_SHIFT; |
186 | |
187 | mdiobus_write(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0, val: data); |
188 | |
189 | /* Check for P3 state */ |
190 | data = serdes_status_poll(priv, phyaddr: serdes_phy_addr, |
191 | SERDES_GSR0, |
192 | SERDES_PWR_ST_MASK, |
193 | SERDES_PWR_ST_P3 << SERDES_PWR_ST_SHIFT); |
194 | |
195 | if (data) { |
196 | dev_err(priv->device, "Serdes power state P3 timeout\n" ); |
197 | return; |
198 | } |
199 | |
200 | /* de-assert clk_req */ |
201 | data = mdiobus_read(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0); |
202 | data &= ~SERDES_PLL_CLK; |
203 | mdiobus_write(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0, val: data); |
204 | |
205 | /* check for clk_ack de-assert */ |
206 | data = serdes_status_poll(priv, phyaddr: serdes_phy_addr, |
207 | SERDES_GSR0, |
208 | SERDES_PLL_CLK, |
209 | val: (u32)~SERDES_PLL_CLK); |
210 | |
211 | if (data) { |
212 | dev_err(priv->device, "Serdes PLL clk de-assert timeout\n" ); |
213 | return; |
214 | } |
215 | |
216 | /* de-assert lane reset */ |
217 | data = mdiobus_read(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0); |
218 | data &= ~SERDES_RST; |
219 | mdiobus_write(bus: priv->mii, addr: serdes_phy_addr, SERDES_GCR0, val: data); |
220 | |
221 | /* check for de-assert lane reset reflection */ |
222 | data = serdes_status_poll(priv, phyaddr: serdes_phy_addr, |
223 | SERDES_GSR0, |
224 | SERDES_RST, |
225 | val: (u32)~SERDES_RST); |
226 | |
227 | if (data) { |
228 | dev_err(priv->device, "Serdes de-assert lane reset timeout\n" ); |
229 | return; |
230 | } |
231 | } |
232 | |
233 | static void intel_speed_mode_2500(struct net_device *ndev, void *intel_data) |
234 | { |
235 | struct intel_priv_data *intel_priv = intel_data; |
236 | struct stmmac_priv *priv = netdev_priv(dev: ndev); |
237 | int serdes_phy_addr = 0; |
238 | u32 data = 0; |
239 | |
240 | serdes_phy_addr = intel_priv->mdio_adhoc_addr; |
241 | |
242 | /* Determine the link speed mode: 2.5Gbps/1Gbps */ |
243 | data = mdiobus_read(bus: priv->mii, addr: serdes_phy_addr, |
244 | SERDES_GCR); |
245 | |
246 | if (((data & SERDES_LINK_MODE_MASK) >> SERDES_LINK_MODE_SHIFT) == |
247 | SERDES_LINK_MODE_2G5) { |
248 | dev_info(priv->device, "Link Speed Mode: 2.5Gbps\n" ); |
249 | priv->plat->max_speed = 2500; |
250 | priv->plat->phy_interface = PHY_INTERFACE_MODE_2500BASEX; |
251 | priv->plat->mdio_bus_data->xpcs_an_inband = false; |
252 | } else { |
253 | priv->plat->max_speed = 1000; |
254 | } |
255 | } |
256 | |
257 | /* Program PTP Clock Frequency for different variant of |
258 | * Intel mGBE that has slightly different GPO mapping |
259 | */ |
260 | static void intel_mgbe_ptp_clk_freq_config(struct stmmac_priv *priv) |
261 | { |
262 | struct intel_priv_data *intel_priv; |
263 | u32 gpio_value; |
264 | |
265 | intel_priv = (struct intel_priv_data *)priv->plat->bsp_priv; |
266 | |
267 | gpio_value = readl(addr: priv->ioaddr + GMAC_GPIO_STATUS); |
268 | |
269 | if (intel_priv->is_pse) { |
270 | /* For PSE GbE, use 200MHz */ |
271 | gpio_value &= ~PSE_PTP_CLK_FREQ_MASK; |
272 | gpio_value |= PSE_PTP_CLK_FREQ_200MHZ; |
273 | } else { |
274 | /* For PCH GbE, use 200MHz */ |
275 | gpio_value &= ~PCH_PTP_CLK_FREQ_MASK; |
276 | gpio_value |= PCH_PTP_CLK_FREQ_200MHZ; |
277 | } |
278 | |
279 | writel(val: gpio_value, addr: priv->ioaddr + GMAC_GPIO_STATUS); |
280 | } |
281 | |
282 | static void get_arttime(struct mii_bus *mii, int intel_adhoc_addr, |
283 | u64 *art_time) |
284 | { |
285 | u64 ns; |
286 | |
287 | ns = mdiobus_read(bus: mii, addr: intel_adhoc_addr, PMC_ART_VALUE3); |
288 | ns <<= GMAC4_ART_TIME_SHIFT; |
289 | ns |= mdiobus_read(bus: mii, addr: intel_adhoc_addr, PMC_ART_VALUE2); |
290 | ns <<= GMAC4_ART_TIME_SHIFT; |
291 | ns |= mdiobus_read(bus: mii, addr: intel_adhoc_addr, PMC_ART_VALUE1); |
292 | ns <<= GMAC4_ART_TIME_SHIFT; |
293 | ns |= mdiobus_read(bus: mii, addr: intel_adhoc_addr, PMC_ART_VALUE0); |
294 | |
295 | *art_time = ns; |
296 | } |
297 | |
298 | static int stmmac_cross_ts_isr(struct stmmac_priv *priv) |
299 | { |
300 | return (readl(addr: priv->ioaddr + GMAC_INT_STATUS) & GMAC_INT_TSIE); |
301 | } |
302 | |
303 | static int intel_crosststamp(ktime_t *device, |
304 | struct system_counterval_t *system, |
305 | void *ctx) |
306 | { |
307 | struct intel_priv_data *intel_priv; |
308 | |
309 | struct stmmac_priv *priv = (struct stmmac_priv *)ctx; |
310 | void __iomem *ptpaddr = priv->ptpaddr; |
311 | void __iomem *ioaddr = priv->hw->pcsr; |
312 | unsigned long flags; |
313 | u64 art_time = 0; |
314 | u64 ptp_time = 0; |
315 | u32 num_snapshot; |
316 | u32 gpio_value; |
317 | u32 acr_value; |
318 | int i; |
319 | |
320 | if (!boot_cpu_has(X86_FEATURE_ART)) |
321 | return -EOPNOTSUPP; |
322 | |
323 | intel_priv = priv->plat->bsp_priv; |
324 | |
325 | /* Both internal crosstimestamping and external triggered event |
326 | * timestamping cannot be run concurrently. |
327 | */ |
328 | if (priv->plat->flags & STMMAC_FLAG_EXT_SNAPSHOT_EN) |
329 | return -EBUSY; |
330 | |
331 | priv->plat->flags |= STMMAC_FLAG_INT_SNAPSHOT_EN; |
332 | |
333 | mutex_lock(&priv->aux_ts_lock); |
334 | /* Enable Internal snapshot trigger */ |
335 | acr_value = readl(addr: ptpaddr + PTP_ACR); |
336 | acr_value &= ~PTP_ACR_MASK; |
337 | switch (priv->plat->int_snapshot_num) { |
338 | case AUX_SNAPSHOT0: |
339 | acr_value |= PTP_ACR_ATSEN0; |
340 | break; |
341 | case AUX_SNAPSHOT1: |
342 | acr_value |= PTP_ACR_ATSEN1; |
343 | break; |
344 | case AUX_SNAPSHOT2: |
345 | acr_value |= PTP_ACR_ATSEN2; |
346 | break; |
347 | case AUX_SNAPSHOT3: |
348 | acr_value |= PTP_ACR_ATSEN3; |
349 | break; |
350 | default: |
351 | mutex_unlock(lock: &priv->aux_ts_lock); |
352 | priv->plat->flags &= ~STMMAC_FLAG_INT_SNAPSHOT_EN; |
353 | return -EINVAL; |
354 | } |
355 | writel(val: acr_value, addr: ptpaddr + PTP_ACR); |
356 | |
357 | /* Clear FIFO */ |
358 | acr_value = readl(addr: ptpaddr + PTP_ACR); |
359 | acr_value |= PTP_ACR_ATSFC; |
360 | writel(val: acr_value, addr: ptpaddr + PTP_ACR); |
361 | /* Release the mutex */ |
362 | mutex_unlock(lock: &priv->aux_ts_lock); |
363 | |
364 | /* Trigger Internal snapshot signal |
365 | * Create a rising edge by just toggle the GPO1 to low |
366 | * and back to high. |
367 | */ |
368 | gpio_value = readl(addr: ioaddr + GMAC_GPIO_STATUS); |
369 | gpio_value &= ~GMAC_GPO1; |
370 | writel(val: gpio_value, addr: ioaddr + GMAC_GPIO_STATUS); |
371 | gpio_value |= GMAC_GPO1; |
372 | writel(val: gpio_value, addr: ioaddr + GMAC_GPIO_STATUS); |
373 | |
374 | /* Time sync done Indication - Interrupt method */ |
375 | if (!wait_event_interruptible_timeout(priv->tstamp_busy_wait, |
376 | stmmac_cross_ts_isr(priv), |
377 | HZ / 100)) { |
378 | priv->plat->flags &= ~STMMAC_FLAG_INT_SNAPSHOT_EN; |
379 | return -ETIMEDOUT; |
380 | } |
381 | |
382 | num_snapshot = (readl(addr: ioaddr + GMAC_TIMESTAMP_STATUS) & |
383 | GMAC_TIMESTAMP_ATSNS_MASK) >> |
384 | GMAC_TIMESTAMP_ATSNS_SHIFT; |
385 | |
386 | /* Repeat until the timestamps are from the FIFO last segment */ |
387 | for (i = 0; i < num_snapshot; i++) { |
388 | read_lock_irqsave(&priv->ptp_lock, flags); |
389 | stmmac_get_ptptime(priv, ptpaddr, &ptp_time); |
390 | *device = ns_to_ktime(ns: ptp_time); |
391 | read_unlock_irqrestore(&priv->ptp_lock, flags); |
392 | get_arttime(mii: priv->mii, intel_adhoc_addr: intel_priv->mdio_adhoc_addr, art_time: &art_time); |
393 | *system = convert_art_to_tsc(art: art_time); |
394 | } |
395 | |
396 | system->cycles *= intel_priv->crossts_adj; |
397 | priv->plat->flags &= ~STMMAC_FLAG_INT_SNAPSHOT_EN; |
398 | |
399 | return 0; |
400 | } |
401 | |
402 | static void intel_mgbe_pse_crossts_adj(struct intel_priv_data *intel_priv, |
403 | int base) |
404 | { |
405 | if (boot_cpu_has(X86_FEATURE_ART)) { |
406 | unsigned int art_freq; |
407 | |
408 | /* On systems that support ART, ART frequency can be obtained |
409 | * from ECX register of CPUID leaf (0x15). |
410 | */ |
411 | art_freq = cpuid_ecx(ART_CPUID_LEAF); |
412 | do_div(art_freq, base); |
413 | intel_priv->crossts_adj = art_freq; |
414 | } |
415 | } |
416 | |
417 | static void common_default_data(struct plat_stmmacenet_data *plat) |
418 | { |
419 | plat->clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ |
420 | plat->has_gmac = 1; |
421 | plat->force_sf_dma_mode = 1; |
422 | |
423 | plat->mdio_bus_data->needs_reset = true; |
424 | |
425 | /* Set default value for multicast hash bins */ |
426 | plat->multicast_filter_bins = HASH_TABLE_SIZE; |
427 | |
428 | /* Set default value for unicast filter entries */ |
429 | plat->unicast_filter_entries = 1; |
430 | |
431 | /* Set the maxmtu to a default of JUMBO_LEN */ |
432 | plat->maxmtu = JUMBO_LEN; |
433 | |
434 | /* Set default number of RX and TX queues to use */ |
435 | plat->tx_queues_to_use = 1; |
436 | plat->rx_queues_to_use = 1; |
437 | |
438 | /* Disable Priority config by default */ |
439 | plat->tx_queues_cfg[0].use_prio = false; |
440 | plat->rx_queues_cfg[0].use_prio = false; |
441 | |
442 | /* Disable RX queues routing by default */ |
443 | plat->rx_queues_cfg[0].pkt_route = 0x0; |
444 | } |
445 | |
446 | static int intel_mgbe_common_data(struct pci_dev *pdev, |
447 | struct plat_stmmacenet_data *plat) |
448 | { |
449 | struct fwnode_handle *fwnode; |
450 | char clk_name[20]; |
451 | int ret; |
452 | int i; |
453 | |
454 | plat->pdev = pdev; |
455 | plat->phy_addr = -1; |
456 | plat->clk_csr = 5; |
457 | plat->has_gmac = 0; |
458 | plat->has_gmac4 = 1; |
459 | plat->force_sf_dma_mode = 0; |
460 | plat->flags |= (STMMAC_FLAG_TSO_EN | STMMAC_FLAG_SPH_DISABLE); |
461 | |
462 | /* Multiplying factor to the clk_eee_i clock time |
463 | * period to make it closer to 100 ns. This value |
464 | * should be programmed such that the clk_eee_time_period * |
465 | * (MULT_FACT_100NS + 1) should be within 80 ns to 120 ns |
466 | * clk_eee frequency is 19.2Mhz |
467 | * clk_eee_time_period is 52ns |
468 | * 52ns * (1 + 1) = 104ns |
469 | * MULT_FACT_100NS = 1 |
470 | */ |
471 | plat->mult_fact_100ns = 1; |
472 | |
473 | plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP; |
474 | |
475 | for (i = 0; i < plat->rx_queues_to_use; i++) { |
476 | plat->rx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB; |
477 | plat->rx_queues_cfg[i].chan = i; |
478 | |
479 | /* Disable Priority config by default */ |
480 | plat->rx_queues_cfg[i].use_prio = false; |
481 | |
482 | /* Disable RX queues routing by default */ |
483 | plat->rx_queues_cfg[i].pkt_route = 0x0; |
484 | } |
485 | |
486 | for (i = 0; i < plat->tx_queues_to_use; i++) { |
487 | plat->tx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB; |
488 | |
489 | /* Disable Priority config by default */ |
490 | plat->tx_queues_cfg[i].use_prio = false; |
491 | /* Default TX Q0 to use TSO and rest TXQ for TBS */ |
492 | if (i > 0) |
493 | plat->tx_queues_cfg[i].tbs_en = 1; |
494 | } |
495 | |
496 | /* FIFO size is 4096 bytes for 1 tx/rx queue */ |
497 | plat->tx_fifo_size = plat->tx_queues_to_use * 4096; |
498 | plat->rx_fifo_size = plat->rx_queues_to_use * 4096; |
499 | |
500 | plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WRR; |
501 | plat->tx_queues_cfg[0].weight = 0x09; |
502 | plat->tx_queues_cfg[1].weight = 0x0A; |
503 | plat->tx_queues_cfg[2].weight = 0x0B; |
504 | plat->tx_queues_cfg[3].weight = 0x0C; |
505 | plat->tx_queues_cfg[4].weight = 0x0D; |
506 | plat->tx_queues_cfg[5].weight = 0x0E; |
507 | plat->tx_queues_cfg[6].weight = 0x0F; |
508 | plat->tx_queues_cfg[7].weight = 0x10; |
509 | |
510 | plat->dma_cfg->pbl = 32; |
511 | plat->dma_cfg->pblx8 = true; |
512 | plat->dma_cfg->fixed_burst = 0; |
513 | plat->dma_cfg->mixed_burst = 0; |
514 | plat->dma_cfg->aal = 0; |
515 | plat->dma_cfg->dche = true; |
516 | |
517 | plat->axi = devm_kzalloc(dev: &pdev->dev, size: sizeof(*plat->axi), |
518 | GFP_KERNEL); |
519 | if (!plat->axi) |
520 | return -ENOMEM; |
521 | |
522 | plat->axi->axi_lpi_en = 0; |
523 | plat->axi->axi_xit_frm = 0; |
524 | plat->axi->axi_wr_osr_lmt = 1; |
525 | plat->axi->axi_rd_osr_lmt = 1; |
526 | plat->axi->axi_blen[0] = 4; |
527 | plat->axi->axi_blen[1] = 8; |
528 | plat->axi->axi_blen[2] = 16; |
529 | |
530 | plat->ptp_max_adj = plat->clk_ptp_rate; |
531 | plat->eee_usecs_rate = plat->clk_ptp_rate; |
532 | |
533 | /* Set system clock */ |
534 | sprintf(buf: clk_name, fmt: "%s-%s" , "stmmac" , pci_name(pdev)); |
535 | |
536 | plat->stmmac_clk = clk_register_fixed_rate(dev: &pdev->dev, |
537 | name: clk_name, NULL, flags: 0, |
538 | fixed_rate: plat->clk_ptp_rate); |
539 | |
540 | if (IS_ERR(ptr: plat->stmmac_clk)) { |
541 | dev_warn(&pdev->dev, "Fail to register stmmac-clk\n" ); |
542 | plat->stmmac_clk = NULL; |
543 | } |
544 | |
545 | ret = clk_prepare_enable(clk: plat->stmmac_clk); |
546 | if (ret) { |
547 | clk_unregister_fixed_rate(clk: plat->stmmac_clk); |
548 | return ret; |
549 | } |
550 | |
551 | plat->ptp_clk_freq_config = intel_mgbe_ptp_clk_freq_config; |
552 | |
553 | /* Set default value for multicast hash bins */ |
554 | plat->multicast_filter_bins = HASH_TABLE_SIZE; |
555 | |
556 | /* Set default value for unicast filter entries */ |
557 | plat->unicast_filter_entries = 1; |
558 | |
559 | /* Set the maxmtu to a default of JUMBO_LEN */ |
560 | plat->maxmtu = JUMBO_LEN; |
561 | |
562 | plat->flags |= STMMAC_FLAG_VLAN_FAIL_Q_EN; |
563 | |
564 | /* Use the last Rx queue */ |
565 | plat->vlan_fail_q = plat->rx_queues_to_use - 1; |
566 | |
567 | /* For fixed-link setup, we allow phy-mode setting */ |
568 | fwnode = dev_fwnode(&pdev->dev); |
569 | if (fwnode) { |
570 | int phy_mode; |
571 | |
572 | /* "phy-mode" setting is optional. If it is set, |
573 | * we allow either sgmii or 1000base-x for now. |
574 | */ |
575 | phy_mode = fwnode_get_phy_mode(fwnode); |
576 | if (phy_mode >= 0) { |
577 | if (phy_mode == PHY_INTERFACE_MODE_SGMII || |
578 | phy_mode == PHY_INTERFACE_MODE_1000BASEX) |
579 | plat->phy_interface = phy_mode; |
580 | else |
581 | dev_warn(&pdev->dev, "Invalid phy-mode\n" ); |
582 | } |
583 | } |
584 | |
585 | /* Intel mgbe SGMII interface uses pcs-xcps */ |
586 | if (plat->phy_interface == PHY_INTERFACE_MODE_SGMII || |
587 | plat->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { |
588 | plat->mdio_bus_data->has_xpcs = true; |
589 | plat->mdio_bus_data->xpcs_an_inband = true; |
590 | } |
591 | |
592 | /* For fixed-link setup, we clear xpcs_an_inband */ |
593 | if (fwnode) { |
594 | struct fwnode_handle *fixed_node; |
595 | |
596 | fixed_node = fwnode_get_named_child_node(fwnode, childname: "fixed-link" ); |
597 | if (fixed_node) |
598 | plat->mdio_bus_data->xpcs_an_inband = false; |
599 | |
600 | fwnode_handle_put(fwnode: fixed_node); |
601 | } |
602 | |
603 | /* Ensure mdio bus scan skips intel serdes and pcs-xpcs */ |
604 | plat->mdio_bus_data->phy_mask = 1 << INTEL_MGBE_ADHOC_ADDR; |
605 | plat->mdio_bus_data->phy_mask |= 1 << INTEL_MGBE_XPCS_ADDR; |
606 | |
607 | plat->int_snapshot_num = AUX_SNAPSHOT1; |
608 | |
609 | plat->crosststamp = intel_crosststamp; |
610 | plat->flags &= ~STMMAC_FLAG_INT_SNAPSHOT_EN; |
611 | |
612 | /* Setup MSI vector offset specific to Intel mGbE controller */ |
613 | plat->msi_mac_vec = 29; |
614 | plat->msi_lpi_vec = 28; |
615 | plat->msi_sfty_ce_vec = 27; |
616 | plat->msi_sfty_ue_vec = 26; |
617 | plat->msi_rx_base_vec = 0; |
618 | plat->msi_tx_base_vec = 1; |
619 | |
620 | return 0; |
621 | } |
622 | |
623 | static int ehl_common_data(struct pci_dev *pdev, |
624 | struct plat_stmmacenet_data *plat) |
625 | { |
626 | plat->rx_queues_to_use = 8; |
627 | plat->tx_queues_to_use = 8; |
628 | plat->flags |= STMMAC_FLAG_USE_PHY_WOL; |
629 | plat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY; |
630 | |
631 | plat->safety_feat_cfg->tsoee = 1; |
632 | plat->safety_feat_cfg->mrxpee = 1; |
633 | plat->safety_feat_cfg->mestee = 1; |
634 | plat->safety_feat_cfg->mrxee = 1; |
635 | plat->safety_feat_cfg->mtxee = 1; |
636 | plat->safety_feat_cfg->epsi = 0; |
637 | plat->safety_feat_cfg->edpp = 0; |
638 | plat->safety_feat_cfg->prtyen = 0; |
639 | plat->safety_feat_cfg->tmouten = 0; |
640 | |
641 | return intel_mgbe_common_data(pdev, plat); |
642 | } |
643 | |
644 | static int ehl_sgmii_data(struct pci_dev *pdev, |
645 | struct plat_stmmacenet_data *plat) |
646 | { |
647 | plat->bus_id = 1; |
648 | plat->phy_interface = PHY_INTERFACE_MODE_SGMII; |
649 | plat->speed_mode_2500 = intel_speed_mode_2500; |
650 | plat->serdes_powerup = intel_serdes_powerup; |
651 | plat->serdes_powerdown = intel_serdes_powerdown; |
652 | |
653 | plat->clk_ptp_rate = 204800000; |
654 | |
655 | return ehl_common_data(pdev, plat); |
656 | } |
657 | |
658 | static struct stmmac_pci_info ehl_sgmii1g_info = { |
659 | .setup = ehl_sgmii_data, |
660 | }; |
661 | |
662 | static int ehl_rgmii_data(struct pci_dev *pdev, |
663 | struct plat_stmmacenet_data *plat) |
664 | { |
665 | plat->bus_id = 1; |
666 | plat->phy_interface = PHY_INTERFACE_MODE_RGMII; |
667 | |
668 | plat->clk_ptp_rate = 204800000; |
669 | |
670 | return ehl_common_data(pdev, plat); |
671 | } |
672 | |
673 | static struct stmmac_pci_info ehl_rgmii1g_info = { |
674 | .setup = ehl_rgmii_data, |
675 | }; |
676 | |
677 | static int ehl_pse0_common_data(struct pci_dev *pdev, |
678 | struct plat_stmmacenet_data *plat) |
679 | { |
680 | struct intel_priv_data *intel_priv = plat->bsp_priv; |
681 | |
682 | intel_priv->is_pse = true; |
683 | plat->bus_id = 2; |
684 | plat->host_dma_width = 32; |
685 | |
686 | plat->clk_ptp_rate = 200000000; |
687 | |
688 | intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ); |
689 | |
690 | return ehl_common_data(pdev, plat); |
691 | } |
692 | |
693 | static int ehl_pse0_rgmii1g_data(struct pci_dev *pdev, |
694 | struct plat_stmmacenet_data *plat) |
695 | { |
696 | plat->phy_interface = PHY_INTERFACE_MODE_RGMII_ID; |
697 | return ehl_pse0_common_data(pdev, plat); |
698 | } |
699 | |
700 | static struct stmmac_pci_info ehl_pse0_rgmii1g_info = { |
701 | .setup = ehl_pse0_rgmii1g_data, |
702 | }; |
703 | |
704 | static int ehl_pse0_sgmii1g_data(struct pci_dev *pdev, |
705 | struct plat_stmmacenet_data *plat) |
706 | { |
707 | plat->phy_interface = PHY_INTERFACE_MODE_SGMII; |
708 | plat->speed_mode_2500 = intel_speed_mode_2500; |
709 | plat->serdes_powerup = intel_serdes_powerup; |
710 | plat->serdes_powerdown = intel_serdes_powerdown; |
711 | return ehl_pse0_common_data(pdev, plat); |
712 | } |
713 | |
714 | static struct stmmac_pci_info ehl_pse0_sgmii1g_info = { |
715 | .setup = ehl_pse0_sgmii1g_data, |
716 | }; |
717 | |
718 | static int ehl_pse1_common_data(struct pci_dev *pdev, |
719 | struct plat_stmmacenet_data *plat) |
720 | { |
721 | struct intel_priv_data *intel_priv = plat->bsp_priv; |
722 | |
723 | intel_priv->is_pse = true; |
724 | plat->bus_id = 3; |
725 | plat->host_dma_width = 32; |
726 | |
727 | plat->clk_ptp_rate = 200000000; |
728 | |
729 | intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ); |
730 | |
731 | return ehl_common_data(pdev, plat); |
732 | } |
733 | |
734 | static int ehl_pse1_rgmii1g_data(struct pci_dev *pdev, |
735 | struct plat_stmmacenet_data *plat) |
736 | { |
737 | plat->phy_interface = PHY_INTERFACE_MODE_RGMII_ID; |
738 | return ehl_pse1_common_data(pdev, plat); |
739 | } |
740 | |
741 | static struct stmmac_pci_info ehl_pse1_rgmii1g_info = { |
742 | .setup = ehl_pse1_rgmii1g_data, |
743 | }; |
744 | |
745 | static int ehl_pse1_sgmii1g_data(struct pci_dev *pdev, |
746 | struct plat_stmmacenet_data *plat) |
747 | { |
748 | plat->phy_interface = PHY_INTERFACE_MODE_SGMII; |
749 | plat->speed_mode_2500 = intel_speed_mode_2500; |
750 | plat->serdes_powerup = intel_serdes_powerup; |
751 | plat->serdes_powerdown = intel_serdes_powerdown; |
752 | return ehl_pse1_common_data(pdev, plat); |
753 | } |
754 | |
755 | static struct stmmac_pci_info ehl_pse1_sgmii1g_info = { |
756 | .setup = ehl_pse1_sgmii1g_data, |
757 | }; |
758 | |
759 | static int tgl_common_data(struct pci_dev *pdev, |
760 | struct plat_stmmacenet_data *plat) |
761 | { |
762 | plat->rx_queues_to_use = 6; |
763 | plat->tx_queues_to_use = 4; |
764 | plat->clk_ptp_rate = 204800000; |
765 | plat->speed_mode_2500 = intel_speed_mode_2500; |
766 | |
767 | plat->safety_feat_cfg->tsoee = 1; |
768 | plat->safety_feat_cfg->mrxpee = 0; |
769 | plat->safety_feat_cfg->mestee = 1; |
770 | plat->safety_feat_cfg->mrxee = 1; |
771 | plat->safety_feat_cfg->mtxee = 1; |
772 | plat->safety_feat_cfg->epsi = 0; |
773 | plat->safety_feat_cfg->edpp = 0; |
774 | plat->safety_feat_cfg->prtyen = 0; |
775 | plat->safety_feat_cfg->tmouten = 0; |
776 | |
777 | return intel_mgbe_common_data(pdev, plat); |
778 | } |
779 | |
780 | static int tgl_sgmii_phy0_data(struct pci_dev *pdev, |
781 | struct plat_stmmacenet_data *plat) |
782 | { |
783 | plat->bus_id = 1; |
784 | plat->phy_interface = PHY_INTERFACE_MODE_SGMII; |
785 | plat->serdes_powerup = intel_serdes_powerup; |
786 | plat->serdes_powerdown = intel_serdes_powerdown; |
787 | return tgl_common_data(pdev, plat); |
788 | } |
789 | |
790 | static struct stmmac_pci_info tgl_sgmii1g_phy0_info = { |
791 | .setup = tgl_sgmii_phy0_data, |
792 | }; |
793 | |
794 | static int tgl_sgmii_phy1_data(struct pci_dev *pdev, |
795 | struct plat_stmmacenet_data *plat) |
796 | { |
797 | plat->bus_id = 2; |
798 | plat->phy_interface = PHY_INTERFACE_MODE_SGMII; |
799 | plat->serdes_powerup = intel_serdes_powerup; |
800 | plat->serdes_powerdown = intel_serdes_powerdown; |
801 | return tgl_common_data(pdev, plat); |
802 | } |
803 | |
804 | static struct stmmac_pci_info tgl_sgmii1g_phy1_info = { |
805 | .setup = tgl_sgmii_phy1_data, |
806 | }; |
807 | |
808 | static int adls_sgmii_phy0_data(struct pci_dev *pdev, |
809 | struct plat_stmmacenet_data *plat) |
810 | { |
811 | plat->bus_id = 1; |
812 | plat->phy_interface = PHY_INTERFACE_MODE_SGMII; |
813 | |
814 | /* SerDes power up and power down are done in BIOS for ADL */ |
815 | |
816 | return tgl_common_data(pdev, plat); |
817 | } |
818 | |
819 | static struct stmmac_pci_info adls_sgmii1g_phy0_info = { |
820 | .setup = adls_sgmii_phy0_data, |
821 | }; |
822 | |
823 | static int adls_sgmii_phy1_data(struct pci_dev *pdev, |
824 | struct plat_stmmacenet_data *plat) |
825 | { |
826 | plat->bus_id = 2; |
827 | plat->phy_interface = PHY_INTERFACE_MODE_SGMII; |
828 | |
829 | /* SerDes power up and power down are done in BIOS for ADL */ |
830 | |
831 | return tgl_common_data(pdev, plat); |
832 | } |
833 | |
834 | static struct stmmac_pci_info adls_sgmii1g_phy1_info = { |
835 | .setup = adls_sgmii_phy1_data, |
836 | }; |
837 | static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = { |
838 | { |
839 | .func = 6, |
840 | .phy_addr = 1, |
841 | }, |
842 | }; |
843 | |
844 | static const struct stmmac_pci_dmi_data galileo_stmmac_dmi_data = { |
845 | .func = galileo_stmmac_func_data, |
846 | .nfuncs = ARRAY_SIZE(galileo_stmmac_func_data), |
847 | }; |
848 | |
849 | static const struct stmmac_pci_func_data iot2040_stmmac_func_data[] = { |
850 | { |
851 | .func = 6, |
852 | .phy_addr = 1, |
853 | }, |
854 | { |
855 | .func = 7, |
856 | .phy_addr = 1, |
857 | }, |
858 | }; |
859 | |
860 | static const struct stmmac_pci_dmi_data iot2040_stmmac_dmi_data = { |
861 | .func = iot2040_stmmac_func_data, |
862 | .nfuncs = ARRAY_SIZE(iot2040_stmmac_func_data), |
863 | }; |
864 | |
865 | static const struct dmi_system_id quark_pci_dmi[] = { |
866 | { |
867 | .matches = { |
868 | DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo" ), |
869 | }, |
870 | .driver_data = (void *)&galileo_stmmac_dmi_data, |
871 | }, |
872 | { |
873 | .matches = { |
874 | DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2" ), |
875 | }, |
876 | .driver_data = (void *)&galileo_stmmac_dmi_data, |
877 | }, |
878 | /* There are 2 types of SIMATIC IOT2000: IOT2020 and IOT2040. |
879 | * The asset tag "6ES7647-0AA00-0YA2" is only for IOT2020 which |
880 | * has only one pci network device while other asset tags are |
881 | * for IOT2040 which has two. |
882 | */ |
883 | { |
884 | .matches = { |
885 | DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000" ), |
886 | DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG, |
887 | "6ES7647-0AA00-0YA2" ), |
888 | }, |
889 | .driver_data = (void *)&galileo_stmmac_dmi_data, |
890 | }, |
891 | { |
892 | .matches = { |
893 | DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000" ), |
894 | }, |
895 | .driver_data = (void *)&iot2040_stmmac_dmi_data, |
896 | }, |
897 | {} |
898 | }; |
899 | |
900 | static int quark_default_data(struct pci_dev *pdev, |
901 | struct plat_stmmacenet_data *plat) |
902 | { |
903 | int ret; |
904 | |
905 | /* Set common default data first */ |
906 | common_default_data(plat); |
907 | |
908 | /* Refuse to load the driver and register net device if MAC controller |
909 | * does not connect to any PHY interface. |
910 | */ |
911 | ret = stmmac_pci_find_phy_addr(pdev, dmi_list: quark_pci_dmi); |
912 | if (ret < 0) { |
913 | /* Return error to the caller on DMI enabled boards. */ |
914 | if (dmi_get_system_info(field: DMI_BOARD_NAME)) |
915 | return ret; |
916 | |
917 | /* Galileo boards with old firmware don't support DMI. We always |
918 | * use 1 here as PHY address, so at least the first found MAC |
919 | * controller would be probed. |
920 | */ |
921 | ret = 1; |
922 | } |
923 | |
924 | plat->bus_id = pci_dev_id(dev: pdev); |
925 | plat->phy_addr = ret; |
926 | plat->phy_interface = PHY_INTERFACE_MODE_RMII; |
927 | |
928 | plat->dma_cfg->pbl = 16; |
929 | plat->dma_cfg->pblx8 = true; |
930 | plat->dma_cfg->fixed_burst = 1; |
931 | /* AXI (TODO) */ |
932 | |
933 | return 0; |
934 | } |
935 | |
936 | static const struct stmmac_pci_info quark_info = { |
937 | .setup = quark_default_data, |
938 | }; |
939 | |
940 | static int stmmac_config_single_msi(struct pci_dev *pdev, |
941 | struct plat_stmmacenet_data *plat, |
942 | struct stmmac_resources *res) |
943 | { |
944 | int ret; |
945 | |
946 | ret = pci_alloc_irq_vectors(dev: pdev, min_vecs: 1, max_vecs: 1, PCI_IRQ_ALL_TYPES); |
947 | if (ret < 0) { |
948 | dev_info(&pdev->dev, "%s: Single IRQ enablement failed\n" , |
949 | __func__); |
950 | return ret; |
951 | } |
952 | |
953 | res->irq = pci_irq_vector(dev: pdev, nr: 0); |
954 | res->wol_irq = res->irq; |
955 | plat->flags &= ~STMMAC_FLAG_MULTI_MSI_EN; |
956 | dev_info(&pdev->dev, "%s: Single IRQ enablement successful\n" , |
957 | __func__); |
958 | |
959 | return 0; |
960 | } |
961 | |
962 | static int stmmac_config_multi_msi(struct pci_dev *pdev, |
963 | struct plat_stmmacenet_data *plat, |
964 | struct stmmac_resources *res) |
965 | { |
966 | int ret; |
967 | int i; |
968 | |
969 | if (plat->msi_rx_base_vec >= STMMAC_MSI_VEC_MAX || |
970 | plat->msi_tx_base_vec >= STMMAC_MSI_VEC_MAX) { |
971 | dev_info(&pdev->dev, "%s: Invalid RX & TX vector defined\n" , |
972 | __func__); |
973 | return -1; |
974 | } |
975 | |
976 | ret = pci_alloc_irq_vectors(dev: pdev, min_vecs: 2, STMMAC_MSI_VEC_MAX, |
977 | PCI_IRQ_MSI | PCI_IRQ_MSIX); |
978 | if (ret < 0) { |
979 | dev_info(&pdev->dev, "%s: multi MSI enablement failed\n" , |
980 | __func__); |
981 | return ret; |
982 | } |
983 | |
984 | /* For RX MSI */ |
985 | for (i = 0; i < plat->rx_queues_to_use; i++) { |
986 | res->rx_irq[i] = pci_irq_vector(dev: pdev, |
987 | nr: plat->msi_rx_base_vec + i * 2); |
988 | } |
989 | |
990 | /* For TX MSI */ |
991 | for (i = 0; i < plat->tx_queues_to_use; i++) { |
992 | res->tx_irq[i] = pci_irq_vector(dev: pdev, |
993 | nr: plat->msi_tx_base_vec + i * 2); |
994 | } |
995 | |
996 | if (plat->msi_mac_vec < STMMAC_MSI_VEC_MAX) |
997 | res->irq = pci_irq_vector(dev: pdev, nr: plat->msi_mac_vec); |
998 | if (plat->msi_wol_vec < STMMAC_MSI_VEC_MAX) |
999 | res->wol_irq = pci_irq_vector(dev: pdev, nr: plat->msi_wol_vec); |
1000 | if (plat->msi_lpi_vec < STMMAC_MSI_VEC_MAX) |
1001 | res->lpi_irq = pci_irq_vector(dev: pdev, nr: plat->msi_lpi_vec); |
1002 | if (plat->msi_sfty_ce_vec < STMMAC_MSI_VEC_MAX) |
1003 | res->sfty_ce_irq = pci_irq_vector(dev: pdev, nr: plat->msi_sfty_ce_vec); |
1004 | if (plat->msi_sfty_ue_vec < STMMAC_MSI_VEC_MAX) |
1005 | res->sfty_ue_irq = pci_irq_vector(dev: pdev, nr: plat->msi_sfty_ue_vec); |
1006 | |
1007 | plat->flags |= STMMAC_FLAG_MULTI_MSI_EN; |
1008 | dev_info(&pdev->dev, "%s: multi MSI enablement successful\n" , __func__); |
1009 | |
1010 | return 0; |
1011 | } |
1012 | |
1013 | /** |
1014 | * intel_eth_pci_probe |
1015 | * |
1016 | * @pdev: pci device pointer |
1017 | * @id: pointer to table of device id/id's. |
1018 | * |
1019 | * Description: This probing function gets called for all PCI devices which |
1020 | * match the ID table and are not "owned" by other driver yet. This function |
1021 | * gets passed a "struct pci_dev *" for each device whose entry in the ID table |
1022 | * matches the device. The probe functions returns zero when the driver choose |
1023 | * to take "ownership" of the device or an error code(-ve no) otherwise. |
1024 | */ |
1025 | static int intel_eth_pci_probe(struct pci_dev *pdev, |
1026 | const struct pci_device_id *id) |
1027 | { |
1028 | struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data; |
1029 | struct intel_priv_data *intel_priv; |
1030 | struct plat_stmmacenet_data *plat; |
1031 | struct stmmac_resources res; |
1032 | int ret; |
1033 | |
1034 | intel_priv = devm_kzalloc(dev: &pdev->dev, size: sizeof(*intel_priv), GFP_KERNEL); |
1035 | if (!intel_priv) |
1036 | return -ENOMEM; |
1037 | |
1038 | plat = devm_kzalloc(dev: &pdev->dev, size: sizeof(*plat), GFP_KERNEL); |
1039 | if (!plat) |
1040 | return -ENOMEM; |
1041 | |
1042 | plat->mdio_bus_data = devm_kzalloc(dev: &pdev->dev, |
1043 | size: sizeof(*plat->mdio_bus_data), |
1044 | GFP_KERNEL); |
1045 | if (!plat->mdio_bus_data) |
1046 | return -ENOMEM; |
1047 | |
1048 | plat->dma_cfg = devm_kzalloc(dev: &pdev->dev, size: sizeof(*plat->dma_cfg), |
1049 | GFP_KERNEL); |
1050 | if (!plat->dma_cfg) |
1051 | return -ENOMEM; |
1052 | |
1053 | plat->safety_feat_cfg = devm_kzalloc(dev: &pdev->dev, |
1054 | size: sizeof(*plat->safety_feat_cfg), |
1055 | GFP_KERNEL); |
1056 | if (!plat->safety_feat_cfg) |
1057 | return -ENOMEM; |
1058 | |
1059 | /* Enable pci device */ |
1060 | ret = pcim_enable_device(pdev); |
1061 | if (ret) { |
1062 | dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n" , |
1063 | __func__); |
1064 | return ret; |
1065 | } |
1066 | |
1067 | ret = pcim_iomap_regions(pdev, BIT(0), name: pci_name(pdev)); |
1068 | if (ret) |
1069 | return ret; |
1070 | |
1071 | pci_set_master(dev: pdev); |
1072 | |
1073 | plat->bsp_priv = intel_priv; |
1074 | intel_priv->mdio_adhoc_addr = INTEL_MGBE_ADHOC_ADDR; |
1075 | intel_priv->crossts_adj = 1; |
1076 | |
1077 | /* Initialize all MSI vectors to invalid so that it can be set |
1078 | * according to platform data settings below. |
1079 | * Note: MSI vector takes value from 0 upto 31 (STMMAC_MSI_VEC_MAX) |
1080 | */ |
1081 | plat->msi_mac_vec = STMMAC_MSI_VEC_MAX; |
1082 | plat->msi_wol_vec = STMMAC_MSI_VEC_MAX; |
1083 | plat->msi_lpi_vec = STMMAC_MSI_VEC_MAX; |
1084 | plat->msi_sfty_ce_vec = STMMAC_MSI_VEC_MAX; |
1085 | plat->msi_sfty_ue_vec = STMMAC_MSI_VEC_MAX; |
1086 | plat->msi_rx_base_vec = STMMAC_MSI_VEC_MAX; |
1087 | plat->msi_tx_base_vec = STMMAC_MSI_VEC_MAX; |
1088 | |
1089 | ret = info->setup(pdev, plat); |
1090 | if (ret) |
1091 | return ret; |
1092 | |
1093 | memset(&res, 0, sizeof(res)); |
1094 | res.addr = pcim_iomap_table(pdev)[0]; |
1095 | |
1096 | if (plat->eee_usecs_rate > 0) { |
1097 | u32 tx_lpi_usec; |
1098 | |
1099 | tx_lpi_usec = (plat->eee_usecs_rate / 1000000) - 1; |
1100 | writel(val: tx_lpi_usec, addr: res.addr + GMAC_1US_TIC_COUNTER); |
1101 | } |
1102 | |
1103 | ret = stmmac_config_multi_msi(pdev, plat, res: &res); |
1104 | if (ret) { |
1105 | ret = stmmac_config_single_msi(pdev, plat, res: &res); |
1106 | if (ret) { |
1107 | dev_err(&pdev->dev, "%s: ERROR: failed to enable IRQ\n" , |
1108 | __func__); |
1109 | goto err_alloc_irq; |
1110 | } |
1111 | } |
1112 | |
1113 | ret = stmmac_dvr_probe(device: &pdev->dev, plat_dat: plat, res: &res); |
1114 | if (ret) { |
1115 | goto err_alloc_irq; |
1116 | } |
1117 | |
1118 | return 0; |
1119 | |
1120 | err_alloc_irq: |
1121 | clk_disable_unprepare(clk: plat->stmmac_clk); |
1122 | clk_unregister_fixed_rate(clk: plat->stmmac_clk); |
1123 | return ret; |
1124 | } |
1125 | |
1126 | /** |
1127 | * intel_eth_pci_remove |
1128 | * |
1129 | * @pdev: pci device pointer |
1130 | * Description: this function calls the main to free the net resources |
1131 | * and releases the PCI resources. |
1132 | */ |
1133 | static void intel_eth_pci_remove(struct pci_dev *pdev) |
1134 | { |
1135 | struct net_device *ndev = dev_get_drvdata(dev: &pdev->dev); |
1136 | struct stmmac_priv *priv = netdev_priv(dev: ndev); |
1137 | |
1138 | stmmac_dvr_remove(dev: &pdev->dev); |
1139 | |
1140 | clk_disable_unprepare(clk: priv->plat->stmmac_clk); |
1141 | clk_unregister_fixed_rate(clk: priv->plat->stmmac_clk); |
1142 | } |
1143 | |
1144 | static int __maybe_unused intel_eth_pci_suspend(struct device *dev) |
1145 | { |
1146 | struct pci_dev *pdev = to_pci_dev(dev); |
1147 | int ret; |
1148 | |
1149 | ret = stmmac_suspend(dev); |
1150 | if (ret) |
1151 | return ret; |
1152 | |
1153 | ret = pci_save_state(dev: pdev); |
1154 | if (ret) |
1155 | return ret; |
1156 | |
1157 | pci_wake_from_d3(dev: pdev, enable: true); |
1158 | pci_set_power_state(dev: pdev, PCI_D3hot); |
1159 | return 0; |
1160 | } |
1161 | |
1162 | static int __maybe_unused intel_eth_pci_resume(struct device *dev) |
1163 | { |
1164 | struct pci_dev *pdev = to_pci_dev(dev); |
1165 | int ret; |
1166 | |
1167 | pci_restore_state(dev: pdev); |
1168 | pci_set_power_state(dev: pdev, PCI_D0); |
1169 | |
1170 | ret = pcim_enable_device(pdev); |
1171 | if (ret) |
1172 | return ret; |
1173 | |
1174 | pci_set_master(dev: pdev); |
1175 | |
1176 | return stmmac_resume(dev); |
1177 | } |
1178 | |
1179 | static SIMPLE_DEV_PM_OPS(intel_eth_pm_ops, intel_eth_pci_suspend, |
1180 | intel_eth_pci_resume); |
1181 | |
1182 | #define PCI_DEVICE_ID_INTEL_QUARK 0x0937 |
1183 | #define PCI_DEVICE_ID_INTEL_EHL_RGMII1G 0x4b30 |
1184 | #define PCI_DEVICE_ID_INTEL_EHL_SGMII1G 0x4b31 |
1185 | #define PCI_DEVICE_ID_INTEL_EHL_SGMII2G5 0x4b32 |
1186 | /* Intel(R) Programmable Services Engine (Intel(R) PSE) consist of 2 MAC |
1187 | * which are named PSE0 and PSE1 |
1188 | */ |
1189 | #define PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G 0x4ba0 |
1190 | #define PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G 0x4ba1 |
1191 | #define PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G5 0x4ba2 |
1192 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G 0x4bb0 |
1193 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G 0x4bb1 |
1194 | #define PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5 0x4bb2 |
1195 | #define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_0 0x43ac |
1196 | #define PCI_DEVICE_ID_INTEL_TGLH_SGMII1G_1 0x43a2 |
1197 | #define PCI_DEVICE_ID_INTEL_TGL_SGMII1G 0xa0ac |
1198 | #define PCI_DEVICE_ID_INTEL_ADLS_SGMII1G_0 0x7aac |
1199 | #define PCI_DEVICE_ID_INTEL_ADLS_SGMII1G_1 0x7aad |
1200 | #define PCI_DEVICE_ID_INTEL_ADLN_SGMII1G 0x54ac |
1201 | #define PCI_DEVICE_ID_INTEL_RPLP_SGMII1G 0x51ac |
1202 | |
1203 | static const struct pci_device_id intel_eth_pci_id_table[] = { |
1204 | { PCI_DEVICE_DATA(INTEL, QUARK, &quark_info) }, |
1205 | { PCI_DEVICE_DATA(INTEL, EHL_RGMII1G, &ehl_rgmii1g_info) }, |
1206 | { PCI_DEVICE_DATA(INTEL, EHL_SGMII1G, &ehl_sgmii1g_info) }, |
1207 | { PCI_DEVICE_DATA(INTEL, EHL_SGMII2G5, &ehl_sgmii1g_info) }, |
1208 | { PCI_DEVICE_DATA(INTEL, EHL_PSE0_RGMII1G, &ehl_pse0_rgmii1g_info) }, |
1209 | { PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII1G, &ehl_pse0_sgmii1g_info) }, |
1210 | { PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII2G5, &ehl_pse0_sgmii1g_info) }, |
1211 | { PCI_DEVICE_DATA(INTEL, EHL_PSE1_RGMII1G, &ehl_pse1_rgmii1g_info) }, |
1212 | { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G, &ehl_pse1_sgmii1g_info) }, |
1213 | { PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5, &ehl_pse1_sgmii1g_info) }, |
1214 | { PCI_DEVICE_DATA(INTEL, TGL_SGMII1G, &tgl_sgmii1g_phy0_info) }, |
1215 | { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_0, &tgl_sgmii1g_phy0_info) }, |
1216 | { PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_1, &tgl_sgmii1g_phy1_info) }, |
1217 | { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_0, &adls_sgmii1g_phy0_info) }, |
1218 | { PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_1, &adls_sgmii1g_phy1_info) }, |
1219 | { PCI_DEVICE_DATA(INTEL, ADLN_SGMII1G, &tgl_sgmii1g_phy0_info) }, |
1220 | { PCI_DEVICE_DATA(INTEL, RPLP_SGMII1G, &tgl_sgmii1g_phy0_info) }, |
1221 | {} |
1222 | }; |
1223 | MODULE_DEVICE_TABLE(pci, intel_eth_pci_id_table); |
1224 | |
1225 | static struct pci_driver intel_eth_pci_driver = { |
1226 | .name = "intel-eth-pci" , |
1227 | .id_table = intel_eth_pci_id_table, |
1228 | .probe = intel_eth_pci_probe, |
1229 | .remove = intel_eth_pci_remove, |
1230 | .driver = { |
1231 | .pm = &intel_eth_pm_ops, |
1232 | }, |
1233 | }; |
1234 | |
1235 | module_pci_driver(intel_eth_pci_driver); |
1236 | |
1237 | MODULE_DESCRIPTION("INTEL 10/100/1000 Ethernet PCI driver" ); |
1238 | MODULE_AUTHOR("Voon Weifeng <weifeng.voon@intel.com>" ); |
1239 | MODULE_LICENSE("GPL v2" ); |
1240 | |