aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/stmmac
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2010-01-06 18:07:20 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-07 20:06:10 -0500
commit21d437cc66dcfd0119a4905214fbbe19f3e276dc (patch)
treea633c68d6ebd89ce2a55efb26040c6a6372e9416 /drivers/net/stmmac
parent7e848ae113ca7442ba6b44168fa2238224f37e8a (diff)
stmmac: rename the gmac as dwmac1000 and split core and dma parts
Use dwmac1000 naming instead of gmac. The patch also splits the gmac.c file in two new ones: dwmac1000_core.c and dwmac1000_dma.c. This could actually help on some architectures where different DMA engines are used. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/stmmac')
-rw-r--r--drivers/net/stmmac/Makefile5
-rw-r--r--drivers/net/stmmac/common.h2
-rw-r--r--drivers/net/stmmac/descs.h4
-rw-r--r--drivers/net/stmmac/dwmac1000.h (renamed from drivers/net/stmmac/gmac.h)19
-rw-r--r--drivers/net/stmmac/dwmac1000_core.c245
-rw-r--r--drivers/net/stmmac/dwmac1000_dma.c (renamed from drivers/net/stmmac/gmac.c)334
-rw-r--r--drivers/net/stmmac/stmmac_main.c2
7 files changed, 324 insertions, 287 deletions
diff --git a/drivers/net/stmmac/Makefile b/drivers/net/stmmac/Makefile
index 2ed83859fd59..c776af15fe1a 100644
--- a/drivers/net/stmmac/Makefile
+++ b/drivers/net/stmmac/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_STMMAC_ETH) += stmmac.o 1obj-$(CONFIG_STMMAC_ETH) += stmmac.o
2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o 2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
3stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o dwmac_lib.o \ 3stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
4 dwmac100.o gmac.o $(stmmac-y) 4 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
5 dwmac100.o $(stmmac-y)
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
index 987faaaa1920..25b53d411516 100644
--- a/drivers/net/stmmac/common.h
+++ b/drivers/net/stmmac/common.h
@@ -224,7 +224,7 @@ struct mac_device_info {
224 struct mac_link link; 224 struct mac_link link;
225}; 225};
226 226
227struct mac_device_info *gmac_setup(unsigned long addr); 227struct mac_device_info *dwmac1000_setup(unsigned long addr);
228struct mac_device_info *dwmac100_setup(unsigned long addr); 228struct mac_device_info *dwmac100_setup(unsigned long addr);
229 229
230extern void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6], 230extern void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
diff --git a/drivers/net/stmmac/descs.h b/drivers/net/stmmac/descs.h
index 6d2a0b2f5e57..63a03e264694 100644
--- a/drivers/net/stmmac/descs.h
+++ b/drivers/net/stmmac/descs.h
@@ -1,6 +1,6 @@
1/******************************************************************************* 1/*******************************************************************************
2 Header File to describe the DMA descriptors 2 Header File to describe the DMA descriptors.
3 Use enhanced descriptors in case of GMAC Cores. 3 Enhanced descriptors have been in case of DWMAC1000 Cores.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms and conditions of the GNU General Public License, 6 under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/stmmac/gmac.h b/drivers/net/stmmac/dwmac1000.h
index 2e82d6c9a148..3d54d6c99129 100644
--- a/drivers/net/stmmac/gmac.h
+++ b/drivers/net/stmmac/dwmac1000.h
@@ -20,6 +20,10 @@
20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
21*******************************************************************************/ 21*******************************************************************************/
22 22
23#include <linux/netdevice.h>
24#include <linux/phy.h>
25#include "common.h"
26
23#define GMAC_CONTROL 0x00000000 /* Configuration */ 27#define GMAC_CONTROL 0x00000000 /* Configuration */
24#define GMAC_FRAME_FILTER 0x00000004 /* Frame Filter */ 28#define GMAC_FRAME_FILTER 0x00000004 /* Frame Filter */
25#define GMAC_HASH_HIGH 0x00000008 /* Multicast Hash Table High */ 29#define GMAC_HASH_HIGH 0x00000008 /* Multicast Hash Table High */
@@ -32,7 +36,7 @@
32#define GMAC_WAKEUP_FILTER 0x00000028 /* Wake-up Frame Filter */ 36#define GMAC_WAKEUP_FILTER 0x00000028 /* Wake-up Frame Filter */
33 37
34#define GMAC_INT_STATUS 0x00000038 /* interrupt status register */ 38#define GMAC_INT_STATUS 0x00000038 /* interrupt status register */
35enum gmac_irq_status { 39enum dwmac1000_irq_status {
36 time_stamp_irq = 0x0200, 40 time_stamp_irq = 0x0200,
37 mmc_rx_csum_offload_irq = 0x0080, 41 mmc_rx_csum_offload_irq = 0x0080,
38 mmc_tx_irq = 0x0040, 42 mmc_tx_irq = 0x0040,
@@ -202,3 +206,16 @@ enum rtc_control {
202#define GMAC_MMC_RX_INTR 0x104 206#define GMAC_MMC_RX_INTR 0x104
203#define GMAC_MMC_TX_INTR 0x108 207#define GMAC_MMC_TX_INTR 0x108
204#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 208#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
209
210#undef DWMAC1000_DEBUG
211/* #define DWMAC1000__DEBUG */
212#undef FRAME_FILTER_DEBUG
213/* #define FRAME_FILTER_DEBUG */
214#ifdef DWMAC1000__DEBUG
215#define DBG(fmt, args...) printk(fmt, ## args)
216#else
217#define DBG(fmt, args...) do { } while (0)
218#endif
219
220extern struct stmmac_dma_ops dwmac1000_dma_ops;
221extern struct stmmac_desc_ops dwmac1000_desc_ops;
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
new file mode 100644
index 000000000000..928eac05b912
--- /dev/null
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -0,0 +1,245 @@
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 "dwmac1000.h"
31
32static void dwmac1000_core_init(unsigned long ioaddr)
33{
34 u32 value = readl(ioaddr + GMAC_CONTROL);
35 value |= GMAC_CORE_INIT;
36 writel(value, ioaddr + GMAC_CONTROL);
37
38 /* STBus Bridge Configuration */
39 /*writel(0xc5608, ioaddr + 0x00007000);*/
40
41 /* Freeze MMC counters */
42 writel(0x8, ioaddr + GMAC_MMC_CTRL);
43 /* Mask GMAC interrupts */
44 writel(0x207, ioaddr + GMAC_INT_MASK);
45
46#ifdef STMMAC_VLAN_TAG_USED
47 /* Tag detection without filtering */
48 writel(0x0, ioaddr + GMAC_VLAN_TAG);
49#endif
50 return;
51}
52
53static 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 return;
64}
65
66static void dwmac1000_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
67 unsigned int reg_n)
68{
69 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
70 GMAC_ADDR_LOW(reg_n));
71}
72
73static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
74 unsigned int reg_n)
75{
76 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
77 GMAC_ADDR_LOW(reg_n));
78}
79
80static void dwmac1000_set_filter(struct net_device *dev)
81{
82 unsigned long ioaddr = dev->base_addr;
83 unsigned int value = 0;
84
85 DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
86 __func__, dev->mc_count, dev->uc.count);
87
88 if (dev->flags & IFF_PROMISC)
89 value = GMAC_FRAME_FILTER_PR;
90 else if ((dev->mc_count > HASH_TABLE_SIZE)
91 || (dev->flags & IFF_ALLMULTI)) {
92 value = GMAC_FRAME_FILTER_PM; /* pass all multi */
93 writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
94 writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
95 } else if (dev->mc_count > 0) {
96 int i;
97 u32 mc_filter[2];
98 struct dev_mc_list *mclist;
99
100 /* Hash filter for multicast */
101 value = GMAC_FRAME_FILTER_HMC;
102
103 memset(mc_filter, 0, sizeof(mc_filter));
104 for (i = 0, mclist = dev->mc_list;
105 mclist && i < dev->mc_count; i++, mclist = mclist->next) {
106 /* The upper 6 bits of the calculated CRC are used to
107 index the contens of the hash table */
108 int bit_nr =
109 bitrev32(~crc32_le(~0, mclist->dmi_addr, 6)) >> 26;
110 /* The most significant bit determines the register to
111 * use (H/L) while the other 5 bits determine the bit
112 * within the register. */
113 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
114 }
115 writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
116 writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
117 }
118
119 /* Handle multiple unicast addresses (perfect filtering)*/
120 if (dev->uc.count > GMAC_MAX_UNICAST_ADDRESSES)
121 /* Switch to promiscuous mode is more than 16 addrs
122 are required */
123 value |= GMAC_FRAME_FILTER_PR;
124 else {
125 int reg = 1;
126 struct netdev_hw_addr *ha;
127
128 list_for_each_entry(ha, &dev->uc.list, list) {
129 dwmac1000_set_umac_addr(ioaddr, ha->addr, reg);
130 reg++;
131 }
132 }
133
134#ifdef FRAME_FILTER_DEBUG
135 /* Enable Receive all mode (to debug filtering_fail errors) */
136 value |= GMAC_FRAME_FILTER_RA;
137#endif
138 writel(value, ioaddr + GMAC_FRAME_FILTER);
139
140 DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
141 "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
142 readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
143
144 return;
145}
146
147static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
148 unsigned int fc, unsigned int pause_time)
149{
150 unsigned int flow = 0;
151
152 DBG(KERN_DEBUG "GMAC Flow-Control:\n");
153 if (fc & FLOW_RX) {
154 DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
155 flow |= GMAC_FLOW_CTRL_RFE;
156 }
157 if (fc & FLOW_TX) {
158 DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
159 flow |= GMAC_FLOW_CTRL_TFE;
160 }
161
162 if (duplex) {
163 DBG(KERN_DEBUG "\tduplex mode: pause time: %d\n", pause_time);
164 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
165 }
166
167 writel(flow, ioaddr + GMAC_FLOW_CTRL);
168 return;
169}
170
171static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode)
172{
173 unsigned int pmt = 0;
174
175 if (mode == WAKE_MAGIC) {
176 DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
177 pmt |= power_down | magic_pkt_en;
178 } else if (mode == WAKE_UCAST) {
179 DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
180 pmt |= global_unicast;
181 }
182
183 writel(pmt, ioaddr + GMAC_PMT);
184 return;
185}
186
187
188static void dwmac1000_irq_status(unsigned long ioaddr)
189{
190 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
191
192 /* Not used events (e.g. MMC interrupts) are not handled. */
193 if ((intr_status & mmc_tx_irq))
194 DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
195 readl(ioaddr + GMAC_MMC_TX_INTR));
196 if (unlikely(intr_status & mmc_rx_irq))
197 DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
198 readl(ioaddr + GMAC_MMC_RX_INTR));
199 if (unlikely(intr_status & mmc_rx_csum_offload_irq))
200 DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
201 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
202 if (unlikely(intr_status & pmt_irq)) {
203 DBG(KERN_DEBUG "GMAC: received Magic frame\n");
204 /* clear the PMT bits 5 and 6 by reading the PMT
205 * status register. */
206 readl(ioaddr + GMAC_PMT);
207 }
208
209 return;
210}
211
212struct stmmac_ops dwmac1000_ops = {
213 .core_init = dwmac1000_core_init,
214 .dump_regs = dwmac1000_dump_regs,
215 .host_irq_status = dwmac1000_irq_status,
216 .set_filter = dwmac1000_set_filter,
217 .flow_ctrl = dwmac1000_flow_ctrl,
218 .pmt = dwmac1000_pmt,
219 .set_umac_addr = dwmac1000_set_umac_addr,
220 .get_umac_addr = dwmac1000_get_umac_addr,
221};
222
223struct mac_device_info *dwmac1000_setup(unsigned long ioaddr)
224{
225 struct mac_device_info *mac;
226 u32 uid = readl(ioaddr + GMAC_VERSION);
227
228 pr_info("\tDWMAC1000 - user ID: 0x%x, Synopsys ID: 0x%x\n",
229 ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
230
231 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
232
233 mac->mac = &dwmac1000_ops;
234 mac->desc = &dwmac1000_desc_ops;
235 mac->dma = &dwmac1000_dma_ops;
236
237 mac->pmt = PMT_SUPPORTED;
238 mac->link.port = GMAC_CONTROL_PS;
239 mac->link.duplex = GMAC_CONTROL_DM;
240 mac->link.speed = GMAC_CONTROL_FES;
241 mac->mii.addr = GMAC_MII_ADDR;
242 mac->mii.data = GMAC_MII_DATA;
243
244 return mac;
245}
diff --git a/drivers/net/stmmac/gmac.c b/drivers/net/stmmac/dwmac1000_dma.c
index 07880922ff46..68245508e2de 100644
--- a/drivers/net/stmmac/gmac.c
+++ b/drivers/net/stmmac/dwmac1000_dma.c
@@ -3,6 +3,8 @@
3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for 3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
4 developing this code. 4 developing this code.
5 5
6 This contains the functions to handle the dma and descriptors.
7
6 Copyright (C) 2007-2009 STMicroelectronics Ltd 8 Copyright (C) 2007-2009 STMicroelectronics Ltd
7 9
8 This program is free software; you can redistribute it and/or modify it 10 This program is free software; you can redistribute it and/or modify it
@@ -24,42 +26,11 @@
24 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 26 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
25*******************************************************************************/ 27*******************************************************************************/
26 28
27#include <linux/netdevice.h> 29#include "dwmac1000.h"
28#include <linux/crc32.h>
29#include <linux/mii.h>
30#include <linux/phy.h>
31
32#include "stmmac.h"
33#include "gmac.h"
34#include "dwmac_dma.h" 30#include "dwmac_dma.h"
35 31
36#undef GMAC_DEBUG 32static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
37/*#define GMAC_DEBUG*/ 33 u32 dma_rx)
38#undef FRAME_FILTER_DEBUG
39/*#define FRAME_FILTER_DEBUG*/
40#ifdef GMAC_DEBUG
41#define DBG(fmt, args...) printk(fmt, ## args)
42#else
43#define DBG(fmt, args...) do { } while (0)
44#endif
45
46static void gmac_dump_regs(unsigned long ioaddr)
47{
48 int i;
49 pr_info("\t----------------------------------------------\n"
50 "\t GMAC registers (base addr = 0x%8x)\n"
51 "\t----------------------------------------------\n",
52 (unsigned int)ioaddr);
53
54 for (i = 0; i < 55; i++) {
55 int offset = i * 4;
56 pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
57 offset, readl(ioaddr + offset));
58 }
59 return;
60}
61
62static int gmac_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx)
63{ 34{
64 u32 value = readl(ioaddr + DMA_BUS_MODE); 35 u32 value = readl(ioaddr + DMA_BUS_MODE);
65 /* DMA SW reset */ 36 /* DMA SW reset */
@@ -88,7 +59,7 @@ static int gmac_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx)
88} 59}
89 60
90/* Transmit FIFO flush operation */ 61/* Transmit FIFO flush operation */
91static void gmac_flush_tx_fifo(unsigned long ioaddr) 62static void dwmac1000_flush_tx_fifo(unsigned long ioaddr)
92{ 63{
93 u32 csr6 = readl(ioaddr + DMA_CONTROL); 64 u32 csr6 = readl(ioaddr + DMA_CONTROL);
94 writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL); 65 writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
@@ -96,7 +67,7 @@ static void gmac_flush_tx_fifo(unsigned long ioaddr)
96 do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF)); 67 do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
97} 68}
98 69
99static void gmac_dma_operation_mode(unsigned long ioaddr, int txmode, 70static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
100 int rxmode) 71 int rxmode)
101{ 72{
102 u32 csr6 = readl(ioaddr + DMA_CONTROL); 73 u32 csr6 = readl(ioaddr + DMA_CONTROL);
@@ -149,13 +120,13 @@ static void gmac_dma_operation_mode(unsigned long ioaddr, int txmode,
149} 120}
150 121
151/* Not yet implemented --- no RMON module */ 122/* Not yet implemented --- no RMON module */
152static void gmac_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x, 123static void dwmac1000_dma_diagnostic_fr(void *data,
153 unsigned long ioaddr) 124 struct stmmac_extra_stats *x, unsigned long ioaddr)
154{ 125{
155 return; 126 return;
156} 127}
157 128
158static void gmac_dump_dma_regs(unsigned long ioaddr) 129static void dwmac1000_dump_dma_regs(unsigned long ioaddr)
159{ 130{
160 int i; 131 int i;
161 pr_info(" DMA registers\n"); 132 pr_info(" DMA registers\n");
@@ -170,8 +141,9 @@ static void gmac_dump_dma_regs(unsigned long ioaddr)
170 return; 141 return;
171} 142}
172 143
173static int gmac_get_tx_frame_status(void *data, struct stmmac_extra_stats *x, 144static int dwmac1000_get_tx_frame_status(void *data,
174 struct dma_desc *p, unsigned long ioaddr) 145 struct stmmac_extra_stats *x,
146 struct dma_desc *p, unsigned long ioaddr)
175{ 147{
176 int ret = 0; 148 int ret = 0;
177 struct net_device_stats *stats = (struct net_device_stats *)data; 149 struct net_device_stats *stats = (struct net_device_stats *)data;
@@ -186,7 +158,7 @@ static int gmac_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
186 if (unlikely(p->des01.etx.frame_flushed)) { 158 if (unlikely(p->des01.etx.frame_flushed)) {
187 DBG(KERN_ERR "\tframe_flushed error\n"); 159 DBG(KERN_ERR "\tframe_flushed error\n");
188 x->tx_frame_flushed++; 160 x->tx_frame_flushed++;
189 gmac_flush_tx_fifo(ioaddr); 161 dwmac1000_flush_tx_fifo(ioaddr);
190 } 162 }
191 163
192 if (unlikely(p->des01.etx.loss_carrier)) { 164 if (unlikely(p->des01.etx.loss_carrier)) {
@@ -214,7 +186,7 @@ static int gmac_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
214 186
215 if (unlikely(p->des01.etx.underflow_error)) { 187 if (unlikely(p->des01.etx.underflow_error)) {
216 DBG(KERN_ERR "\tunderflow error\n"); 188 DBG(KERN_ERR "\tunderflow error\n");
217 gmac_flush_tx_fifo(ioaddr); 189 dwmac1000_flush_tx_fifo(ioaddr);
218 x->tx_underflow++; 190 x->tx_underflow++;
219 } 191 }
220 192
@@ -226,7 +198,7 @@ static int gmac_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
226 if (unlikely(p->des01.etx.payload_error)) { 198 if (unlikely(p->des01.etx.payload_error)) {
227 DBG(KERN_ERR "\tAddr/Payload csum error\n"); 199 DBG(KERN_ERR "\tAddr/Payload csum error\n");
228 x->tx_payload_error++; 200 x->tx_payload_error++;
229 gmac_flush_tx_fifo(ioaddr); 201 dwmac1000_flush_tx_fifo(ioaddr);
230 } 202 }
231 203
232 ret = -1; 204 ret = -1;
@@ -246,12 +218,12 @@ static int gmac_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
246 return ret; 218 return ret;
247} 219}
248 220
249static int gmac_get_tx_len(struct dma_desc *p) 221static int dwmac1000_get_tx_len(struct dma_desc *p)
250{ 222{
251 return p->des01.etx.buffer1_size; 223 return p->des01.etx.buffer1_size;
252} 224}
253 225
254static int gmac_coe_rdes0(int ipc_err, int type, int payload_err) 226static int dwmac1000_coe_rdes0(int ipc_err, int type, int payload_err)
255{ 227{
256 int ret = good_frame; 228 int ret = good_frame;
257 u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7; 229 u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
@@ -294,8 +266,8 @@ static int gmac_coe_rdes0(int ipc_err, int type, int payload_err)
294 return ret; 266 return ret;
295} 267}
296 268
297static int gmac_get_rx_frame_status(void *data, struct stmmac_extra_stats *x, 269static int dwmac1000_get_rx_frame_status(void *data,
298 struct dma_desc *p) 270 struct stmmac_extra_stats *x, struct dma_desc *p)
299{ 271{
300 int ret = good_frame; 272 int ret = good_frame;
301 struct net_device_stats *stats = (struct net_device_stats *)data; 273 struct net_device_stats *stats = (struct net_device_stats *)data;
@@ -340,7 +312,7 @@ static int gmac_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
340 * It doesn't match with the information reported into the databook. 312 * It doesn't match with the information reported into the databook.
341 * At any rate, we need to understand if the CSUM hw computation is ok 313 * At any rate, we need to understand if the CSUM hw computation is ok
342 * and report this info to the upper layers. */ 314 * and report this info to the upper layers. */
343 ret = gmac_coe_rdes0(p->des01.erx.ipc_csum_error, 315 ret = dwmac1000_coe_rdes0(p->des01.erx.ipc_csum_error,
344 p->des01.erx.frame_type, p->des01.erx.payload_csum_error); 316 p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
345 317
346 if (unlikely(p->des01.erx.dribbling)) { 318 if (unlikely(p->des01.erx.dribbling)) {
@@ -371,170 +343,7 @@ static int gmac_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
371 return ret; 343 return ret;
372} 344}
373 345
374static void gmac_irq_status(unsigned long ioaddr) 346static void dwmac1000_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
375{
376 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
377
378 /* Not used events (e.g. MMC interrupts) are not handled. */
379 if ((intr_status & mmc_tx_irq))
380 DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
381 readl(ioaddr + GMAC_MMC_TX_INTR));
382 if (unlikely(intr_status & mmc_rx_irq))
383 DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
384 readl(ioaddr + GMAC_MMC_RX_INTR));
385 if (unlikely(intr_status & mmc_rx_csum_offload_irq))
386 DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
387 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
388 if (unlikely(intr_status & pmt_irq)) {
389 DBG(KERN_DEBUG "GMAC: received Magic frame\n");
390 /* clear the PMT bits 5 and 6 by reading the PMT
391 * status register. */
392 readl(ioaddr + GMAC_PMT);
393 }
394
395 return;
396}
397
398static void gmac_core_init(unsigned long ioaddr)
399{
400 u32 value = readl(ioaddr + GMAC_CONTROL);
401 value |= GMAC_CORE_INIT;
402 writel(value, ioaddr + GMAC_CONTROL);
403
404 /* Freeze MMC counters */
405 writel(0x8, ioaddr + GMAC_MMC_CTRL);
406 /* Mask GMAC interrupts */
407 writel(0x207, ioaddr + GMAC_INT_MASK);
408
409#ifdef STMMAC_VLAN_TAG_USED
410 /* Tag detection without filtering */
411 writel(0x0, ioaddr + GMAC_VLAN_TAG);
412#endif
413 return;
414}
415
416static void gmac_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
417 unsigned int reg_n)
418{
419 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
420 GMAC_ADDR_LOW(reg_n));
421}
422
423static void gmac_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
424 unsigned int reg_n)
425{
426 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
427 GMAC_ADDR_LOW(reg_n));
428}
429
430static void gmac_set_filter(struct net_device *dev)
431{
432 unsigned long ioaddr = dev->base_addr;
433 unsigned int value = 0;
434
435 DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
436 __func__, dev->mc_count, dev->uc.count);
437
438 if (dev->flags & IFF_PROMISC)
439 value = GMAC_FRAME_FILTER_PR;
440 else if ((dev->mc_count > HASH_TABLE_SIZE)
441 || (dev->flags & IFF_ALLMULTI)) {
442 value = GMAC_FRAME_FILTER_PM; /* pass all multi */
443 writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
444 writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
445 } else if (dev->mc_count > 0) {
446 int i;
447 u32 mc_filter[2];
448 struct dev_mc_list *mclist;
449
450 /* Hash filter for multicast */
451 value = GMAC_FRAME_FILTER_HMC;
452
453 memset(mc_filter, 0, sizeof(mc_filter));
454 for (i = 0, mclist = dev->mc_list;
455 mclist && i < dev->mc_count; i++, mclist = mclist->next) {
456 /* The upper 6 bits of the calculated CRC are used to
457 index the contens of the hash table */
458 int bit_nr =
459 bitrev32(~crc32_le(~0, mclist->dmi_addr, 6)) >> 26;
460 /* The most significant bit determines the register to
461 * use (H/L) while the other 5 bits determine the bit
462 * within the register. */
463 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
464 }
465 writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
466 writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
467 }
468
469 /* Handle multiple unicast addresses (perfect filtering)*/
470 if (dev->uc.count > GMAC_MAX_UNICAST_ADDRESSES)
471 /* Switch to promiscuous mode is more than 16 addrs
472 are required */
473 value |= GMAC_FRAME_FILTER_PR;
474 else {
475 int reg = 1;
476 struct netdev_hw_addr *ha;
477
478 list_for_each_entry(ha, &dev->uc.list, list) {
479 gmac_set_umac_addr(ioaddr, ha->addr, reg);
480 reg++;
481 }
482 }
483
484#ifdef FRAME_FILTER_DEBUG
485 /* Enable Receive all mode (to debug filtering_fail errors) */
486 value |= GMAC_FRAME_FILTER_RA;
487#endif
488 writel(value, ioaddr + GMAC_FRAME_FILTER);
489
490 DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
491 "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
492 readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
493
494 return;
495}
496
497static void gmac_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
498 unsigned int fc, unsigned int pause_time)
499{
500 unsigned int flow = 0;
501
502 DBG(KERN_DEBUG "GMAC Flow-Control:\n");
503 if (fc & FLOW_RX) {
504 DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
505 flow |= GMAC_FLOW_CTRL_RFE;
506 }
507 if (fc & FLOW_TX) {
508 DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
509 flow |= GMAC_FLOW_CTRL_TFE;
510 }
511
512 if (duplex) {
513 DBG(KERN_DEBUG "\tduplex mode: pause time: %d\n", pause_time);
514 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
515 }
516
517 writel(flow, ioaddr + GMAC_FLOW_CTRL);
518 return;
519}
520
521static void gmac_pmt(unsigned long ioaddr, unsigned long mode)
522{
523 unsigned int pmt = 0;
524
525 if (mode == WAKE_MAGIC) {
526 DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
527 pmt |= power_down | magic_pkt_en;
528 } else if (mode == WAKE_UCAST) {
529 DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
530 pmt |= global_unicast;
531 }
532
533 writel(pmt, ioaddr + GMAC_PMT);
534 return;
535}
536
537static void gmac_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
538 int disable_rx_ic) 347 int disable_rx_ic)
539{ 348{
540 int i; 349 int i;
@@ -552,7 +361,7 @@ static void gmac_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
552 return; 361 return;
553} 362}
554 363
555static void gmac_init_tx_desc(struct dma_desc *p, unsigned int ring_size) 364static void dwmac1000_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
556{ 365{
557 int i; 366 int i;
558 367
@@ -566,32 +375,32 @@ static void gmac_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
566 return; 375 return;
567} 376}
568 377
569static int gmac_get_tx_owner(struct dma_desc *p) 378static int dwmac1000_get_tx_owner(struct dma_desc *p)
570{ 379{
571 return p->des01.etx.own; 380 return p->des01.etx.own;
572} 381}
573 382
574static int gmac_get_rx_owner(struct dma_desc *p) 383static int dwmac1000_get_rx_owner(struct dma_desc *p)
575{ 384{
576 return p->des01.erx.own; 385 return p->des01.erx.own;
577} 386}
578 387
579static void gmac_set_tx_owner(struct dma_desc *p) 388static void dwmac1000_set_tx_owner(struct dma_desc *p)
580{ 389{
581 p->des01.etx.own = 1; 390 p->des01.etx.own = 1;
582} 391}
583 392
584static void gmac_set_rx_owner(struct dma_desc *p) 393static void dwmac1000_set_rx_owner(struct dma_desc *p)
585{ 394{
586 p->des01.erx.own = 1; 395 p->des01.erx.own = 1;
587} 396}
588 397
589static int gmac_get_tx_ls(struct dma_desc *p) 398static int dwmac1000_get_tx_ls(struct dma_desc *p)
590{ 399{
591 return p->des01.etx.last_segment; 400 return p->des01.etx.last_segment;
592} 401}
593 402
594static void gmac_release_tx_desc(struct dma_desc *p) 403static void dwmac1000_release_tx_desc(struct dma_desc *p)
595{ 404{
596 int ter = p->des01.etx.end_ring; 405 int ter = p->des01.etx.end_ring;
597 406
@@ -601,7 +410,7 @@ static void gmac_release_tx_desc(struct dma_desc *p)
601 return; 410 return;
602} 411}
603 412
604static void gmac_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, 413static void dwmac1000_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
605 int csum_flag) 414 int csum_flag)
606{ 415{
607 p->des01.etx.first_segment = is_fs; 416 p->des01.etx.first_segment = is_fs;
@@ -615,38 +424,27 @@ static void gmac_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
615 p->des01.etx.checksum_insertion = cic_full; 424 p->des01.etx.checksum_insertion = cic_full;
616} 425}
617 426
618static void gmac_clear_tx_ic(struct dma_desc *p) 427static void dwmac1000_clear_tx_ic(struct dma_desc *p)
619{ 428{
620 p->des01.etx.interrupt = 0; 429 p->des01.etx.interrupt = 0;
621} 430}
622 431
623static void gmac_close_tx_desc(struct dma_desc *p) 432static void dwmac1000_close_tx_desc(struct dma_desc *p)
624{ 433{
625 p->des01.etx.last_segment = 1; 434 p->des01.etx.last_segment = 1;
626 p->des01.etx.interrupt = 1; 435 p->des01.etx.interrupt = 1;
627} 436}
628 437
629static int gmac_get_rx_frame_len(struct dma_desc *p) 438static int dwmac1000_get_rx_frame_len(struct dma_desc *p)
630{ 439{
631 return p->des01.erx.frame_length; 440 return p->des01.erx.frame_length;
632} 441}
633 442
634struct stmmac_ops gmac_ops = { 443struct stmmac_dma_ops dwmac1000_dma_ops = {
635 .core_init = gmac_core_init, 444 .init = dwmac1000_dma_init,
636 .dump_regs = gmac_dump_regs, 445 .dump_regs = dwmac1000_dump_dma_regs,
637 .host_irq_status = gmac_irq_status, 446 .dma_mode = dwmac1000_dma_operation_mode,
638 .set_filter = gmac_set_filter, 447 .dma_diagnostic_fr = dwmac1000_dma_diagnostic_fr,
639 .flow_ctrl = gmac_flow_ctrl,
640 .pmt = gmac_pmt,
641 .set_umac_addr = gmac_set_umac_addr,
642 .get_umac_addr = gmac_get_umac_addr,
643};
644
645struct stmmac_dma_ops gmac_dma_ops = {
646 .init = gmac_dma_init,
647 .dump_regs = gmac_dump_dma_regs,
648 .dma_mode = gmac_dma_operation_mode,
649 .dma_diagnostic_fr = gmac_dma_diagnostic_fr,
650 .enable_dma_transmission = dwmac_enable_dma_transmission, 448 .enable_dma_transmission = dwmac_enable_dma_transmission,
651 .enable_dma_irq = dwmac_enable_dma_irq, 449 .enable_dma_irq = dwmac_enable_dma_irq,
652 .disable_dma_irq = dwmac_disable_dma_irq, 450 .disable_dma_irq = dwmac_disable_dma_irq,
@@ -657,44 +455,20 @@ struct stmmac_dma_ops gmac_dma_ops = {
657 .dma_interrupt = dwmac_dma_interrupt, 455 .dma_interrupt = dwmac_dma_interrupt,
658}; 456};
659 457
660struct stmmac_desc_ops gmac_desc_ops = { 458struct stmmac_desc_ops dwmac1000_desc_ops = {
661 .tx_status = gmac_get_tx_frame_status, 459 .tx_status = dwmac1000_get_tx_frame_status,
662 .rx_status = gmac_get_rx_frame_status, 460 .rx_status = dwmac1000_get_rx_frame_status,
663 .get_tx_len = gmac_get_tx_len, 461 .get_tx_len = dwmac1000_get_tx_len,
664 .init_rx_desc = gmac_init_rx_desc, 462 .init_rx_desc = dwmac1000_init_rx_desc,
665 .init_tx_desc = gmac_init_tx_desc, 463 .init_tx_desc = dwmac1000_init_tx_desc,
666 .get_tx_owner = gmac_get_tx_owner, 464 .get_tx_owner = dwmac1000_get_tx_owner,
667 .get_rx_owner = gmac_get_rx_owner, 465 .get_rx_owner = dwmac1000_get_rx_owner,
668 .release_tx_desc = gmac_release_tx_desc, 466 .release_tx_desc = dwmac1000_release_tx_desc,
669 .prepare_tx_desc = gmac_prepare_tx_desc, 467 .prepare_tx_desc = dwmac1000_prepare_tx_desc,
670 .clear_tx_ic = gmac_clear_tx_ic, 468 .clear_tx_ic = dwmac1000_clear_tx_ic,
671 .close_tx_desc = gmac_close_tx_desc, 469 .close_tx_desc = dwmac1000_close_tx_desc,
672 .get_tx_ls = gmac_get_tx_ls, 470 .get_tx_ls = dwmac1000_get_tx_ls,
673 .set_tx_owner = gmac_set_tx_owner, 471 .set_tx_owner = dwmac1000_set_tx_owner,
674 .set_rx_owner = gmac_set_rx_owner, 472 .set_rx_owner = dwmac1000_set_rx_owner,
675 .get_rx_frame_len = gmac_get_rx_frame_len, 473 .get_rx_frame_len = dwmac1000_get_rx_frame_len,
676}; 474};
677
678struct mac_device_info *gmac_setup(unsigned long ioaddr)
679{
680 struct mac_device_info *mac;
681 u32 uid = readl(ioaddr + GMAC_VERSION);
682
683 pr_info("\tGMAC - user ID: 0x%x, Synopsys ID: 0x%x\n",
684 ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
685
686 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
687
688 mac->mac = &gmac_ops;
689 mac->desc = &gmac_desc_ops;
690 mac->dma = &gmac_dma_ops;
691
692 mac->pmt = PMT_SUPPORTED;
693 mac->link.port = GMAC_CONTROL_PS;
694 mac->link.duplex = GMAC_CONTROL_DM;
695 mac->link.speed = GMAC_CONTROL_FES;
696 mac->mii.addr = GMAC_MII_ADDR;
697 mac->mii.data = GMAC_MII_DATA;
698
699 return mac;
700}
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index e79e00b6f147..16d4e1cecf8f 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -1583,7 +1583,7 @@ static int stmmac_mac_device_setup(struct net_device *dev)
1583 struct mac_device_info *device; 1583 struct mac_device_info *device;
1584 1584
1585 if (priv->is_gmac) 1585 if (priv->is_gmac)
1586 device = gmac_setup(ioaddr); 1586 device = dwmac1000_setup(ioaddr);
1587 else 1587 else
1588 device = dwmac100_setup(ioaddr); 1588 device = dwmac100_setup(ioaddr);
1589 1589