xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c (revision e72e9e6933071fbbb3076811d3a0cc20e8720a5b)
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(void __iomem * ioaddr,bool ane,bool srgmi_ral,bool loopback)396 static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral,
397 			       bool loopback)
398 {
399 	dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback);
400 }
401 
dwmac1000_get_adv_lp(void __iomem * ioaddr,struct rgmii_adv * adv)402 static void dwmac1000_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv)
403 {
404 	dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv);
405 }
406 
dwmac1000_debug(struct stmmac_priv * priv,void __iomem * ioaddr,struct stmmac_extra_stats * x,u32 rx_queues,u32 tx_queues)407 static void dwmac1000_debug(struct stmmac_priv *priv, void __iomem *ioaddr,
408 			    struct stmmac_extra_stats *x,
409 			    u32 rx_queues, u32 tx_queues)
410 {
411 	u32 value = readl(ioaddr + GMAC_DEBUG);
412 
413 	if (value & GMAC_DEBUG_TXSTSFSTS)
414 		x->mtl_tx_status_fifo_full++;
415 	if (value & GMAC_DEBUG_TXFSTS)
416 		x->mtl_tx_fifo_not_empty++;
417 	if (value & GMAC_DEBUG_TWCSTS)
418 		x->mmtl_fifo_ctrl++;
419 	if (value & GMAC_DEBUG_TRCSTS_MASK) {
420 		u32 trcsts = (value & GMAC_DEBUG_TRCSTS_MASK)
421 			     >> GMAC_DEBUG_TRCSTS_SHIFT;
422 		if (trcsts == GMAC_DEBUG_TRCSTS_WRITE)
423 			x->mtl_tx_fifo_read_ctrl_write++;
424 		else if (trcsts == GMAC_DEBUG_TRCSTS_TXW)
425 			x->mtl_tx_fifo_read_ctrl_wait++;
426 		else if (trcsts == GMAC_DEBUG_TRCSTS_READ)
427 			x->mtl_tx_fifo_read_ctrl_read++;
428 		else
429 			x->mtl_tx_fifo_read_ctrl_idle++;
430 	}
431 	if (value & GMAC_DEBUG_TXPAUSED)
432 		x->mac_tx_in_pause++;
433 	if (value & GMAC_DEBUG_TFCSTS_MASK) {
434 		u32 tfcsts = (value & GMAC_DEBUG_TFCSTS_MASK)
435 			      >> GMAC_DEBUG_TFCSTS_SHIFT;
436 
437 		if (tfcsts == GMAC_DEBUG_TFCSTS_XFER)
438 			x->mac_tx_frame_ctrl_xfer++;
439 		else if (tfcsts == GMAC_DEBUG_TFCSTS_GEN_PAUSE)
440 			x->mac_tx_frame_ctrl_pause++;
441 		else if (tfcsts == GMAC_DEBUG_TFCSTS_WAIT)
442 			x->mac_tx_frame_ctrl_wait++;
443 		else
444 			x->mac_tx_frame_ctrl_idle++;
445 	}
446 	if (value & GMAC_DEBUG_TPESTS)
447 		x->mac_gmii_tx_proto_engine++;
448 	if (value & GMAC_DEBUG_RXFSTS_MASK) {
449 		u32 rxfsts = (value & GMAC_DEBUG_RXFSTS_MASK)
450 			     >> GMAC_DEBUG_RRCSTS_SHIFT;
451 
452 		if (rxfsts == GMAC_DEBUG_RXFSTS_FULL)
453 			x->mtl_rx_fifo_fill_level_full++;
454 		else if (rxfsts == GMAC_DEBUG_RXFSTS_AT)
455 			x->mtl_rx_fifo_fill_above_thresh++;
456 		else if (rxfsts == GMAC_DEBUG_RXFSTS_BT)
457 			x->mtl_rx_fifo_fill_below_thresh++;
458 		else
459 			x->mtl_rx_fifo_fill_level_empty++;
460 	}
461 	if (value & GMAC_DEBUG_RRCSTS_MASK) {
462 		u32 rrcsts = (value & GMAC_DEBUG_RRCSTS_MASK) >>
463 			     GMAC_DEBUG_RRCSTS_SHIFT;
464 
465 		if (rrcsts == GMAC_DEBUG_RRCSTS_FLUSH)
466 			x->mtl_rx_fifo_read_ctrl_flush++;
467 		else if (rrcsts == GMAC_DEBUG_RRCSTS_RSTAT)
468 			x->mtl_rx_fifo_read_ctrl_read_data++;
469 		else if (rrcsts == GMAC_DEBUG_RRCSTS_RDATA)
470 			x->mtl_rx_fifo_read_ctrl_status++;
471 		else
472 			x->mtl_rx_fifo_read_ctrl_idle++;
473 	}
474 	if (value & GMAC_DEBUG_RWCSTS)
475 		x->mtl_rx_fifo_ctrl_active++;
476 	if (value & GMAC_DEBUG_RFCFCSTS_MASK)
477 		x->mac_rx_frame_ctrl_fifo = (value & GMAC_DEBUG_RFCFCSTS_MASK)
478 					    >> GMAC_DEBUG_RFCFCSTS_SHIFT;
479 	if (value & GMAC_DEBUG_RPESTS)
480 		x->mac_gmii_rx_proto_engine++;
481 }
482 
dwmac1000_set_mac_loopback(void __iomem * ioaddr,bool enable)483 static void dwmac1000_set_mac_loopback(void __iomem *ioaddr, bool enable)
484 {
485 	u32 value = readl(ioaddr + GMAC_CONTROL);
486 
487 	if (enable)
488 		value |= GMAC_CONTROL_LM;
489 	else
490 		value &= ~GMAC_CONTROL_LM;
491 
492 	writel(value, ioaddr + GMAC_CONTROL);
493 }
494 
495 const struct stmmac_ops dwmac1000_ops = {
496 	.core_init = dwmac1000_core_init,
497 	.set_mac = stmmac_set_mac,
498 	.rx_ipc = dwmac1000_rx_ipc_enable,
499 	.dump_regs = dwmac1000_dump_regs,
500 	.host_irq_status = dwmac1000_irq_status,
501 	.set_filter = dwmac1000_set_filter,
502 	.flow_ctrl = dwmac1000_flow_ctrl,
503 	.pmt = dwmac1000_pmt,
504 	.set_umac_addr = dwmac1000_set_umac_addr,
505 	.get_umac_addr = dwmac1000_get_umac_addr,
506 	.set_lpi_mode = dwmac1000_set_lpi_mode,
507 	.set_eee_timer = dwmac1000_set_eee_timer,
508 	.set_eee_pls = dwmac1000_set_eee_pls,
509 	.debug = dwmac1000_debug,
510 	.pcs_ctrl_ane = dwmac1000_ctrl_ane,
511 	.pcs_get_adv_lp = dwmac1000_get_adv_lp,
512 	.set_mac_loopback = dwmac1000_set_mac_loopback,
513 };
514 
dwmac1000_setup(struct stmmac_priv * priv)515 int dwmac1000_setup(struct stmmac_priv *priv)
516 {
517 	struct mac_device_info *mac = priv->hw;
518 
519 	dev_info(priv->device, "\tDWMAC1000\n");
520 
521 	priv->dev->priv_flags |= IFF_UNICAST_FLT;
522 	mac->pcsr = priv->ioaddr;
523 	mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
524 	mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
525 	mac->mcast_bits_log2 = 0;
526 
527 	if (mac->multicast_filter_bins)
528 		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
529 
530 	mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
531 			 MAC_10 | MAC_100 | MAC_1000;
532 	mac->link.duplex = GMAC_CONTROL_DM;
533 	mac->link.speed10 = GMAC_CONTROL_PS;
534 	mac->link.speed100 = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
535 	mac->link.speed1000 = 0;
536 	mac->link.speed_mask = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
537 	mac->mii.addr = GMAC_MII_ADDR;
538 	mac->mii.data = GMAC_MII_DATA;
539 	mac->mii.addr_shift = 11;
540 	mac->mii.addr_mask = 0x0000F800;
541 	mac->mii.reg_shift = 6;
542 	mac->mii.reg_mask = 0x000007C0;
543 	mac->mii.clk_csr_shift = 2;
544 	mac->mii.clk_csr_mask = GENMASK(5, 2);
545 
546 	return 0;
547 }
548 
549 /* DWMAC 1000 HW Timestaming ops */
550 
dwmac1000_get_ptptime(void __iomem * ptpaddr,u64 * ptp_time)551 void dwmac1000_get_ptptime(void __iomem *ptpaddr, u64 *ptp_time)
552 {
553 	u64 ns;
554 
555 	ns = readl(ptpaddr + GMAC_PTP_ATNR);
556 	ns += (u64)readl(ptpaddr + GMAC_PTP_ATSR) * NSEC_PER_SEC;
557 
558 	*ptp_time = ns;
559 }
560 
dwmac1000_timestamp_interrupt(struct stmmac_priv * priv)561 void dwmac1000_timestamp_interrupt(struct stmmac_priv *priv)
562 {
563 	struct ptp_clock_event event;
564 	u32 ts_status, num_snapshot;
565 	unsigned long flags;
566 	u64 ptp_time;
567 	int i;
568 
569 	/* Clears the timestamp interrupt */
570 	ts_status = readl(priv->ptpaddr + GMAC3_X_TIMESTAMP_STATUS);
571 
572 	if (!(priv->plat->flags & STMMAC_FLAG_EXT_SNAPSHOT_EN))
573 		return;
574 
575 	num_snapshot = (ts_status & GMAC3_X_ATSNS) >> GMAC3_X_ATSNS_SHIFT;
576 
577 	for (i = 0; i < num_snapshot; i++) {
578 		read_lock_irqsave(&priv->ptp_lock, flags);
579 		stmmac_get_ptptime(priv, priv->ptpaddr, &ptp_time);
580 		read_unlock_irqrestore(&priv->ptp_lock, flags);
581 
582 		event.type = PTP_CLOCK_EXTTS;
583 		event.index = 0;
584 		event.timestamp = ptp_time;
585 		ptp_clock_event(priv->ptp_clock, &event);
586 	}
587 }
588 
589 /* DWMAC 1000 ptp_clock_info ops */
590 
dwmac1000_timestamp_interrupt_cfg(struct stmmac_priv * priv,bool en)591 static void dwmac1000_timestamp_interrupt_cfg(struct stmmac_priv *priv, bool en)
592 {
593 	void __iomem *ioaddr = priv->ioaddr;
594 
595 	u32 intr_mask = readl(ioaddr + GMAC_INT_MASK);
596 
597 	if (en)
598 		intr_mask &= ~GMAC_INT_DISABLE_TIMESTAMP;
599 	else
600 		intr_mask |= GMAC_INT_DISABLE_TIMESTAMP;
601 
602 	writel(intr_mask, ioaddr + GMAC_INT_MASK);
603 }
604 
dwmac1000_ptp_enable(struct ptp_clock_info * ptp,struct ptp_clock_request * rq,int on)605 int dwmac1000_ptp_enable(struct ptp_clock_info *ptp,
606 			 struct ptp_clock_request *rq, int on)
607 {
608 	struct stmmac_priv *priv =
609 	    container_of(ptp, struct stmmac_priv, ptp_clock_ops);
610 	void __iomem *ptpaddr = priv->ptpaddr;
611 	int ret = -EOPNOTSUPP;
612 	u32 tcr_val;
613 
614 	switch (rq->type) {
615 	case PTP_CLK_REQ_EXTTS:
616 		mutex_lock(&priv->aux_ts_lock);
617 		tcr_val = readl(ptpaddr + PTP_TCR);
618 
619 		if (on) {
620 			tcr_val |= GMAC_PTP_TCR_ATSEN0;
621 			tcr_val |= GMAC_PTP_TCR_ATSFC;
622 			priv->plat->flags |= STMMAC_FLAG_EXT_SNAPSHOT_EN;
623 		} else {
624 			tcr_val &= ~GMAC_PTP_TCR_ATSEN0;
625 			priv->plat->flags &= ~STMMAC_FLAG_EXT_SNAPSHOT_EN;
626 		}
627 
628 		netdev_dbg(priv->dev, "Auxiliary Snapshot %s.\n",
629 			   str_enabled_disabled(on));
630 		writel(tcr_val, ptpaddr + PTP_TCR);
631 
632 		/* wait for auxts fifo clear to finish */
633 		ret = readl_poll_timeout(ptpaddr + PTP_TCR, tcr_val,
634 					 !(tcr_val & GMAC_PTP_TCR_ATSFC),
635 					 10, 10000);
636 
637 		mutex_unlock(&priv->aux_ts_lock);
638 
639 		dwmac1000_timestamp_interrupt_cfg(priv, on);
640 		break;
641 
642 	default:
643 		break;
644 	}
645 
646 	return ret;
647 }
648