drivers/net: Remove unnecessary returns from void function()s
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / net / stmmac / dwmac1000_core.c
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 "dwmac1000.h"
32
33 static void dwmac1000_core_init(unsigned long ioaddr)
34 {
35 u32 value = readl(ioaddr + GMAC_CONTROL);
36 value |= GMAC_CORE_INIT;
37 writel(value, ioaddr + GMAC_CONTROL);
38
39 /* STBus Bridge Configuration */
40 /*writel(0xc5608, ioaddr + 0x00007000);*/
41
42 /* Freeze MMC counters */
43 writel(0x8, ioaddr + GMAC_MMC_CTRL);
44 /* Mask GMAC interrupts */
45 writel(0x207, ioaddr + GMAC_INT_MASK);
46
47 #ifdef STMMAC_VLAN_TAG_USED
48 /* Tag detection without filtering */
49 writel(0x0, ioaddr + GMAC_VLAN_TAG);
50 #endif
51 }
52
53 static void dwmac1000_dump_regs(unsigned long ioaddr)
54 {
55 int i;
56 pr_info("\tDWMAC1000 regs (base addr = 0x%8x)\n", (unsigned int)ioaddr);
57
58 for (i = 0; i < 55; i++) {
59 int offset = i * 4;
60 pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
61 offset, readl(ioaddr + offset));
62 }
63 }
64
65 static void dwmac1000_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
66 unsigned int reg_n)
67 {
68 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
69 GMAC_ADDR_LOW(reg_n));
70 }
71
72 static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
73 unsigned int reg_n)
74 {
75 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
76 GMAC_ADDR_LOW(reg_n));
77 }
78
79 static void dwmac1000_set_filter(struct net_device *dev)
80 {
81 unsigned long ioaddr = dev->base_addr;
82 unsigned int value = 0;
83
84 CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
85 __func__, netdev_mc_count(dev), netdev_uc_count(dev));
86
87 if (dev->flags & IFF_PROMISC)
88 value = GMAC_FRAME_FILTER_PR;
89 else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
90 || (dev->flags & IFF_ALLMULTI)) {
91 value = GMAC_FRAME_FILTER_PM; /* pass all multi */
92 writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
93 writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
94 } else if (!netdev_mc_empty(dev)) {
95 u32 mc_filter[2];
96 struct netdev_hw_addr *ha;
97
98 /* Hash filter for multicast */
99 value = GMAC_FRAME_FILTER_HMC;
100
101 memset(mc_filter, 0, sizeof(mc_filter));
102 netdev_for_each_mc_addr(ha, dev) {
103 /* The upper 6 bits of the calculated CRC are used to
104 index the contens of the hash table */
105 int bit_nr =
106 bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26;
107 /* The most significant bit determines the register to
108 * use (H/L) while the other 5 bits determine the bit
109 * within the register. */
110 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
111 }
112 writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
113 writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
114 }
115
116 /* Handle multiple unicast addresses (perfect filtering)*/
117 if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES)
118 /* Switch to promiscuous mode is more than 16 addrs
119 are required */
120 value |= GMAC_FRAME_FILTER_PR;
121 else {
122 int reg = 1;
123 struct netdev_hw_addr *ha;
124
125 netdev_for_each_uc_addr(ha, dev) {
126 dwmac1000_set_umac_addr(ioaddr, ha->addr, reg);
127 reg++;
128 }
129 }
130
131 #ifdef FRAME_FILTER_DEBUG
132 /* Enable Receive all mode (to debug filtering_fail errors) */
133 value |= GMAC_FRAME_FILTER_RA;
134 #endif
135 writel(value, ioaddr + GMAC_FRAME_FILTER);
136
137 CHIP_DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
138 "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
139 readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
140 }
141
142 static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
143 unsigned int fc, unsigned int pause_time)
144 {
145 unsigned int flow = 0;
146
147 CHIP_DBG(KERN_DEBUG "GMAC Flow-Control:\n");
148 if (fc & FLOW_RX) {
149 CHIP_DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
150 flow |= GMAC_FLOW_CTRL_RFE;
151 }
152 if (fc & FLOW_TX) {
153 CHIP_DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
154 flow |= GMAC_FLOW_CTRL_TFE;
155 }
156
157 if (duplex) {
158 CHIP_DBG(KERN_DEBUG "\tduplex mode: PAUSE %d\n", pause_time);
159 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
160 }
161
162 writel(flow, ioaddr + GMAC_FLOW_CTRL);
163 }
164
165 static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode)
166 {
167 unsigned int pmt = 0;
168
169 if (mode == WAKE_MAGIC) {
170 CHIP_DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
171 pmt |= power_down | magic_pkt_en;
172 } else if (mode == WAKE_UCAST) {
173 CHIP_DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
174 pmt |= global_unicast;
175 }
176
177 writel(pmt, ioaddr + GMAC_PMT);
178 }
179
180
181 static void dwmac1000_irq_status(unsigned long ioaddr)
182 {
183 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
184
185 /* Not used events (e.g. MMC interrupts) are not handled. */
186 if ((intr_status & mmc_tx_irq))
187 CHIP_DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
188 readl(ioaddr + GMAC_MMC_TX_INTR));
189 if (unlikely(intr_status & mmc_rx_irq))
190 CHIP_DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
191 readl(ioaddr + GMAC_MMC_RX_INTR));
192 if (unlikely(intr_status & mmc_rx_csum_offload_irq))
193 CHIP_DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
194 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
195 if (unlikely(intr_status & pmt_irq)) {
196 CHIP_DBG(KERN_DEBUG "GMAC: received Magic frame\n");
197 /* clear the PMT bits 5 and 6 by reading the PMT
198 * status register. */
199 readl(ioaddr + GMAC_PMT);
200 }
201 }
202
203 struct stmmac_ops dwmac1000_ops = {
204 .core_init = dwmac1000_core_init,
205 .dump_regs = dwmac1000_dump_regs,
206 .host_irq_status = dwmac1000_irq_status,
207 .set_filter = dwmac1000_set_filter,
208 .flow_ctrl = dwmac1000_flow_ctrl,
209 .pmt = dwmac1000_pmt,
210 .set_umac_addr = dwmac1000_set_umac_addr,
211 .get_umac_addr = dwmac1000_get_umac_addr,
212 };
213
214 struct mac_device_info *dwmac1000_setup(unsigned long ioaddr)
215 {
216 struct mac_device_info *mac;
217 u32 uid = readl(ioaddr + GMAC_VERSION);
218
219 pr_info("\tDWMAC1000 - user ID: 0x%x, Synopsys ID: 0x%x\n",
220 ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
221
222 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
223
224 mac->mac = &dwmac1000_ops;
225 mac->dma = &dwmac1000_dma_ops;
226
227 mac->pmt = PMT_SUPPORTED;
228 mac->link.port = GMAC_CONTROL_PS;
229 mac->link.duplex = GMAC_CONTROL_DM;
230 mac->link.speed = GMAC_CONTROL_FES;
231 mac->mii.addr = GMAC_MII_ADDR;
232 mac->mii.data = GMAC_MII_DATA;
233
234 return mac;
235 }