1 // SPDX-License-Identifier: GPL-2.0-only
2 /*******************************************************************************
3 This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
4 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
5 developing this code.
6
7 This only implements the mac core functions for this chip.
8
9 Copyright (C) 2007-2009 STMicroelectronics Ltd
10
11
12 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
13 *******************************************************************************/
14
15 #include <linux/crc32.h>
16 #include <linux/slab.h>
17 #include <linux/ethtool.h>
18 #include <linux/io.h>
19 #include <linux/string_choices.h>
20 #include "stmmac.h"
21 #include "stmmac_pcs.h"
22 #include "stmmac_ptp.h"
23 #include "dwmac1000.h"
24
25 static const struct stmmac_pcs_info dwmac1000_pcs_info = {
26 .pcs_offset = GMAC_PCS_BASE,
27 .rgsmii_offset = GMAC_RGSMIIIS,
28 .rgsmii_status_mask = GMAC_RSGMIIIS_MASK,
29 .int_mask = GMAC_INT_DISABLE_PCSLINK | GMAC_INT_DISABLE_PCSAN,
30 };
31
dwmac1000_pcs_init(struct stmmac_priv * priv)32 static int dwmac1000_pcs_init(struct stmmac_priv *priv)
33 {
34 if (!priv->dma_cap.pcs)
35 return 0;
36
37 return stmmac_integrated_pcs_init(priv, &dwmac1000_pcs_info);
38 }
39
dwmac1000_core_init(struct mac_device_info * hw,struct net_device * dev)40 static void dwmac1000_core_init(struct mac_device_info *hw,
41 struct net_device *dev)
42 {
43 void __iomem *ioaddr = hw->pcsr;
44 int mtu = dev->mtu;
45 u32 value;
46
47 /* Configure GMAC core */
48 value = readl(ioaddr + GMAC_CONTROL);
49
50 if (mtu > 1500)
51 value |= GMAC_CONTROL_2K;
52 if (mtu > 2000)
53 value |= GMAC_CONTROL_JE;
54
55 writel(value | GMAC_CORE_INIT, ioaddr + GMAC_CONTROL);
56
57 /* Mask GMAC interrupts */
58 writel(GMAC_INT_DEFAULT_MASK, ioaddr + GMAC_INT_MASK);
59
60 #ifdef STMMAC_VLAN_TAG_USED
61 /* Tag detection without filtering */
62 writel(0x0, ioaddr + GMAC_VLAN_TAG);
63 #endif
64 }
65
dwmac1000_irq_modify(struct mac_device_info * hw,u32 disable,u32 enable)66 static void dwmac1000_irq_modify(struct mac_device_info *hw, u32 disable,
67 u32 enable)
68 {
69 void __iomem *int_mask = hw->pcsr + GMAC_INT_MASK;
70 unsigned long flags;
71 u32 value;
72
73 spin_lock_irqsave(&hw->irq_ctrl_lock, flags);
74 value = readl(int_mask) | disable;
75 value &= ~enable;
76 writel(value, int_mask);
77 spin_unlock_irqrestore(&hw->irq_ctrl_lock, flags);
78 }
79
dwmac1000_rx_ipc_enable(struct mac_device_info * hw)80 static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
81 {
82 void __iomem *ioaddr = hw->pcsr;
83 u32 value = readl(ioaddr + GMAC_CONTROL);
84
85 if (hw->rx_csum)
86 value |= GMAC_CONTROL_IPC;
87 else
88 value &= ~GMAC_CONTROL_IPC;
89
90 writel(value, ioaddr + GMAC_CONTROL);
91
92 value = readl(ioaddr + GMAC_CONTROL);
93
94 return !!(value & GMAC_CONTROL_IPC);
95 }
96
dwmac1000_dump_regs(struct mac_device_info * hw,u32 * reg_space)97 static void dwmac1000_dump_regs(struct mac_device_info *hw, u32 *reg_space)
98 {
99 void __iomem *ioaddr = hw->pcsr;
100 int i;
101
102 for (i = 0; i < 55; i++)
103 reg_space[i] = readl(ioaddr + i * 4);
104 }
105
dwmac1000_set_umac_addr(struct mac_device_info * hw,const unsigned char * addr,unsigned int reg_n)106 static void dwmac1000_set_umac_addr(struct mac_device_info *hw,
107 const unsigned char *addr,
108 unsigned int reg_n)
109 {
110 void __iomem *ioaddr = hw->pcsr;
111 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
112 GMAC_ADDR_LOW(reg_n));
113 }
114
dwmac1000_get_umac_addr(struct mac_device_info * hw,unsigned char * addr,unsigned int reg_n)115 static void dwmac1000_get_umac_addr(struct mac_device_info *hw,
116 unsigned char *addr,
117 unsigned int reg_n)
118 {
119 void __iomem *ioaddr = hw->pcsr;
120 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
121 GMAC_ADDR_LOW(reg_n));
122 }
123
dwmac1000_set_mchash(void __iomem * ioaddr,u32 * mcfilterbits,int mcbitslog2)124 static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
125 int mcbitslog2)
126 {
127 int numhashregs, regs;
128
129 switch (mcbitslog2) {
130 case 6:
131 writel(mcfilterbits[0], ioaddr + GMAC_HASH_LOW);
132 writel(mcfilterbits[1], ioaddr + GMAC_HASH_HIGH);
133 return;
134 case 7:
135 numhashregs = 4;
136 break;
137 case 8:
138 numhashregs = 8;
139 break;
140 default:
141 pr_debug("STMMAC: err in setting multicast filter\n");
142 return;
143 }
144 for (regs = 0; regs < numhashregs; regs++)
145 writel(mcfilterbits[regs],
146 ioaddr + GMAC_EXTHASH_BASE + regs * 4);
147 }
148
dwmac1000_set_filter(struct mac_device_info * hw,struct net_device * dev)149 static void dwmac1000_set_filter(struct mac_device_info *hw,
150 struct net_device *dev)
151 {
152 void __iomem *ioaddr = (void __iomem *)dev->base_addr;
153 unsigned int value = 0;
154 unsigned int perfect_addr_number = hw->unicast_filter_entries;
155 u32 mc_filter[8];
156 int mcbitslog2 = hw->mcast_bits_log2;
157
158 pr_debug("%s: # mcasts %d, # unicast %d\n", __func__,
159 netdev_mc_count(dev), netdev_uc_count(dev));
160
161 memset(mc_filter, 0, sizeof(mc_filter));
162
163 if (dev->flags & IFF_PROMISC) {
164 value = GMAC_FRAME_FILTER_PR | GMAC_FRAME_FILTER_PCF;
165 } else if (dev->flags & IFF_ALLMULTI) {
166 value = GMAC_FRAME_FILTER_PM; /* pass all multi */
167 } else if (!netdev_mc_empty(dev) && (mcbitslog2 == 0)) {
168 /* Fall back to all multicast if we've no filter */
169 value = GMAC_FRAME_FILTER_PM;
170 } else if (!netdev_mc_empty(dev)) {
171 struct netdev_hw_addr *ha;
172
173 /* Hash filter for multicast */
174 value = GMAC_FRAME_FILTER_HMC;
175
176 netdev_for_each_mc_addr(ha, dev) {
177 /* The upper n bits of the calculated CRC are used to
178 * index the contents of the hash table. The number of
179 * bits used depends on the hardware configuration
180 * selected at core configuration time.
181 */
182 int bit_nr = bitrev32(~crc32_le(~0, ha->addr,
183 ETH_ALEN)) >>
184 (32 - mcbitslog2);
185 /* The most significant bit determines the register to
186 * use (H/L) while the other 5 bits determine the bit
187 * within the register.
188 */
189 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
190 }
191 }
192
193 value |= GMAC_FRAME_FILTER_HPF;
194 dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2);
195
196 /* Handle multiple unicast addresses (perfect filtering) */
197 if (netdev_uc_count(dev) + 1 > perfect_addr_number)
198 /* Switch to promiscuous mode if more than unicast
199 * addresses are requested than supported by hardware.
200 */
201 value |= GMAC_FRAME_FILTER_PR;
202 else {
203 int reg = 1;
204 struct netdev_hw_addr *ha;
205
206 netdev_for_each_uc_addr(ha, dev) {
207 stmmac_set_mac_addr(ioaddr, ha->addr,
208 GMAC_ADDR_HIGH(reg),
209 GMAC_ADDR_LOW(reg));
210 reg++;
211 }
212
213 while (reg < perfect_addr_number) {
214 writel(0, ioaddr + GMAC_ADDR_HIGH(reg));
215 writel(0, ioaddr + GMAC_ADDR_LOW(reg));
216 reg++;
217 }
218 }
219
220 #ifdef FRAME_FILTER_DEBUG
221 /* Enable Receive all mode (to debug filtering_fail errors) */
222 value |= GMAC_FRAME_FILTER_RA;
223 #endif
224 writel(value, ioaddr + GMAC_FRAME_FILTER);
225 }
226
227
dwmac1000_flow_ctrl(struct mac_device_info * hw,unsigned int duplex,unsigned int fc,unsigned int pause_time,u8 tx_cnt)228 static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
229 unsigned int fc, unsigned int pause_time,
230 u8 tx_cnt)
231 {
232 void __iomem *ioaddr = hw->pcsr;
233 /* Set flow such that DZPQ in Mac Register 6 is 0,
234 * and unicast pause detect is enabled.
235 */
236 unsigned int flow = GMAC_FLOW_CTRL_UP;
237
238 pr_debug("GMAC Flow-Control:\n");
239 if (fc & FLOW_RX) {
240 pr_debug("\tReceive Flow-Control ON\n");
241 flow |= GMAC_FLOW_CTRL_RFE;
242 }
243 if (fc & FLOW_TX) {
244 pr_debug("\tTransmit Flow-Control ON\n");
245 flow |= GMAC_FLOW_CTRL_TFE;
246 }
247
248 if (duplex) {
249 pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
250 flow |= FIELD_PREP(GMAC_FLOW_CTRL_PT_MASK, pause_time);
251 }
252
253 writel(flow, ioaddr + GMAC_FLOW_CTRL);
254 }
255
dwmac1000_pmt(struct mac_device_info * hw,unsigned long mode)256 static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
257 {
258 void __iomem *ioaddr = hw->pcsr;
259 unsigned int pmt = 0;
260
261 if (mode & WAKE_MAGIC) {
262 pr_debug("GMAC: WOL Magic frame\n");
263 pmt |= power_down | magic_pkt_en;
264 }
265 if (mode & WAKE_UCAST) {
266 pr_debug("GMAC: WOL on global unicast\n");
267 pmt |= power_down | global_unicast | wake_up_frame_en;
268 }
269
270 writel(pmt, ioaddr + GMAC_PMT);
271 }
272
dwmac1000_irq_status(struct stmmac_priv * priv,struct stmmac_extra_stats * x)273 static int dwmac1000_irq_status(struct stmmac_priv *priv,
274 struct stmmac_extra_stats *x)
275 {
276 void __iomem *ioaddr = priv->hw->pcsr;
277 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
278 u32 intr_mask = readl(ioaddr + GMAC_INT_MASK);
279 int ret = 0;
280
281 /* Discard masked bits */
282 intr_status &= ~intr_mask;
283
284 /* Not used events (e.g. MMC interrupts) are not handled. */
285 if ((intr_status & GMAC_INT_STATUS_MMCTIS))
286 x->mmc_tx_irq_n++;
287 if (unlikely(intr_status & GMAC_INT_STATUS_MMCRIS))
288 x->mmc_rx_irq_n++;
289 if (unlikely(intr_status & GMAC_INT_STATUS_MMCCSUM))
290 x->mmc_rx_csum_offload_irq_n++;
291 if (unlikely(intr_status & GMAC_INT_DISABLE_PMT)) {
292 /* clear the PMT bits 5 and 6 by reading the PMT status reg */
293 readl(ioaddr + GMAC_PMT);
294 x->irq_receive_pmt_irq_n++;
295 }
296
297 /* MAC tx/rx EEE LPI entry/exit interrupts */
298 if (intr_status & GMAC_INT_STATUS_LPIIS) {
299 /* Clean LPI interrupt by reading the Reg 12 */
300 ret = readl(ioaddr + LPI_CTRL_STATUS);
301
302 if (ret & LPI_CTRL_STATUS_TLPIEN)
303 x->irq_tx_path_in_lpi_mode_n++;
304 if (ret & LPI_CTRL_STATUS_TLPIEX)
305 x->irq_tx_path_exit_lpi_mode_n++;
306 if (ret & LPI_CTRL_STATUS_RLPIEN)
307 x->irq_rx_path_in_lpi_mode_n++;
308 if (ret & LPI_CTRL_STATUS_RLPIEX)
309 x->irq_rx_path_exit_lpi_mode_n++;
310 }
311
312 if (intr_status & (PCS_ANE_IRQ | PCS_LINK_IRQ))
313 stmmac_integrated_pcs_irq(priv, intr_status, x);
314
315 return ret;
316 }
317
dwmac1000_set_lpi_mode(struct mac_device_info * hw,enum stmmac_lpi_mode mode,bool en_tx_lpi_clockgating,u32 et)318 static int dwmac1000_set_lpi_mode(struct mac_device_info *hw,
319 enum stmmac_lpi_mode mode,
320 bool en_tx_lpi_clockgating, u32 et)
321 {
322 void __iomem *ioaddr = hw->pcsr;
323 u32 value;
324
325 if (mode == STMMAC_LPI_TIMER)
326 return -EOPNOTSUPP;
327
328 value = readl(ioaddr + LPI_CTRL_STATUS);
329 if (mode == STMMAC_LPI_FORCED)
330 value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
331 else
332 value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
333 writel(value, ioaddr + LPI_CTRL_STATUS);
334
335 return 0;
336 }
337
dwmac1000_set_eee_pls(struct mac_device_info * hw,int link)338 static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
339 {
340 void __iomem *ioaddr = hw->pcsr;
341 u32 value;
342
343 value = readl(ioaddr + LPI_CTRL_STATUS);
344
345 if (link)
346 value |= LPI_CTRL_STATUS_PLS;
347 else
348 value &= ~LPI_CTRL_STATUS_PLS;
349
350 writel(value, ioaddr + LPI_CTRL_STATUS);
351 }
352
dwmac1000_set_eee_timer(struct mac_device_info * hw,int ls,int tw)353 static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
354 {
355 void __iomem *ioaddr = hw->pcsr;
356 int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
357
358 /* Program the timers in the LPI timer control register:
359 * LS: minimum time (ms) for which the link
360 * status from PHY should be ok before transmitting
361 * the LPI pattern.
362 * TW: minimum time (us) for which the core waits
363 * after it has stopped transmitting the LPI pattern.
364 */
365 writel(value, ioaddr + LPI_TIMER_CTRL);
366 }
367
dwmac1000_ctrl_ane(struct stmmac_priv * priv,bool ane,bool srgmi_ral)368 static void dwmac1000_ctrl_ane(struct stmmac_priv *priv, bool ane,
369 bool srgmi_ral)
370 {
371 dwmac_ctrl_ane(priv->ioaddr, GMAC_PCS_BASE, ane, srgmi_ral);
372 }
373
dwmac1000_debug(struct stmmac_priv * priv,void __iomem * ioaddr,struct stmmac_extra_stats * x,u32 rx_queues,u32 tx_queues)374 static void dwmac1000_debug(struct stmmac_priv *priv, void __iomem *ioaddr,
375 struct stmmac_extra_stats *x,
376 u32 rx_queues, u32 tx_queues)
377 {
378 u32 value = readl(ioaddr + GMAC_DEBUG);
379
380 if (value & GMAC_DEBUG_TXSTSFSTS)
381 x->mtl_tx_status_fifo_full++;
382 if (value & GMAC_DEBUG_TXFSTS)
383 x->mtl_tx_fifo_not_empty++;
384 if (value & GMAC_DEBUG_TWCSTS)
385 x->mmtl_fifo_ctrl++;
386 if (value & GMAC_DEBUG_TRCSTS_MASK) {
387 u32 trcsts = FIELD_GET(GMAC_DEBUG_TRCSTS_MASK, value);
388
389 if (trcsts == GMAC_DEBUG_TRCSTS_WRITE)
390 x->mtl_tx_fifo_read_ctrl_write++;
391 else if (trcsts == GMAC_DEBUG_TRCSTS_TXW)
392 x->mtl_tx_fifo_read_ctrl_wait++;
393 else if (trcsts == GMAC_DEBUG_TRCSTS_READ)
394 x->mtl_tx_fifo_read_ctrl_read++;
395 else
396 x->mtl_tx_fifo_read_ctrl_idle++;
397 }
398 if (value & GMAC_DEBUG_TXPAUSED)
399 x->mac_tx_in_pause++;
400 if (value & GMAC_DEBUG_TFCSTS_MASK) {
401 u32 tfcsts = FIELD_GET(GMAC_DEBUG_TFCSTS_MASK, value);
402
403 if (tfcsts == GMAC_DEBUG_TFCSTS_XFER)
404 x->mac_tx_frame_ctrl_xfer++;
405 else if (tfcsts == GMAC_DEBUG_TFCSTS_GEN_PAUSE)
406 x->mac_tx_frame_ctrl_pause++;
407 else if (tfcsts == GMAC_DEBUG_TFCSTS_WAIT)
408 x->mac_tx_frame_ctrl_wait++;
409 else
410 x->mac_tx_frame_ctrl_idle++;
411 }
412 if (value & GMAC_DEBUG_TPESTS)
413 x->mac_gmii_tx_proto_engine++;
414 if (value & GMAC_DEBUG_RXFSTS_MASK) {
415 u32 rxfsts = FIELD_GET(GMAC_DEBUG_RXFSTS_MASK, value);
416
417 if (rxfsts == GMAC_DEBUG_RXFSTS_FULL)
418 x->mtl_rx_fifo_fill_level_full++;
419 else if (rxfsts == GMAC_DEBUG_RXFSTS_AT)
420 x->mtl_rx_fifo_fill_above_thresh++;
421 else if (rxfsts == GMAC_DEBUG_RXFSTS_BT)
422 x->mtl_rx_fifo_fill_below_thresh++;
423 else
424 x->mtl_rx_fifo_fill_level_empty++;
425 }
426 if (value & GMAC_DEBUG_RRCSTS_MASK) {
427 u32 rrcsts = FIELD_GET(GMAC_DEBUG_RRCSTS_MASK, value);
428
429 if (rrcsts == GMAC_DEBUG_RRCSTS_FLUSH)
430 x->mtl_rx_fifo_read_ctrl_flush++;
431 else if (rrcsts == GMAC_DEBUG_RRCSTS_RSTAT)
432 x->mtl_rx_fifo_read_ctrl_read_data++;
433 else if (rrcsts == GMAC_DEBUG_RRCSTS_RDATA)
434 x->mtl_rx_fifo_read_ctrl_status++;
435 else
436 x->mtl_rx_fifo_read_ctrl_idle++;
437 }
438 if (value & GMAC_DEBUG_RWCSTS)
439 x->mtl_rx_fifo_ctrl_active++;
440 if (value & GMAC_DEBUG_RFCFCSTS_MASK)
441 x->mac_rx_frame_ctrl_fifo = FIELD_GET(GMAC_DEBUG_RFCFCSTS_MASK,
442 value);
443 if (value & GMAC_DEBUG_RPESTS)
444 x->mac_gmii_rx_proto_engine++;
445 }
446
dwmac1000_set_mac_loopback(void __iomem * ioaddr,bool enable)447 static void dwmac1000_set_mac_loopback(void __iomem *ioaddr, bool enable)
448 {
449 u32 value = readl(ioaddr + GMAC_CONTROL);
450
451 if (enable)
452 value |= GMAC_CONTROL_LM;
453 else
454 value &= ~GMAC_CONTROL_LM;
455
456 writel(value, ioaddr + GMAC_CONTROL);
457 }
458
459 const struct stmmac_ops dwmac1000_ops = {
460 .pcs_init = dwmac1000_pcs_init,
461 .core_init = dwmac1000_core_init,
462 .irq_modify = dwmac1000_irq_modify,
463 .set_mac = stmmac_set_mac,
464 .rx_ipc = dwmac1000_rx_ipc_enable,
465 .dump_regs = dwmac1000_dump_regs,
466 .host_irq_status = dwmac1000_irq_status,
467 .set_filter = dwmac1000_set_filter,
468 .flow_ctrl = dwmac1000_flow_ctrl,
469 .pmt = dwmac1000_pmt,
470 .set_umac_addr = dwmac1000_set_umac_addr,
471 .get_umac_addr = dwmac1000_get_umac_addr,
472 .set_lpi_mode = dwmac1000_set_lpi_mode,
473 .set_eee_timer = dwmac1000_set_eee_timer,
474 .set_eee_pls = dwmac1000_set_eee_pls,
475 .debug = dwmac1000_debug,
476 .pcs_ctrl_ane = dwmac1000_ctrl_ane,
477 .set_mac_loopback = dwmac1000_set_mac_loopback,
478 };
479
dwmac1000_setup(struct stmmac_priv * priv)480 int dwmac1000_setup(struct stmmac_priv *priv)
481 {
482 struct mac_device_info *mac = priv->hw;
483
484 dev_info(priv->device, "\tDWMAC1000\n");
485
486 priv->dev->priv_flags |= IFF_UNICAST_FLT;
487 mac->pcsr = priv->ioaddr;
488 mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
489 mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
490 mac->mcast_bits_log2 = 0;
491
492 if (mac->multicast_filter_bins)
493 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
494
495 mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
496 MAC_10 | MAC_100 | MAC_1000;
497 mac->link.duplex = GMAC_CONTROL_DM;
498 mac->link.speed10 = GMAC_CONTROL_PS;
499 mac->link.speed100 = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
500 mac->link.speed1000 = 0;
501 mac->link.speed_mask = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
502 mac->mii.addr = GMAC_MII_ADDR;
503 mac->mii.data = GMAC_MII_DATA;
504 mac->mii.addr_mask = GENMASK_U32(15, 11);
505 mac->mii.reg_mask = GENMASK_U32(10, 6);
506 mac->mii.clk_csr_mask = GENMASK_U32(5, 2);
507
508 return 0;
509 }
510
511 /* DWMAC 1000 HW Timestaming ops */
512
dwmac1000_get_ptptime(void __iomem * ptpaddr,u64 * ptp_time)513 void dwmac1000_get_ptptime(void __iomem *ptpaddr, u64 *ptp_time)
514 {
515 u64 ns;
516
517 ns = readl(ptpaddr + GMAC_PTP_ATNR);
518 ns += (u64)readl(ptpaddr + GMAC_PTP_ATSR) * NSEC_PER_SEC;
519
520 *ptp_time = ns;
521 }
522
dwmac1000_timestamp_interrupt(struct stmmac_priv * priv)523 void dwmac1000_timestamp_interrupt(struct stmmac_priv *priv)
524 {
525 struct ptp_clock_event event;
526 u32 ts_status, num_snapshot;
527 unsigned long flags;
528 u64 ptp_time;
529 int i;
530
531 /* Clears the timestamp interrupt */
532 ts_status = readl(priv->ptpaddr + GMAC3_X_TIMESTAMP_STATUS);
533
534 if (!(priv->plat->flags & STMMAC_FLAG_EXT_SNAPSHOT_EN))
535 return;
536
537 num_snapshot = FIELD_GET(GMAC3_X_ATSNS, ts_status);
538
539 for (i = 0; i < num_snapshot; i++) {
540 read_lock_irqsave(&priv->ptp_lock, flags);
541 stmmac_get_ptptime(priv, priv->ptpaddr, &ptp_time);
542 read_unlock_irqrestore(&priv->ptp_lock, flags);
543
544 event.type = PTP_CLOCK_EXTTS;
545 event.index = 0;
546 event.timestamp = ptp_time;
547 ptp_clock_event(priv->ptp_clock, &event);
548 }
549 }
550
551 /* DWMAC 1000 ptp_clock_info ops */
552
dwmac1000_timestamp_interrupt_cfg(struct stmmac_priv * priv,bool en)553 static void dwmac1000_timestamp_interrupt_cfg(struct stmmac_priv *priv, bool en)
554 {
555 void __iomem *ioaddr = priv->ioaddr;
556
557 u32 intr_mask = readl(ioaddr + GMAC_INT_MASK);
558
559 if (en)
560 intr_mask &= ~GMAC_INT_DISABLE_TIMESTAMP;
561 else
562 intr_mask |= GMAC_INT_DISABLE_TIMESTAMP;
563
564 writel(intr_mask, ioaddr + GMAC_INT_MASK);
565 }
566
dwmac1000_ptp_enable(struct ptp_clock_info * ptp,struct ptp_clock_request * rq,int on)567 int dwmac1000_ptp_enable(struct ptp_clock_info *ptp,
568 struct ptp_clock_request *rq, int on)
569 {
570 struct stmmac_priv *priv =
571 container_of(ptp, struct stmmac_priv, ptp_clock_ops);
572 void __iomem *ptpaddr = priv->ptpaddr;
573 int ret = -EOPNOTSUPP;
574 u32 tcr_val;
575
576 switch (rq->type) {
577 case PTP_CLK_REQ_EXTTS:
578 mutex_lock(&priv->aux_ts_lock);
579 tcr_val = readl(ptpaddr + PTP_TCR);
580
581 if (on) {
582 tcr_val |= GMAC_PTP_TCR_ATSEN0;
583 tcr_val |= GMAC_PTP_TCR_ATSFC;
584 priv->plat->flags |= STMMAC_FLAG_EXT_SNAPSHOT_EN;
585 } else {
586 tcr_val &= ~GMAC_PTP_TCR_ATSEN0;
587 priv->plat->flags &= ~STMMAC_FLAG_EXT_SNAPSHOT_EN;
588 }
589
590 netdev_dbg(priv->dev, "Auxiliary Snapshot %s.\n",
591 str_enabled_disabled(on));
592 writel(tcr_val, ptpaddr + PTP_TCR);
593
594 /* wait for auxts fifo clear to finish */
595 ret = readl_poll_timeout(ptpaddr + PTP_TCR, tcr_val,
596 !(tcr_val & GMAC_PTP_TCR_ATSFC),
597 10, 10000);
598
599 mutex_unlock(&priv->aux_ts_lock);
600
601 dwmac1000_timestamp_interrupt_cfg(priv, on);
602 break;
603
604 default:
605 break;
606 }
607
608 return ret;
609 }
610