• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2   This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3   DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
4   developing this code.
5 
6   This only implements the mac core functions for this chip.
7 
8   Copyright (C) 2007-2009  STMicroelectronics Ltd
9 
10   This program is free software; you can redistribute it and/or modify it
11   under the terms and conditions of the GNU General Public License,
12   version 2, as published by the Free Software Foundation.
13 
14   This program is distributed in the hope it will be useful, but WITHOUT
15   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17   more details.
18 
19   You should have received a copy of the GNU General Public License along with
20   this program; if not, write to the Free Software Foundation, Inc.,
21   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22 
23   The full GNU General Public License is included in this distribution in
24   the file called "COPYING".
25 
26   Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
27 *******************************************************************************/
28 
29 #include <linux/crc32.h>
30 #include <linux/slab.h>
31 #include <linux/ethtool.h>
32 #include <asm/io.h>
33 #include "dwmac1000.h"
34 
dwmac1000_core_init(struct mac_device_info * hw,int mtu)35 static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
36 {
37 	void __iomem *ioaddr = hw->pcsr;
38 	u32 value = readl(ioaddr + GMAC_CONTROL);
39 	value |= GMAC_CORE_INIT;
40 	if (mtu > 1500)
41 		value |= GMAC_CONTROL_2K;
42 	if (mtu > 2000)
43 		value |= GMAC_CONTROL_JE;
44 
45 	writel(value, ioaddr + GMAC_CONTROL);
46 
47 	/* Mask GMAC interrupts */
48 	writel(0x207, ioaddr + GMAC_INT_MASK);
49 
50 #ifdef STMMAC_VLAN_TAG_USED
51 	/* Tag detection without filtering */
52 	writel(0x0, ioaddr + GMAC_VLAN_TAG);
53 #endif
54 }
55 
dwmac1000_rx_ipc_enable(struct mac_device_info * hw)56 static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
57 {
58 	void __iomem *ioaddr = hw->pcsr;
59 	u32 value = readl(ioaddr + GMAC_CONTROL);
60 
61 	if (hw->rx_csum)
62 		value |= GMAC_CONTROL_IPC;
63 	else
64 		value &= ~GMAC_CONTROL_IPC;
65 
66 	writel(value, ioaddr + GMAC_CONTROL);
67 
68 	value = readl(ioaddr + GMAC_CONTROL);
69 
70 	return !!(value & GMAC_CONTROL_IPC);
71 }
72 
dwmac1000_dump_regs(struct mac_device_info * hw)73 static void dwmac1000_dump_regs(struct mac_device_info *hw)
74 {
75 	void __iomem *ioaddr = hw->pcsr;
76 	int i;
77 	pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
78 
79 	for (i = 0; i < 55; i++) {
80 		int offset = i * 4;
81 		pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
82 			offset, readl(ioaddr + offset));
83 	}
84 }
85 
dwmac1000_set_umac_addr(struct mac_device_info * hw,unsigned char * addr,unsigned int reg_n)86 static void dwmac1000_set_umac_addr(struct mac_device_info *hw,
87 				    unsigned char *addr,
88 				    unsigned int reg_n)
89 {
90 	void __iomem *ioaddr = hw->pcsr;
91 	stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
92 			    GMAC_ADDR_LOW(reg_n));
93 }
94 
dwmac1000_get_umac_addr(struct mac_device_info * hw,unsigned char * addr,unsigned int reg_n)95 static void dwmac1000_get_umac_addr(struct mac_device_info *hw,
96 				    unsigned char *addr,
97 				    unsigned int reg_n)
98 {
99 	void __iomem *ioaddr = hw->pcsr;
100 	stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
101 			    GMAC_ADDR_LOW(reg_n));
102 }
103 
dwmac1000_set_mchash(void __iomem * ioaddr,u32 * mcfilterbits,int mcbitslog2)104 static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
105 				 int mcbitslog2)
106 {
107 	int numhashregs, regs;
108 
109 	switch (mcbitslog2) {
110 	case 6:
111 		writel(mcfilterbits[0], ioaddr + GMAC_HASH_LOW);
112 		writel(mcfilterbits[1], ioaddr + GMAC_HASH_HIGH);
113 		return;
114 		break;
115 	case 7:
116 		numhashregs = 4;
117 		break;
118 	case 8:
119 		numhashregs = 8;
120 		break;
121 	default:
122 		pr_debug("STMMAC: err in setting mulitcast filter\n");
123 		return;
124 		break;
125 	}
126 	for (regs = 0; regs < numhashregs; regs++)
127 		writel(mcfilterbits[regs],
128 		       ioaddr + GMAC_EXTHASH_BASE + regs * 4);
129 }
130 
dwmac1000_set_filter(struct mac_device_info * hw,struct net_device * dev)131 static void dwmac1000_set_filter(struct mac_device_info *hw,
132 				 struct net_device *dev)
133 {
134 	void __iomem *ioaddr = (void __iomem *)dev->base_addr;
135 	unsigned int value = 0;
136 	unsigned int perfect_addr_number = hw->unicast_filter_entries;
137 	u32 mc_filter[8];
138 	int mcbitslog2 = hw->mcast_bits_log2;
139 
140 	pr_debug("%s: # mcasts %d, # unicast %d\n", __func__,
141 		 netdev_mc_count(dev), netdev_uc_count(dev));
142 
143 	memset(mc_filter, 0, sizeof(mc_filter));
144 
145 	if (dev->flags & IFF_PROMISC) {
146 		value = GMAC_FRAME_FILTER_PR;
147 	} else if (dev->flags & IFF_ALLMULTI) {
148 		value = GMAC_FRAME_FILTER_PM;	/* pass all multi */
149 	} else if (!netdev_mc_empty(dev) && (mcbitslog2 == 0)) {
150 		/* Fall back to all multicast if we've no filter */
151 		value = GMAC_FRAME_FILTER_PM;
152 	} else if (!netdev_mc_empty(dev)) {
153 		struct netdev_hw_addr *ha;
154 
155 		/* Hash filter for multicast */
156 		value = GMAC_FRAME_FILTER_HMC;
157 
158 		netdev_for_each_mc_addr(ha, dev) {
159 			/* The upper n bits of the calculated CRC are used to
160 			 * index the contents of the hash table. The number of
161 			 * bits used depends on the hardware configuration
162 			 * selected at core configuration time.
163 			 */
164 			int bit_nr = bitrev32(~crc32_le(~0, ha->addr,
165 					      ETH_ALEN)) >>
166 					      (32 - mcbitslog2);
167 			/* The most significant bit determines the register to
168 			 * use (H/L) while the other 5 bits determine the bit
169 			 * within the register.
170 			 */
171 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
172 		}
173 	}
174 
175 	dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2);
176 
177 	/* Handle multiple unicast addresses (perfect filtering) */
178 	if (netdev_uc_count(dev) > perfect_addr_number)
179 		/* Switch to promiscuous mode if more than unicast
180 		 * addresses are requested than supported by hardware.
181 		 */
182 		value |= GMAC_FRAME_FILTER_PR;
183 	else {
184 		int reg = 1;
185 		struct netdev_hw_addr *ha;
186 
187 		netdev_for_each_uc_addr(ha, dev) {
188 			stmmac_set_mac_addr(ioaddr, ha->addr,
189 					    GMAC_ADDR_HIGH(reg),
190 					    GMAC_ADDR_LOW(reg));
191 			reg++;
192 		}
193 
194 		while (reg < perfect_addr_number) {
195 			writel(0, ioaddr + GMAC_ADDR_HIGH(reg));
196 			writel(0, ioaddr + GMAC_ADDR_LOW(reg));
197 			reg++;
198 		}
199 	}
200 
201 #ifdef FRAME_FILTER_DEBUG
202 	/* Enable Receive all mode (to debug filtering_fail errors) */
203 	value |= GMAC_FRAME_FILTER_RA;
204 #endif
205 	writel(value, ioaddr + GMAC_FRAME_FILTER);
206 }
207 
208 
dwmac1000_flow_ctrl(struct mac_device_info * hw,unsigned int duplex,unsigned int fc,unsigned int pause_time)209 static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
210 				unsigned int fc, unsigned int pause_time)
211 {
212 	void __iomem *ioaddr = hw->pcsr;
213 	/* Set flow such that DZPQ in Mac Register 6 is 0,
214 	 * and unicast pause detect is enabled.
215 	 */
216 	unsigned int flow = GMAC_FLOW_CTRL_UP;
217 
218 	pr_debug("GMAC Flow-Control:\n");
219 	if (fc & FLOW_RX) {
220 		pr_debug("\tReceive Flow-Control ON\n");
221 		flow |= GMAC_FLOW_CTRL_RFE;
222 	}
223 	if (fc & FLOW_TX) {
224 		pr_debug("\tTransmit Flow-Control ON\n");
225 		flow |= GMAC_FLOW_CTRL_TFE;
226 	}
227 
228 	if (duplex) {
229 		pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
230 		flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
231 	}
232 
233 	writel(flow, ioaddr + GMAC_FLOW_CTRL);
234 }
235 
dwmac1000_pmt(struct mac_device_info * hw,unsigned long mode)236 static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
237 {
238 	void __iomem *ioaddr = hw->pcsr;
239 	unsigned int pmt = 0;
240 
241 	if (mode & WAKE_MAGIC) {
242 		pr_debug("GMAC: WOL Magic frame\n");
243 		pmt |= power_down | magic_pkt_en;
244 	}
245 	if (mode & WAKE_UCAST) {
246 		pr_debug("GMAC: WOL on global unicast\n");
247 		pmt |= global_unicast;
248 	}
249 
250 	writel(pmt, ioaddr + GMAC_PMT);
251 }
252 
dwmac1000_irq_status(struct mac_device_info * hw,struct stmmac_extra_stats * x)253 static int dwmac1000_irq_status(struct mac_device_info *hw,
254 				struct stmmac_extra_stats *x)
255 {
256 	void __iomem *ioaddr = hw->pcsr;
257 	u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
258 	int ret = 0;
259 
260 	/* Not used events (e.g. MMC interrupts) are not handled. */
261 	if ((intr_status & mmc_tx_irq))
262 		x->mmc_tx_irq_n++;
263 	if (unlikely(intr_status & mmc_rx_irq))
264 		x->mmc_rx_irq_n++;
265 	if (unlikely(intr_status & mmc_rx_csum_offload_irq))
266 		x->mmc_rx_csum_offload_irq_n++;
267 	if (unlikely(intr_status & pmt_irq)) {
268 		/* clear the PMT bits 5 and 6 by reading the PMT status reg */
269 		readl(ioaddr + GMAC_PMT);
270 		x->irq_receive_pmt_irq_n++;
271 	}
272 	/* MAC trx/rx EEE LPI entry/exit interrupts */
273 	if (intr_status & lpiis_irq) {
274 		/* Clean LPI interrupt by reading the Reg 12 */
275 		ret = readl(ioaddr + LPI_CTRL_STATUS);
276 
277 		if (ret & LPI_CTRL_STATUS_TLPIEN)
278 			x->irq_tx_path_in_lpi_mode_n++;
279 		if (ret & LPI_CTRL_STATUS_TLPIEX)
280 			x->irq_tx_path_exit_lpi_mode_n++;
281 		if (ret & LPI_CTRL_STATUS_RLPIEN)
282 			x->irq_rx_path_in_lpi_mode_n++;
283 		if (ret & LPI_CTRL_STATUS_RLPIEX)
284 			x->irq_rx_path_exit_lpi_mode_n++;
285 	}
286 
287 	if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
288 		readl(ioaddr + GMAC_AN_STATUS);
289 		x->irq_pcs_ane_n++;
290 	}
291 	if (intr_status & rgmii_irq) {
292 		u32 status = readl(ioaddr + GMAC_S_R_GMII);
293 		x->irq_rgmii_n++;
294 
295 		/* Save and dump the link status. */
296 		if (status & GMAC_S_R_GMII_LINK) {
297 			int speed_value = (status & GMAC_S_R_GMII_SPEED) >>
298 			    GMAC_S_R_GMII_SPEED_SHIFT;
299 			x->pcs_duplex = (status & GMAC_S_R_GMII_MODE);
300 
301 			if (speed_value == GMAC_S_R_GMII_SPEED_125)
302 				x->pcs_speed = SPEED_1000;
303 			else if (speed_value == GMAC_S_R_GMII_SPEED_25)
304 				x->pcs_speed = SPEED_100;
305 			else
306 				x->pcs_speed = SPEED_10;
307 
308 			x->pcs_link = 1;
309 			pr_debug("%s: Link is Up - %d/%s\n", __func__,
310 				 (int)x->pcs_speed,
311 				 x->pcs_duplex ? "Full" : "Half");
312 		} else {
313 			x->pcs_link = 0;
314 			pr_debug("%s: Link is Down\n", __func__);
315 		}
316 	}
317 
318 	return ret;
319 }
320 
dwmac1000_set_eee_mode(struct mac_device_info * hw)321 static void dwmac1000_set_eee_mode(struct mac_device_info *hw)
322 {
323 	void __iomem *ioaddr = hw->pcsr;
324 	u32 value;
325 
326 	/* Enable the link status receive on RGMII, SGMII ore SMII
327 	 * receive path and instruct the transmit to enter in LPI
328 	 * state.
329 	 */
330 	value = readl(ioaddr + LPI_CTRL_STATUS);
331 	value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
332 	writel(value, ioaddr + LPI_CTRL_STATUS);
333 }
334 
dwmac1000_reset_eee_mode(struct mac_device_info * hw)335 static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
336 {
337 	void __iomem *ioaddr = hw->pcsr;
338 	u32 value;
339 
340 	value = readl(ioaddr + LPI_CTRL_STATUS);
341 	value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
342 	writel(value, ioaddr + LPI_CTRL_STATUS);
343 }
344 
dwmac1000_set_eee_pls(struct mac_device_info * hw,int link)345 static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
346 {
347 	void __iomem *ioaddr = hw->pcsr;
348 	u32 value;
349 
350 	value = readl(ioaddr + LPI_CTRL_STATUS);
351 
352 	if (link)
353 		value |= LPI_CTRL_STATUS_PLS;
354 	else
355 		value &= ~LPI_CTRL_STATUS_PLS;
356 
357 	writel(value, ioaddr + LPI_CTRL_STATUS);
358 }
359 
dwmac1000_set_eee_timer(struct mac_device_info * hw,int ls,int tw)360 static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
361 {
362 	void __iomem *ioaddr = hw->pcsr;
363 	int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
364 
365 	/* Program the timers in the LPI timer control register:
366 	 * LS: minimum time (ms) for which the link
367 	 *  status from PHY should be ok before transmitting
368 	 *  the LPI pattern.
369 	 * TW: minimum time (us) for which the core waits
370 	 *  after it has stopped transmitting the LPI pattern.
371 	 */
372 	writel(value, ioaddr + LPI_TIMER_CTRL);
373 }
374 
dwmac1000_ctrl_ane(struct mac_device_info * hw,bool restart)375 static void dwmac1000_ctrl_ane(struct mac_device_info *hw, bool restart)
376 {
377 	void __iomem *ioaddr = hw->pcsr;
378 	/* auto negotiation enable and External Loopback enable */
379 	u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
380 
381 	if (restart)
382 		value |= GMAC_AN_CTRL_RAN;
383 
384 	writel(value, ioaddr + GMAC_AN_CTRL);
385 }
386 
dwmac1000_get_adv(struct mac_device_info * hw,struct rgmii_adv * adv)387 static void dwmac1000_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv)
388 {
389 	void __iomem *ioaddr = hw->pcsr;
390 	u32 value = readl(ioaddr + GMAC_ANE_ADV);
391 
392 	if (value & GMAC_ANE_FD)
393 		adv->duplex = DUPLEX_FULL;
394 	if (value & GMAC_ANE_HD)
395 		adv->duplex |= DUPLEX_HALF;
396 
397 	adv->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
398 
399 	value = readl(ioaddr + GMAC_ANE_LPA);
400 
401 	if (value & GMAC_ANE_FD)
402 		adv->lp_duplex = DUPLEX_FULL;
403 	if (value & GMAC_ANE_HD)
404 		adv->lp_duplex = DUPLEX_HALF;
405 
406 	adv->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
407 }
408 
409 static const struct stmmac_ops dwmac1000_ops = {
410 	.core_init = dwmac1000_core_init,
411 	.rx_ipc = dwmac1000_rx_ipc_enable,
412 	.dump_regs = dwmac1000_dump_regs,
413 	.host_irq_status = dwmac1000_irq_status,
414 	.set_filter = dwmac1000_set_filter,
415 	.flow_ctrl = dwmac1000_flow_ctrl,
416 	.pmt = dwmac1000_pmt,
417 	.set_umac_addr = dwmac1000_set_umac_addr,
418 	.get_umac_addr = dwmac1000_get_umac_addr,
419 	.set_eee_mode = dwmac1000_set_eee_mode,
420 	.reset_eee_mode = dwmac1000_reset_eee_mode,
421 	.set_eee_timer = dwmac1000_set_eee_timer,
422 	.set_eee_pls = dwmac1000_set_eee_pls,
423 	.ctrl_ane = dwmac1000_ctrl_ane,
424 	.get_adv = dwmac1000_get_adv,
425 };
426 
dwmac1000_setup(void __iomem * ioaddr,int mcbins,int perfect_uc_entries)427 struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
428 					int perfect_uc_entries)
429 {
430 	struct mac_device_info *mac;
431 	u32 hwid = readl(ioaddr + GMAC_VERSION);
432 
433 	mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
434 	if (!mac)
435 		return NULL;
436 
437 	mac->pcsr = ioaddr;
438 	mac->multicast_filter_bins = mcbins;
439 	mac->unicast_filter_entries = perfect_uc_entries;
440 	mac->mcast_bits_log2 = 0;
441 
442 	if (mac->multicast_filter_bins)
443 		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
444 
445 	mac->mac = &dwmac1000_ops;
446 	mac->dma = &dwmac1000_dma_ops;
447 
448 	mac->link.port = GMAC_CONTROL_PS;
449 	mac->link.duplex = GMAC_CONTROL_DM;
450 	mac->link.speed = GMAC_CONTROL_FES;
451 	mac->mii.addr = GMAC_MII_ADDR;
452 	mac->mii.data = GMAC_MII_DATA;
453 	mac->synopsys_uid = hwid;
454 
455 	return mac;
456 }
457