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
35static 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
56static 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
73static 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
86static 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
95static 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
104static 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
131static 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
200static 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	/* Set flow such that DZPQ in Mac Register 6 is 0,
205	 * and unicast pause detect is enabled.
206	 */
207	unsigned int flow = GMAC_FLOW_CTRL_UP;
208
209	pr_debug("GMAC Flow-Control:\n");
210	if (fc & FLOW_RX) {
211		pr_debug("\tReceive Flow-Control ON\n");
212		flow |= GMAC_FLOW_CTRL_RFE;
213	}
214	if (fc & FLOW_TX) {
215		pr_debug("\tTransmit Flow-Control ON\n");
216		flow |= GMAC_FLOW_CTRL_TFE;
217	}
218
219	if (duplex) {
220		pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
221		flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
222	}
223
224	writel(flow, ioaddr + GMAC_FLOW_CTRL);
225}
226
227static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
228{
229	void __iomem *ioaddr = hw->pcsr;
230	unsigned int pmt = 0;
231
232	if (mode & WAKE_MAGIC) {
233		pr_debug("GMAC: WOL Magic frame\n");
234		pmt |= power_down | magic_pkt_en;
235	}
236	if (mode & WAKE_UCAST) {
237		pr_debug("GMAC: WOL on global unicast\n");
238		pmt |= global_unicast;
239	}
240
241	writel(pmt, ioaddr + GMAC_PMT);
242}
243
244static int dwmac1000_irq_status(struct mac_device_info *hw,
245				struct stmmac_extra_stats *x)
246{
247	void __iomem *ioaddr = hw->pcsr;
248	u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
249	int ret = 0;
250
251	/* Not used events (e.g. MMC interrupts) are not handled. */
252	if ((intr_status & mmc_tx_irq))
253		x->mmc_tx_irq_n++;
254	if (unlikely(intr_status & mmc_rx_irq))
255		x->mmc_rx_irq_n++;
256	if (unlikely(intr_status & mmc_rx_csum_offload_irq))
257		x->mmc_rx_csum_offload_irq_n++;
258	if (unlikely(intr_status & pmt_irq)) {
259		/* clear the PMT bits 5 and 6 by reading the PMT status reg */
260		readl(ioaddr + GMAC_PMT);
261		x->irq_receive_pmt_irq_n++;
262	}
263	/* MAC trx/rx EEE LPI entry/exit interrupts */
264	if (intr_status & lpiis_irq) {
265		/* Clean LPI interrupt by reading the Reg 12 */
266		ret = readl(ioaddr + LPI_CTRL_STATUS);
267
268		if (ret & LPI_CTRL_STATUS_TLPIEN)
269			x->irq_tx_path_in_lpi_mode_n++;
270		if (ret & LPI_CTRL_STATUS_TLPIEX)
271			x->irq_tx_path_exit_lpi_mode_n++;
272		if (ret & LPI_CTRL_STATUS_RLPIEN)
273			x->irq_rx_path_in_lpi_mode_n++;
274		if (ret & LPI_CTRL_STATUS_RLPIEX)
275			x->irq_rx_path_exit_lpi_mode_n++;
276	}
277
278	if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
279		readl(ioaddr + GMAC_AN_STATUS);
280		x->irq_pcs_ane_n++;
281	}
282	if (intr_status & rgmii_irq) {
283		u32 status = readl(ioaddr + GMAC_S_R_GMII);
284		x->irq_rgmii_n++;
285
286		/* Save and dump the link status. */
287		if (status & GMAC_S_R_GMII_LINK) {
288			int speed_value = (status & GMAC_S_R_GMII_SPEED) >>
289			    GMAC_S_R_GMII_SPEED_SHIFT;
290			x->pcs_duplex = (status & GMAC_S_R_GMII_MODE);
291
292			if (speed_value == GMAC_S_R_GMII_SPEED_125)
293				x->pcs_speed = SPEED_1000;
294			else if (speed_value == GMAC_S_R_GMII_SPEED_25)
295				x->pcs_speed = SPEED_100;
296			else
297				x->pcs_speed = SPEED_10;
298
299			x->pcs_link = 1;
300			pr_debug("%s: Link is Up - %d/%s\n", __func__,
301				 (int)x->pcs_speed,
302				 x->pcs_duplex ? "Full" : "Half");
303		} else {
304			x->pcs_link = 0;
305			pr_debug("%s: Link is Down\n", __func__);
306		}
307	}
308
309	return ret;
310}
311
312static void dwmac1000_set_eee_mode(struct mac_device_info *hw)
313{
314	void __iomem *ioaddr = hw->pcsr;
315	u32 value;
316
317	/* Enable the link status receive on RGMII, SGMII ore SMII
318	 * receive path and instruct the transmit to enter in LPI
319	 * state.
320	 */
321	value = readl(ioaddr + LPI_CTRL_STATUS);
322	value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
323	writel(value, ioaddr + LPI_CTRL_STATUS);
324}
325
326static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
327{
328	void __iomem *ioaddr = hw->pcsr;
329	u32 value;
330
331	value = readl(ioaddr + LPI_CTRL_STATUS);
332	value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
333	writel(value, ioaddr + LPI_CTRL_STATUS);
334}
335
336static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
337{
338	void __iomem *ioaddr = hw->pcsr;
339	u32 value;
340
341	value = readl(ioaddr + LPI_CTRL_STATUS);
342
343	if (link)
344		value |= LPI_CTRL_STATUS_PLS;
345	else
346		value &= ~LPI_CTRL_STATUS_PLS;
347
348	writel(value, ioaddr + LPI_CTRL_STATUS);
349}
350
351static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
352{
353	void __iomem *ioaddr = hw->pcsr;
354	int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
355
356	/* Program the timers in the LPI timer control register:
357	 * LS: minimum time (ms) for which the link
358	 *  status from PHY should be ok before transmitting
359	 *  the LPI pattern.
360	 * TW: minimum time (us) for which the core waits
361	 *  after it has stopped transmitting the LPI pattern.
362	 */
363	writel(value, ioaddr + LPI_TIMER_CTRL);
364}
365
366static void dwmac1000_ctrl_ane(struct mac_device_info *hw, bool restart)
367{
368	void __iomem *ioaddr = hw->pcsr;
369	/* auto negotiation enable and External Loopback enable */
370	u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
371
372	if (restart)
373		value |= GMAC_AN_CTRL_RAN;
374
375	writel(value, ioaddr + GMAC_AN_CTRL);
376}
377
378static void dwmac1000_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv)
379{
380	void __iomem *ioaddr = hw->pcsr;
381	u32 value = readl(ioaddr + GMAC_ANE_ADV);
382
383	if (value & GMAC_ANE_FD)
384		adv->duplex = DUPLEX_FULL;
385	if (value & GMAC_ANE_HD)
386		adv->duplex |= DUPLEX_HALF;
387
388	adv->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
389
390	value = readl(ioaddr + GMAC_ANE_LPA);
391
392	if (value & GMAC_ANE_FD)
393		adv->lp_duplex = DUPLEX_FULL;
394	if (value & GMAC_ANE_HD)
395		adv->lp_duplex = DUPLEX_HALF;
396
397	adv->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
398}
399
400static const struct stmmac_ops dwmac1000_ops = {
401	.core_init = dwmac1000_core_init,
402	.rx_ipc = dwmac1000_rx_ipc_enable,
403	.dump_regs = dwmac1000_dump_regs,
404	.host_irq_status = dwmac1000_irq_status,
405	.set_filter = dwmac1000_set_filter,
406	.flow_ctrl = dwmac1000_flow_ctrl,
407	.pmt = dwmac1000_pmt,
408	.set_umac_addr = dwmac1000_set_umac_addr,
409	.get_umac_addr = dwmac1000_get_umac_addr,
410	.set_eee_mode = dwmac1000_set_eee_mode,
411	.reset_eee_mode = dwmac1000_reset_eee_mode,
412	.set_eee_timer = dwmac1000_set_eee_timer,
413	.set_eee_pls = dwmac1000_set_eee_pls,
414	.ctrl_ane = dwmac1000_ctrl_ane,
415	.get_adv = dwmac1000_get_adv,
416};
417
418struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
419					int perfect_uc_entries)
420{
421	struct mac_device_info *mac;
422	u32 hwid = readl(ioaddr + GMAC_VERSION);
423
424	mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
425	if (!mac)
426		return NULL;
427
428	mac->pcsr = ioaddr;
429	mac->multicast_filter_bins = mcbins;
430	mac->unicast_filter_entries = perfect_uc_entries;
431	mac->mcast_bits_log2 = 0;
432
433	if (mac->multicast_filter_bins)
434		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
435
436	mac->mac = &dwmac1000_ops;
437	mac->dma = &dwmac1000_dma_ops;
438
439	mac->link.port = GMAC_CONTROL_PS;
440	mac->link.duplex = GMAC_CONTROL_DM;
441	mac->link.speed = GMAC_CONTROL_FES;
442	mac->mii.addr = GMAC_MII_ADDR;
443	mac->mii.data = GMAC_MII_DATA;
444	mac->synopsys_uid = hwid;
445
446	return mac;
447}
448