net: pxa168_eth: PXA168_ETH should depend on HAS_DMA
[deliverable/linux.git] / drivers / net / ethernet / stmicro / stmmac / dwmac1000_core.c
CommitLineData
21d437cc
GC
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>
5a0e3ad6 30#include <linux/slab.h>
e58bb43f 31#include <linux/ethtool.h>
b7f080cf 32#include <asm/io.h>
21d437cc
GC
33#include "dwmac1000.h"
34
7ed24bbe 35static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
21d437cc 36{
7ed24bbe 37 void __iomem *ioaddr = hw->pcsr;
21d437cc
GC
38 u32 value = readl(ioaddr + GMAC_CONTROL);
39 value |= GMAC_CORE_INIT;
2618abb7
VB
40 if (mtu > 1500)
41 value |= GMAC_CONTROL_2K;
42 if (mtu > 2000)
43 value |= GMAC_CONTROL_JE;
44
21d437cc
GC
45 writel(value, ioaddr + GMAC_CONTROL);
46
21d437cc
GC
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
21d437cc
GC
54}
55
7ed24bbe 56static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
ebbb293f 57{
7ed24bbe 58 void __iomem *ioaddr = hw->pcsr;
ebbb293f
GC
59 u32 value = readl(ioaddr + GMAC_CONTROL);
60
d2afb5bd
GC
61 if (hw->rx_csum)
62 value |= GMAC_CONTROL_IPC;
63 else
64 value &= ~GMAC_CONTROL_IPC;
65
ebbb293f
GC
66 writel(value, ioaddr + GMAC_CONTROL);
67
68 value = readl(ioaddr + GMAC_CONTROL);
69
70 return !!(value & GMAC_CONTROL_IPC);
71}
72
7ed24bbe 73static void dwmac1000_dump_regs(struct mac_device_info *hw)
21d437cc 74{
7ed24bbe 75 void __iomem *ioaddr = hw->pcsr;
21d437cc 76 int i;
1f0f6388 77 pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
21d437cc
GC
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 }
21d437cc
GC
84}
85
7ed24bbe
VB
86static void dwmac1000_set_umac_addr(struct mac_device_info *hw,
87 unsigned char *addr,
ceb69499 88 unsigned int reg_n)
21d437cc 89{
7ed24bbe 90 void __iomem *ioaddr = hw->pcsr;
21d437cc 91 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
ceb69499 92 GMAC_ADDR_LOW(reg_n));
21d437cc
GC
93}
94
7ed24bbe
VB
95static void dwmac1000_get_umac_addr(struct mac_device_info *hw,
96 unsigned char *addr,
ceb69499 97 unsigned int reg_n)
21d437cc 98{
7ed24bbe 99 void __iomem *ioaddr = hw->pcsr;
21d437cc 100 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
ceb69499 101 GMAC_ADDR_LOW(reg_n));
21d437cc
GC
102}
103
3b57de95
VB
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)
21d437cc 133{
ceb69499 134 void __iomem *ioaddr = (void __iomem *)dev->base_addr;
21d437cc 135 unsigned int value = 0;
3b57de95 136 unsigned int perfect_addr_number = hw->unicast_filter_entries;
aefef4c1 137 u32 mc_filter[2];
3b57de95 138 int mcbitslog2 = hw->mcast_bits_log2;
21d437cc 139
83d7af64
GC
140 pr_debug("%s: # mcasts %d, # unicast %d\n", __func__,
141 netdev_mc_count(dev), netdev_uc_count(dev));
21d437cc 142
aefef4c1
VB
143 memset(mc_filter, 0, sizeof(mc_filter));
144
145 if (dev->flags & IFF_PROMISC) {
21d437cc 146 value = GMAC_FRAME_FILTER_PR;
aefef4c1 147 } else if (dev->flags & IFF_ALLMULTI) {
21d437cc 148 value = GMAC_FRAME_FILTER_PM; /* pass all multi */
4cd24eaf 149 } else if (!netdev_mc_empty(dev)) {
22bedad3 150 struct netdev_hw_addr *ha;
21d437cc
GC
151
152 /* Hash filter for multicast */
153 value = GMAC_FRAME_FILTER_HMC;
154
22bedad3 155 netdev_for_each_mc_addr(ha, dev) {
3b57de95
VB
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.
ceb69499 160 */
3b57de95
VB
161 int bit_nr = bitrev32(~crc32_le(~0, ha->addr,
162 ETH_ALEN)) >>
163 (32 - mcbitslog2);
21d437cc
GC
164 /* The most significant bit determines the register to
165 * use (H/L) while the other 5 bits determine the bit
ceb69499
GC
166 * within the register.
167 */
21d437cc
GC
168 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
169 }
21d437cc
GC
170 }
171
3b57de95 172 dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2);
cffb13f4 173
ceb69499 174 /* Handle multiple unicast addresses (perfect filtering) */
cffb13f4 175 if (netdev_uc_count(dev) > perfect_addr_number)
3b57de95
VB
176 /* Switch to promiscuous mode if more than unicast
177 * addresses are requested than supported by hardware.
ceb69499 178 */
21d437cc
GC
179 value |= GMAC_FRAME_FILTER_PR;
180 else {
181 int reg = 1;
182 struct netdev_hw_addr *ha;
183
32e7bfc4 184 netdev_for_each_uc_addr(ha, dev) {
7ed24bbe
VB
185 stmmac_get_mac_addr(ioaddr, ha->addr,
186 GMAC_ADDR_HIGH(reg),
187 GMAC_ADDR_LOW(reg));
32e7bfc4 188 reg++;
21d437cc
GC
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);
21d437cc
GC
197}
198
7ed24bbe
VB
199
200static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
ceb69499 201 unsigned int fc, unsigned int pause_time)
21d437cc 202{
7ed24bbe 203 void __iomem *ioaddr = hw->pcsr;
21d437cc
GC
204 unsigned int flow = 0;
205
83d7af64 206 pr_debug("GMAC Flow-Control:\n");
21d437cc 207 if (fc & FLOW_RX) {
83d7af64 208 pr_debug("\tReceive Flow-Control ON\n");
21d437cc
GC
209 flow |= GMAC_FLOW_CTRL_RFE;
210 }
211 if (fc & FLOW_TX) {
83d7af64 212 pr_debug("\tTransmit Flow-Control ON\n");
21d437cc
GC
213 flow |= GMAC_FLOW_CTRL_TFE;
214 }
215
216 if (duplex) {
83d7af64 217 pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
21d437cc
GC
218 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
219 }
220
221 writel(flow, ioaddr + GMAC_FLOW_CTRL);
21d437cc
GC
222}
223
7ed24bbe 224static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
21d437cc 225{
7ed24bbe 226 void __iomem *ioaddr = hw->pcsr;
21d437cc
GC
227 unsigned int pmt = 0;
228
74ae2fd7 229 if (mode & WAKE_MAGIC) {
83d7af64 230 pr_debug("GMAC: WOL Magic frame\n");
21d437cc 231 pmt |= power_down | magic_pkt_en;
74ae2fd7
GC
232 }
233 if (mode & WAKE_UCAST) {
83d7af64 234 pr_debug("GMAC: WOL on global unicast\n");
21d437cc
GC
235 pmt |= global_unicast;
236 }
237
238 writel(pmt, ioaddr + GMAC_PMT);
21d437cc
GC
239}
240
7ed24bbe 241static int dwmac1000_irq_status(struct mac_device_info *hw,
0982a0f6 242 struct stmmac_extra_stats *x)
21d437cc 243{
7ed24bbe 244 void __iomem *ioaddr = hw->pcsr;
21d437cc 245 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
0982a0f6 246 int ret = 0;
21d437cc
GC
247
248 /* Not used events (e.g. MMC interrupts) are not handled. */
83d7af64 249 if ((intr_status & mmc_tx_irq))
0982a0f6 250 x->mmc_tx_irq_n++;
83d7af64 251 if (unlikely(intr_status & mmc_rx_irq))
0982a0f6 252 x->mmc_rx_irq_n++;
83d7af64 253 if (unlikely(intr_status & mmc_rx_csum_offload_irq))
0982a0f6 254 x->mmc_rx_csum_offload_irq_n++;
21d437cc 255 if (unlikely(intr_status & pmt_irq)) {
ceb69499 256 /* clear the PMT bits 5 and 6 by reading the PMT status reg */
21d437cc 257 readl(ioaddr + GMAC_PMT);
0982a0f6 258 x->irq_receive_pmt_irq_n++;
21d437cc 259 }
d765955d
GC
260 /* MAC trx/rx EEE LPI entry/exit interrupts */
261 if (intr_status & lpiis_irq) {
262 /* Clean LPI interrupt by reading the Reg 12 */
0982a0f6 263 ret = readl(ioaddr + LPI_CTRL_STATUS);
d765955d 264
83d7af64 265 if (ret & LPI_CTRL_STATUS_TLPIEN)
0982a0f6 266 x->irq_tx_path_in_lpi_mode_n++;
83d7af64 267 if (ret & LPI_CTRL_STATUS_TLPIEX)
0982a0f6 268 x->irq_tx_path_exit_lpi_mode_n++;
83d7af64 269 if (ret & LPI_CTRL_STATUS_RLPIEN)
0982a0f6 270 x->irq_rx_path_in_lpi_mode_n++;
83d7af64 271 if (ret & LPI_CTRL_STATUS_RLPIEX)
0982a0f6 272 x->irq_rx_path_exit_lpi_mode_n++;
d765955d
GC
273 }
274
0982a0f6 275 if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
0982a0f6
GC
276 readl(ioaddr + GMAC_AN_STATUS);
277 x->irq_pcs_ane_n++;
278 }
279 if (intr_status & rgmii_irq) {
ceb69499 280 u32 status = readl(ioaddr + GMAC_S_R_GMII);
0982a0f6 281 x->irq_rgmii_n++;
e58bb43f
GC
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) >>
ceb69499 286 GMAC_S_R_GMII_SPEED_SHIFT;
e58bb43f
GC
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;
83d7af64
GC
297 pr_debug("%s: Link is Up - %d/%s\n", __func__,
298 (int)x->pcs_speed,
e58bb43f
GC
299 x->pcs_duplex ? "Full" : "Half");
300 } else {
301 x->pcs_link = 0;
83d7af64 302 pr_debug("%s: Link is Down\n", __func__);
e58bb43f 303 }
0982a0f6
GC
304 }
305
306 return ret;
d765955d
GC
307}
308
7ed24bbe 309static void dwmac1000_set_eee_mode(struct mac_device_info *hw)
d765955d 310{
7ed24bbe 311 void __iomem *ioaddr = hw->pcsr;
d765955d
GC
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
ceb69499
GC
316 * state.
317 */
d765955d
GC
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
7ed24bbe 323static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
d765955d 324{
7ed24bbe 325 void __iomem *ioaddr = hw->pcsr;
d765955d
GC
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
7ed24bbe 333static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
d765955d 334{
7ed24bbe 335 void __iomem *ioaddr = hw->pcsr;
d765955d
GC
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
7ed24bbe 348static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
d765955d 349{
7ed24bbe 350 void __iomem *ioaddr = hw->pcsr;
d765955d
GC
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);
21d437cc
GC
361}
362
7ed24bbe 363static void dwmac1000_ctrl_ane(struct mac_device_info *hw, bool restart)
e58bb43f 364{
7ed24bbe 365 void __iomem *ioaddr = hw->pcsr;
e58bb43f 366 /* auto negotiation enable and External Loopback enable */
c8df8ce3 367 u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
e58bb43f
GC
368
369 if (restart)
370 value |= GMAC_AN_CTRL_RAN;
371
372 writel(value, ioaddr + GMAC_AN_CTRL);
373}
374
7ed24bbe 375static void dwmac1000_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv)
e58bb43f 376{
7ed24bbe 377 void __iomem *ioaddr = hw->pcsr;
e58bb43f
GC
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
cadb7924 397static const struct stmmac_ops dwmac1000_ops = {
21d437cc 398 .core_init = dwmac1000_core_init,
38912bdb 399 .rx_ipc = dwmac1000_rx_ipc_enable,
21d437cc
GC
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,
ceb69499
GC
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,
e58bb43f
GC
411 .ctrl_ane = dwmac1000_ctrl_ane,
412 .get_adv = dwmac1000_get_adv,
21d437cc
GC
413};
414
3b57de95
VB
415struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
416 int perfect_uc_entries)
21d437cc
GC
417{
418 struct mac_device_info *mac;
f0b9d786 419 u32 hwid = readl(ioaddr + GMAC_VERSION);
21d437cc
GC
420
421 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
1ff21906
DC
422 if (!mac)
423 return NULL;
21d437cc 424
7ed24bbe 425 mac->pcsr = ioaddr;
3b57de95
VB
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
21d437cc 433 mac->mac = &dwmac1000_ops;
21d437cc
GC
434 mac->dma = &dwmac1000_dma_ops;
435
21d437cc
GC
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;
f0b9d786 441 mac->synopsys_uid = hwid;
21d437cc
GC
442
443 return mac;
444}
This page took 0.772691 seconds and 5 git commands to generate.