aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2010-04-13 16:21:11 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-14 07:49:49 -0400
commit3c32be635c18ead00d460b7bdad1da52622ff40f (patch)
tree5a26fc20ebe0b826fc3deb66676b20897ac8e979
parentf0ad0860d01e47a3ffd220564c5c653b3afbe962 (diff)
stmmac: split core and dma for the mac10/100
The patch splits core and dma parts for the mac10/100 device. This was already done for the GMAC device. It should make more flexible the driver to support other chips. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/stmmac/Makefile2
-rw-r--r--drivers/net/stmmac/dwmac100.h17
-rw-r--r--drivers/net/stmmac/dwmac100_core.c202
-rw-r--r--drivers/net/stmmac/dwmac100_dma.c (renamed from drivers/net/stmmac/dwmac100.c)213
4 files changed, 234 insertions, 200 deletions
diff --git a/drivers/net/stmmac/Makefile b/drivers/net/stmmac/Makefile
index c776af15fe1a..b14bd563b1e2 100644
--- a/drivers/net/stmmac/Makefile
+++ b/drivers/net/stmmac/Makefile
@@ -2,4 +2,4 @@ obj-$(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 \ 3stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
4 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ 4 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
5 dwmac100.o $(stmmac-y) 5 dwmac100_core.o dwmac100_dma.o $(stmmac-y)
diff --git a/drivers/net/stmmac/dwmac100.h b/drivers/net/stmmac/dwmac100.h
index 0f8f110d004a..9f4ba2e76575 100644
--- a/drivers/net/stmmac/dwmac100.h
+++ b/drivers/net/stmmac/dwmac100.h
@@ -22,6 +22,9 @@
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/ 23*******************************************************************************/
24 24
25#include <linux/phy.h>
26#include "common.h"
27
25/*---------------------------------------------------------------------------- 28/*----------------------------------------------------------------------------
26 * MAC BLOCK defines 29 * MAC BLOCK defines
27 *---------------------------------------------------------------------------*/ 30 *---------------------------------------------------------------------------*/
@@ -114,3 +117,17 @@ enum ttc_control {
114#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000 /* Overflow Frame Counter */ 117#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000 /* Overflow Frame Counter */
115#define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */ 118#define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */
116#define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */ 119#define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */
120
121#undef DWMAC100_DEBUG
122/* #define DWMAC100__DEBUG */
123#undef FRAME_FILTER_DEBUG
124/* #define FRAME_FILTER_DEBUG */
125#ifdef DWMAC100__DEBUG
126#define DBG(fmt, args...) printk(fmt, ## args)
127#else
128#define DBG(fmt, args...) do { } while (0)
129#endif
130
131extern struct stmmac_dma_ops dwmac100_dma_ops;
132extern struct stmmac_desc_ops dwmac100_desc_ops;
133
diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c
new file mode 100644
index 000000000000..8ecb8c0b4d98
--- /dev/null
+++ b/drivers/net/stmmac/dwmac100_core.c
@@ -0,0 +1,202 @@
1/*******************************************************************************
2 This is the driver for the MAC 10/100 on-chip Ethernet controller
3 currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
4
5 DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
6 this code.
7
8 This only implements the mac core functions for this chip.
9
10 Copyright (C) 2007-2009 STMicroelectronics Ltd
11
12 This program is free software; you can redistribute it and/or modify it
13 under the terms and conditions of the GNU General Public License,
14 version 2, as published by the Free Software Foundation.
15
16 This program is distributed in the hope it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 more details.
20
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
24
25 The full GNU General Public License is included in this distribution in
26 the file called "COPYING".
27
28 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
29*******************************************************************************/
30
31#include <linux/crc32.h>
32#include "dwmac100.h"
33
34static void dwmac100_core_init(unsigned long ioaddr)
35{
36 u32 value = readl(ioaddr + MAC_CONTROL);
37
38 writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
39
40#ifdef STMMAC_VLAN_TAG_USED
41 writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
42#endif
43 return;
44}
45
46static void dwmac100_dump_mac_regs(unsigned long ioaddr)
47{
48 pr_info("\t----------------------------------------------\n"
49 "\t DWMAC 100 CSR (base addr = 0x%8x)\n"
50 "\t----------------------------------------------\n",
51 (unsigned int)ioaddr);
52 pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
53 readl(ioaddr + MAC_CONTROL));
54 pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
55 readl(ioaddr + MAC_ADDR_HIGH));
56 pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
57 readl(ioaddr + MAC_ADDR_LOW));
58 pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
59 MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
60 pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
61 MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
62 pr_info("\tflow control (offset 0x%x): 0x%08x\n",
63 MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
64 pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
65 readl(ioaddr + MAC_VLAN1));
66 pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
67 readl(ioaddr + MAC_VLAN2));
68 pr_info("\n\tMAC management counter registers\n");
69 pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
70 MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
71 pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
72 MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
73 pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
74 MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
75 pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
76 MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
77 pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
78 MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
79 return;
80}
81
82static void dwmac100_irq_status(unsigned long ioaddr)
83{
84 return;
85}
86
87static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
88 unsigned int reg_n)
89{
90 stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
91}
92
93static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
94 unsigned int reg_n)
95{
96 stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
97}
98
99static void dwmac100_set_filter(struct net_device *dev)
100{
101 unsigned long ioaddr = dev->base_addr;
102 u32 value = readl(ioaddr + MAC_CONTROL);
103
104 if (dev->flags & IFF_PROMISC) {
105 value |= MAC_CONTROL_PR;
106 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
107 MAC_CONTROL_HP);
108 } else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
109 || (dev->flags & IFF_ALLMULTI)) {
110 value |= MAC_CONTROL_PM;
111 value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
112 writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
113 writel(0xffffffff, ioaddr + MAC_HASH_LOW);
114 } else if (netdev_mc_empty(dev)) { /* no multicast */
115 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
116 MAC_CONTROL_HO | MAC_CONTROL_HP);
117 } else {
118 u32 mc_filter[2];
119 struct netdev_hw_addr *ha;
120
121 /* Perfect filter mode for physical address and Hash
122 filter for multicast */
123 value |= MAC_CONTROL_HP;
124 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
125 MAC_CONTROL_IF | MAC_CONTROL_HO);
126
127 memset(mc_filter, 0, sizeof(mc_filter));
128 netdev_for_each_mc_addr(ha, dev) {
129 /* The upper 6 bits of the calculated CRC are used to
130 * index the contens of the hash table */
131 int bit_nr =
132 ether_crc(ETH_ALEN, ha->addr) >> 26;
133 /* The most significant bit determines the register to
134 * use (H/L) while the other 5 bits determine the bit
135 * within the register. */
136 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
137 }
138 writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
139 writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
140 }
141
142 writel(value, ioaddr + MAC_CONTROL);
143
144 DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
145 "HI 0x%08x, LO 0x%08x\n",
146 __func__, readl(ioaddr + MAC_CONTROL),
147 readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
148 return;
149}
150
151static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
152 unsigned int fc, unsigned int pause_time)
153{
154 unsigned int flow = MAC_FLOW_CTRL_ENABLE;
155
156 if (duplex)
157 flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
158 writel(flow, ioaddr + MAC_FLOW_CTRL);
159
160 return;
161}
162
163/* No PMT module supported for this Ethernet Controller.
164 * Tested on ST platforms only.
165 */
166static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
167{
168 return;
169}
170
171struct stmmac_ops dwmac100_ops = {
172 .core_init = dwmac100_core_init,
173 .dump_regs = dwmac100_dump_mac_regs,
174 .host_irq_status = dwmac100_irq_status,
175 .set_filter = dwmac100_set_filter,
176 .flow_ctrl = dwmac100_flow_ctrl,
177 .pmt = dwmac100_pmt,
178 .set_umac_addr = dwmac100_set_umac_addr,
179 .get_umac_addr = dwmac100_get_umac_addr,
180};
181
182struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
183{
184 struct mac_device_info *mac;
185
186 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
187
188 pr_info("\tDWMAC100\n");
189
190 mac->mac = &dwmac100_ops;
191 mac->desc = &dwmac100_desc_ops;
192 mac->dma = &dwmac100_dma_ops;
193
194 mac->pmt = PMT_NOT_SUPPORTED;
195 mac->link.port = MAC_CONTROL_PS;
196 mac->link.duplex = MAC_CONTROL_F;
197 mac->link.speed = 0;
198 mac->mii.addr = MAC_MII_ADDR;
199 mac->mii.data = MAC_MII_DATA;
200
201 return mac;
202}
diff --git a/drivers/net/stmmac/dwmac100.c b/drivers/net/stmmac/dwmac100_dma.c
index 1ca84eab289c..7fcc52650505 100644
--- a/drivers/net/stmmac/dwmac100.c
+++ b/drivers/net/stmmac/dwmac100_dma.c
@@ -5,6 +5,8 @@
5 DWC Ether MAC 10/100 Universal version 4.0 has been used for developing 5 DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
6 this code. 6 this code.
7 7
8 This contains the functions to handle the dma and descriptors.
9
8 Copyright (C) 2007-2009 STMicroelectronics Ltd 10 Copyright (C) 2007-2009 STMicroelectronics Ltd
9 11
10 This program is free software; you can redistribute it and/or modify it 12 This program is free software; you can redistribute it and/or modify it
@@ -26,73 +28,11 @@
26 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 28 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
27*******************************************************************************/ 29*******************************************************************************/
28 30
29#include <linux/crc32.h>
30#include <linux/mii.h>
31#include <linux/phy.h>
32#include <linux/slab.h>
33
34#include "common.h"
35#include "dwmac100.h" 31#include "dwmac100.h"
36#include "dwmac_dma.h" 32#include "dwmac_dma.h"
37 33
38#undef DWMAC100_DEBUG
39/*#define DWMAC100_DEBUG*/
40#ifdef DWMAC100_DEBUG
41#define DBG(fmt, args...) printk(fmt, ## args)
42#else
43#define DBG(fmt, args...) do { } while (0)
44#endif
45
46static void dwmac100_core_init(unsigned long ioaddr)
47{
48 u32 value = readl(ioaddr + MAC_CONTROL);
49
50 writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
51
52#ifdef STMMAC_VLAN_TAG_USED
53 writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
54#endif
55 return;
56}
57
58static void dwmac100_dump_mac_regs(unsigned long ioaddr)
59{
60 pr_info("\t----------------------------------------------\n"
61 "\t DWMAC 100 CSR (base addr = 0x%8x)\n"
62 "\t----------------------------------------------\n",
63 (unsigned int)ioaddr);
64 pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
65 readl(ioaddr + MAC_CONTROL));
66 pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
67 readl(ioaddr + MAC_ADDR_HIGH));
68 pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
69 readl(ioaddr + MAC_ADDR_LOW));
70 pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
71 MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
72 pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
73 MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
74 pr_info("\tflow control (offset 0x%x): 0x%08x\n",
75 MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
76 pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
77 readl(ioaddr + MAC_VLAN1));
78 pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
79 readl(ioaddr + MAC_VLAN2));
80 pr_info("\n\tMAC management counter registers\n");
81 pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
82 MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
83 pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
84 MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
85 pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
86 MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
87 pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
88 MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
89 pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
90 MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
91 return;
92}
93
94static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, 34static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
95 u32 dma_rx) 35 u32 dma_rx)
96{ 36{
97 u32 value = readl(ioaddr + DMA_BUS_MODE); 37 u32 value = readl(ioaddr + DMA_BUS_MODE);
98 /* DMA SW reset */ 38 /* DMA SW reset */
@@ -119,7 +59,7 @@ static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
119 * The transmit threshold can be programmed by 59 * The transmit threshold can be programmed by
120 * setting the TTC bits in the DMA control register.*/ 60 * setting the TTC bits in the DMA control register.*/
121static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode, 61static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
122 int rxmode) 62 int rxmode)
123{ 63{
124 u32 csr6 = readl(ioaddr + DMA_CONTROL); 64 u32 csr6 = readl(ioaddr + DMA_CONTROL);
125 65
@@ -153,9 +93,8 @@ static void dwmac100_dump_dma_regs(unsigned long ioaddr)
153 93
154/* DMA controller has two counters to track the number of 94/* DMA controller has two counters to track the number of
155 * the receive missed frames. */ 95 * the receive missed frames. */
156static void dwmac100_dma_diagnostic_fr(void *data, 96static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
157 struct stmmac_extra_stats *x, 97 unsigned long ioaddr)
158 unsigned long ioaddr)
159{ 98{
160 struct net_device_stats *stats = (struct net_device_stats *)data; 99 struct net_device_stats *stats = (struct net_device_stats *)data;
161 u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR); 100 u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
@@ -183,9 +122,8 @@ static void dwmac100_dma_diagnostic_fr(void *data,
183 return; 122 return;
184} 123}
185 124
186static int dwmac100_get_tx_frame_status(void *data, 125static int dwmac100_get_tx_status(void *data, struct stmmac_extra_stats *x,
187 struct stmmac_extra_stats *x, 126 struct dma_desc *p, unsigned long ioaddr)
188 struct dma_desc *p, unsigned long ioaddr)
189{ 127{
190 int ret = 0; 128 int ret = 0;
191 struct net_device_stats *stats = (struct net_device_stats *)data; 129 struct net_device_stats *stats = (struct net_device_stats *)data;
@@ -229,9 +167,8 @@ static int dwmac100_get_tx_len(struct dma_desc *p)
229 * and, if required, updates the multicast statistics. 167 * and, if required, updates the multicast statistics.
230 * In case of success, it returns csum_none becasue the device 168 * In case of success, it returns csum_none becasue the device
231 * is not able to compute the csum in HW. */ 169 * is not able to compute the csum in HW. */
232static int dwmac100_get_rx_frame_status(void *data, 170static int dwmac100_get_rx_status(void *data, struct stmmac_extra_stats *x,
233 struct stmmac_extra_stats *x, 171 struct dma_desc *p)
234 struct dma_desc *p)
235{ 172{
236 int ret = csum_none; 173 int ret = csum_none;
237 struct net_device_stats *stats = (struct net_device_stats *)data; 174 struct net_device_stats *stats = (struct net_device_stats *)data;
@@ -280,97 +217,8 @@ static int dwmac100_get_rx_frame_status(void *data,
280 return ret; 217 return ret;
281} 218}
282 219
283static void dwmac100_irq_status(unsigned long ioaddr)
284{
285 return;
286}
287
288static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
289 unsigned int reg_n)
290{
291 stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
292}
293
294static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
295 unsigned int reg_n)
296{
297 stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
298}
299
300static void dwmac100_set_filter(struct net_device *dev)
301{
302 unsigned long ioaddr = dev->base_addr;
303 u32 value = readl(ioaddr + MAC_CONTROL);
304
305 if (dev->flags & IFF_PROMISC) {
306 value |= MAC_CONTROL_PR;
307 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
308 MAC_CONTROL_HP);
309 } else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
310 || (dev->flags & IFF_ALLMULTI)) {
311 value |= MAC_CONTROL_PM;
312 value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
313 writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
314 writel(0xffffffff, ioaddr + MAC_HASH_LOW);
315 } else if (netdev_mc_empty(dev)) { /* no multicast */
316 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
317 MAC_CONTROL_HO | MAC_CONTROL_HP);
318 } else {
319 u32 mc_filter[2];
320 struct netdev_hw_addr *ha;
321
322 /* Perfect filter mode for physical address and Hash
323 filter for multicast */
324 value |= MAC_CONTROL_HP;
325 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
326 MAC_CONTROL_IF | MAC_CONTROL_HO);
327
328 memset(mc_filter, 0, sizeof(mc_filter));
329 netdev_for_each_mc_addr(ha, dev) {
330 /* The upper 6 bits of the calculated CRC are used to
331 * index the contens of the hash table */
332 int bit_nr =
333 ether_crc(ETH_ALEN, ha->addr) >> 26;
334 /* The most significant bit determines the register to
335 * use (H/L) while the other 5 bits determine the bit
336 * within the register. */
337 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
338 }
339 writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
340 writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
341 }
342
343 writel(value, ioaddr + MAC_CONTROL);
344
345 DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
346 "HI 0x%08x, LO 0x%08x\n",
347 __func__, readl(ioaddr + MAC_CONTROL),
348 readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
349 return;
350}
351
352static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
353 unsigned int fc, unsigned int pause_time)
354{
355 unsigned int flow = MAC_FLOW_CTRL_ENABLE;
356
357 if (duplex)
358 flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
359 writel(flow, ioaddr + MAC_FLOW_CTRL);
360
361 return;
362}
363
364/* No PMT module supported for this Ethernet Controller.
365 * Tested on ST platforms only.
366 */
367static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
368{
369 return;
370}
371
372static void dwmac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size, 220static void dwmac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
373 int disable_rx_ic) 221 int disable_rx_ic)
374{ 222{
375 int i; 223 int i;
376 for (i = 0; i < ring_size; i++) { 224 for (i = 0; i < ring_size; i++) {
@@ -449,7 +297,7 @@ static void dwmac100_release_tx_desc(struct dma_desc *p)
449} 297}
450 298
451static void dwmac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, 299static void dwmac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
452 int csum_flag) 300 int csum_flag)
453{ 301{
454 p->des01.tx.first_segment = is_fs; 302 p->des01.tx.first_segment = is_fs;
455 p->des01.tx.buffer1_size = len; 303 p->des01.tx.buffer1_size = len;
@@ -471,17 +319,6 @@ static int dwmac100_get_rx_frame_len(struct dma_desc *p)
471 return p->des01.rx.frame_length; 319 return p->des01.rx.frame_length;
472} 320}
473 321
474struct stmmac_ops dwmac100_ops = {
475 .core_init = dwmac100_core_init,
476 .dump_regs = dwmac100_dump_mac_regs,
477 .host_irq_status = dwmac100_irq_status,
478 .set_filter = dwmac100_set_filter,
479 .flow_ctrl = dwmac100_flow_ctrl,
480 .pmt = dwmac100_pmt,
481 .set_umac_addr = dwmac100_set_umac_addr,
482 .get_umac_addr = dwmac100_get_umac_addr,
483};
484
485struct stmmac_dma_ops dwmac100_dma_ops = { 322struct stmmac_dma_ops dwmac100_dma_ops = {
486 .init = dwmac100_dma_init, 323 .init = dwmac100_dma_init,
487 .dump_regs = dwmac100_dump_dma_regs, 324 .dump_regs = dwmac100_dump_dma_regs,
@@ -498,8 +335,8 @@ struct stmmac_dma_ops dwmac100_dma_ops = {
498}; 335};
499 336
500struct stmmac_desc_ops dwmac100_desc_ops = { 337struct stmmac_desc_ops dwmac100_desc_ops = {
501 .tx_status = dwmac100_get_tx_frame_status, 338 .tx_status = dwmac100_get_tx_status,
502 .rx_status = dwmac100_get_rx_frame_status, 339 .rx_status = dwmac100_get_rx_status,
503 .get_tx_len = dwmac100_get_tx_len, 340 .get_tx_len = dwmac100_get_tx_len,
504 .init_rx_desc = dwmac100_init_rx_desc, 341 .init_rx_desc = dwmac100_init_rx_desc,
505 .init_tx_desc = dwmac100_init_tx_desc, 342 .init_tx_desc = dwmac100_init_tx_desc,
@@ -514,25 +351,3 @@ struct stmmac_desc_ops dwmac100_desc_ops = {
514 .set_rx_owner = dwmac100_set_rx_owner, 351 .set_rx_owner = dwmac100_set_rx_owner,
515 .get_rx_frame_len = dwmac100_get_rx_frame_len, 352 .get_rx_frame_len = dwmac100_get_rx_frame_len,
516}; 353};
517
518struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
519{
520 struct mac_device_info *mac;
521
522 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
523
524 pr_info("\tDWMAC100\n");
525
526 mac->mac = &dwmac100_ops;
527 mac->desc = &dwmac100_desc_ops;
528 mac->dma = &dwmac100_dma_ops;
529
530 mac->pmt = PMT_NOT_SUPPORTED;
531 mac->link.port = MAC_CONTROL_PS;
532 mac->link.duplex = MAC_CONTROL_F;
533 mac->link.speed = 0;
534 mac->mii.addr = MAC_MII_ADDR;
535 mac->mii.data = MAC_MII_DATA;
536
537 return mac;
538}