xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c (revision 49bda4826843be0ef97a162009a29ea3a63f3935)
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