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