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