• 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)) {
150 		struct netdev_hw_addr *ha;
151 
152 		/* Hash filter for multicast */
153 		value = GMAC_FRAME_FILTER_HMC;
154 
155 		netdev_for_each_mc_addr(ha, dev) {
156 			/* The upper n bits of the calculated CRC are used to
157 			 * index the contents of the hash table. The number of
158 			 * bits used depends on the hardware configuration
159 			 * selected at core configuration time.
160 			 */
161 			int bit_nr = bitrev32(~crc32_le(~0, ha->addr,
162 					      ETH_ALEN)) >>
163 					      (32 - mcbitslog2);
164 			/* The most significant bit determines the register to
165 			 * use (H/L) while the other 5 bits determine the bit
166 			 * within the register.
167 			 */
168 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
169 		}
170 	}
171 
172 	dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2);
173 
174 	/* Handle multiple unicast addresses (perfect filtering) */
175 	if (netdev_uc_count(dev) > perfect_addr_number)
176 		/* Switch to promiscuous mode if more than unicast
177 		 * addresses are requested than supported by hardware.
178 		 */
179 		value |= GMAC_FRAME_FILTER_PR;
180 	else {
181 		int reg = 1;
182 		struct netdev_hw_addr *ha;
183 
184 		netdev_for_each_uc_addr(ha, dev) {
185 			stmmac_set_mac_addr(ioaddr, ha->addr,
186 					    GMAC_ADDR_HIGH(reg),
187 					    GMAC_ADDR_LOW(reg));
188 			reg++;
189 		}
190 	}
191 
192 #ifdef FRAME_FILTER_DEBUG
193 	/* Enable Receive all mode (to debug filtering_fail errors) */
194 	value |= GMAC_FRAME_FILTER_RA;
195 #endif
196 	writel(value, ioaddr + GMAC_FRAME_FILTER);
197 }
198 
199 
dwmac1000_flow_ctrl(struct mac_device_info * hw,unsigned int duplex,unsigned int fc,unsigned int pause_time)200 static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
201 				unsigned int fc, unsigned int pause_time)
202 {
203 	void __iomem *ioaddr = hw->pcsr;
204 	unsigned int flow = 0;
205 
206 	pr_debug("GMAC Flow-Control:\n");
207 	if (fc & FLOW_RX) {
208 		pr_debug("\tReceive Flow-Control ON\n");
209 		flow |= GMAC_FLOW_CTRL_RFE;
210 	}
211 	if (fc & FLOW_TX) {
212 		pr_debug("\tTransmit Flow-Control ON\n");
213 		flow |= GMAC_FLOW_CTRL_TFE;
214 	}
215 
216 	if (duplex) {
217 		pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
218 		flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
219 	}
220 
221 	writel(flow, ioaddr + GMAC_FLOW_CTRL);
222 }
223 
dwmac1000_pmt(struct mac_device_info * hw,unsigned long mode)224 static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
225 {
226 	void __iomem *ioaddr = hw->pcsr;
227 	unsigned int pmt = 0;
228 
229 	if (mode & WAKE_MAGIC) {
230 		pr_debug("GMAC: WOL Magic frame\n");
231 		pmt |= power_down | magic_pkt_en;
232 	}
233 	if (mode & WAKE_UCAST) {
234 		pr_debug("GMAC: WOL on global unicast\n");
235 		pmt |= global_unicast;
236 	}
237 
238 	writel(pmt, ioaddr + GMAC_PMT);
239 }
240 
dwmac1000_irq_status(struct mac_device_info * hw,struct stmmac_extra_stats * x)241 static int dwmac1000_irq_status(struct mac_device_info *hw,
242 				struct stmmac_extra_stats *x)
243 {
244 	void __iomem *ioaddr = hw->pcsr;
245 	u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
246 	int ret = 0;
247 
248 	/* Not used events (e.g. MMC interrupts) are not handled. */
249 	if ((intr_status & mmc_tx_irq))
250 		x->mmc_tx_irq_n++;
251 	if (unlikely(intr_status & mmc_rx_irq))
252 		x->mmc_rx_irq_n++;
253 	if (unlikely(intr_status & mmc_rx_csum_offload_irq))
254 		x->mmc_rx_csum_offload_irq_n++;
255 	if (unlikely(intr_status & pmt_irq)) {
256 		/* clear the PMT bits 5 and 6 by reading the PMT status reg */
257 		readl(ioaddr + GMAC_PMT);
258 		x->irq_receive_pmt_irq_n++;
259 	}
260 	/* MAC trx/rx EEE LPI entry/exit interrupts */
261 	if (intr_status & lpiis_irq) {
262 		/* Clean LPI interrupt by reading the Reg 12 */
263 		ret = readl(ioaddr + LPI_CTRL_STATUS);
264 
265 		if (ret & LPI_CTRL_STATUS_TLPIEN)
266 			x->irq_tx_path_in_lpi_mode_n++;
267 		if (ret & LPI_CTRL_STATUS_TLPIEX)
268 			x->irq_tx_path_exit_lpi_mode_n++;
269 		if (ret & LPI_CTRL_STATUS_RLPIEN)
270 			x->irq_rx_path_in_lpi_mode_n++;
271 		if (ret & LPI_CTRL_STATUS_RLPIEX)
272 			x->irq_rx_path_exit_lpi_mode_n++;
273 	}
274 
275 	if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
276 		readl(ioaddr + GMAC_AN_STATUS);
277 		x->irq_pcs_ane_n++;
278 	}
279 	if (intr_status & rgmii_irq) {
280 		u32 status = readl(ioaddr + GMAC_S_R_GMII);
281 		x->irq_rgmii_n++;
282 
283 		/* Save and dump the link status. */
284 		if (status & GMAC_S_R_GMII_LINK) {
285 			int speed_value = (status & GMAC_S_R_GMII_SPEED) >>
286 			    GMAC_S_R_GMII_SPEED_SHIFT;
287 			x->pcs_duplex = (status & GMAC_S_R_GMII_MODE);
288 
289 			if (speed_value == GMAC_S_R_GMII_SPEED_125)
290 				x->pcs_speed = SPEED_1000;
291 			else if (speed_value == GMAC_S_R_GMII_SPEED_25)
292 				x->pcs_speed = SPEED_100;
293 			else
294 				x->pcs_speed = SPEED_10;
295 
296 			x->pcs_link = 1;
297 			pr_debug("%s: Link is Up - %d/%s\n", __func__,
298 				 (int)x->pcs_speed,
299 				 x->pcs_duplex ? "Full" : "Half");
300 		} else {
301 			x->pcs_link = 0;
302 			pr_debug("%s: Link is Down\n", __func__);
303 		}
304 	}
305 
306 	return ret;
307 }
308 
dwmac1000_set_eee_mode(struct mac_device_info * hw)309 static void dwmac1000_set_eee_mode(struct mac_device_info *hw)
310 {
311 	void __iomem *ioaddr = hw->pcsr;
312 	u32 value;
313 
314 	/* Enable the link status receive on RGMII, SGMII ore SMII
315 	 * receive path and instruct the transmit to enter in LPI
316 	 * state.
317 	 */
318 	value = readl(ioaddr + LPI_CTRL_STATUS);
319 	value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
320 	writel(value, ioaddr + LPI_CTRL_STATUS);
321 }
322 
dwmac1000_reset_eee_mode(struct mac_device_info * hw)323 static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
324 {
325 	void __iomem *ioaddr = hw->pcsr;
326 	u32 value;
327 
328 	value = readl(ioaddr + LPI_CTRL_STATUS);
329 	value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
330 	writel(value, ioaddr + LPI_CTRL_STATUS);
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 mac_device_info * hw,bool restart)363 static void dwmac1000_ctrl_ane(struct mac_device_info *hw, bool restart)
364 {
365 	void __iomem *ioaddr = hw->pcsr;
366 	/* auto negotiation enable and External Loopback enable */
367 	u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
368 
369 	if (restart)
370 		value |= GMAC_AN_CTRL_RAN;
371 
372 	writel(value, ioaddr + GMAC_AN_CTRL);
373 }
374 
dwmac1000_get_adv(struct mac_device_info * hw,struct rgmii_adv * adv)375 static void dwmac1000_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv)
376 {
377 	void __iomem *ioaddr = hw->pcsr;
378 	u32 value = readl(ioaddr + GMAC_ANE_ADV);
379 
380 	if (value & GMAC_ANE_FD)
381 		adv->duplex = DUPLEX_FULL;
382 	if (value & GMAC_ANE_HD)
383 		adv->duplex |= DUPLEX_HALF;
384 
385 	adv->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
386 
387 	value = readl(ioaddr + GMAC_ANE_LPA);
388 
389 	if (value & GMAC_ANE_FD)
390 		adv->lp_duplex = DUPLEX_FULL;
391 	if (value & GMAC_ANE_HD)
392 		adv->lp_duplex = DUPLEX_HALF;
393 
394 	adv->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
395 }
396 
397 static const struct stmmac_ops dwmac1000_ops = {
398 	.core_init = dwmac1000_core_init,
399 	.rx_ipc = dwmac1000_rx_ipc_enable,
400 	.dump_regs = dwmac1000_dump_regs,
401 	.host_irq_status = dwmac1000_irq_status,
402 	.set_filter = dwmac1000_set_filter,
403 	.flow_ctrl = dwmac1000_flow_ctrl,
404 	.pmt = dwmac1000_pmt,
405 	.set_umac_addr = dwmac1000_set_umac_addr,
406 	.get_umac_addr = dwmac1000_get_umac_addr,
407 	.set_eee_mode = dwmac1000_set_eee_mode,
408 	.reset_eee_mode = dwmac1000_reset_eee_mode,
409 	.set_eee_timer = dwmac1000_set_eee_timer,
410 	.set_eee_pls = dwmac1000_set_eee_pls,
411 	.ctrl_ane = dwmac1000_ctrl_ane,
412 	.get_adv = dwmac1000_get_adv,
413 };
414 
dwmac1000_setup(void __iomem * ioaddr,int mcbins,int perfect_uc_entries)415 struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
416 					int perfect_uc_entries)
417 {
418 	struct mac_device_info *mac;
419 	u32 hwid = readl(ioaddr + GMAC_VERSION);
420 
421 	mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
422 	if (!mac)
423 		return NULL;
424 
425 	mac->pcsr = ioaddr;
426 	mac->multicast_filter_bins = mcbins;
427 	mac->unicast_filter_entries = perfect_uc_entries;
428 	mac->mcast_bits_log2 = 0;
429 
430 	if (mac->multicast_filter_bins)
431 		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
432 
433 	mac->mac = &dwmac1000_ops;
434 	mac->dma = &dwmac1000_dma_ops;
435 
436 	mac->link.port = GMAC_CONTROL_PS;
437 	mac->link.duplex = GMAC_CONTROL_DM;
438 	mac->link.speed = GMAC_CONTROL_FES;
439 	mac->mii.addr = GMAC_MII_ADDR;
440 	mac->mii.data = GMAC_MII_DATA;
441 	mac->synopsys_uid = hwid;
442 
443 	return mac;
444 }
445