]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/net/stmmac/dwmac100.c
net/various: remove trailing space in messages
[mirror_ubuntu-jammy-kernel.git] / drivers / net / stmmac / dwmac100.c
CommitLineData
47dd7a54
GC
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 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
47dd7a54
GC
29#include <linux/crc32.h>
30#include <linux/mii.h>
31#include <linux/phy.h>
32
33#include "common.h"
7e848ae1 34#include "dwmac100.h"
aec7ff27 35#include "dwmac_dma.h"
47dd7a54 36
7e848ae1
GC
37#undef DWMAC100_DEBUG
38/*#define DWMAC100_DEBUG*/
39#ifdef DWMAC100_DEBUG
47dd7a54
GC
40#define DBG(fmt, args...) printk(fmt, ## args)
41#else
42#define DBG(fmt, args...) do { } while (0)
43#endif
44
7e848ae1 45static void dwmac100_core_init(unsigned long ioaddr)
47dd7a54
GC
46{
47 u32 value = readl(ioaddr + MAC_CONTROL);
48
49 writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
50
51#ifdef STMMAC_VLAN_TAG_USED
52 writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
53#endif
54 return;
55}
56
7e848ae1 57static void dwmac100_dump_mac_regs(unsigned long ioaddr)
47dd7a54
GC
58{
59 pr_info("\t----------------------------------------------\n"
7e848ae1
GC
60 "\t DWMAC 100 CSR (base addr = 0x%8x)\n"
61 "\t----------------------------------------------\n",
62 (unsigned int)ioaddr);
47dd7a54 63 pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
7e848ae1 64 readl(ioaddr + MAC_CONTROL));
47dd7a54 65 pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
7e848ae1 66 readl(ioaddr + MAC_ADDR_HIGH));
47dd7a54 67 pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
7e848ae1 68 readl(ioaddr + MAC_ADDR_LOW));
47dd7a54 69 pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
7e848ae1 70 MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
47dd7a54 71 pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
7e848ae1 72 MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
47dd7a54
GC
73 pr_info("\tflow control (offset 0x%x): 0x%08x\n",
74 MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
75 pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
7e848ae1 76 readl(ioaddr + MAC_VLAN1));
47dd7a54 77 pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
7e848ae1 78 readl(ioaddr + MAC_VLAN2));
47dd7a54
GC
79 pr_info("\n\tMAC management counter registers\n");
80 pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
7e848ae1 81 MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
47dd7a54 82 pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
7e848ae1 83 MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
47dd7a54 84 pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
7e848ae1 85 MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
47dd7a54 86 pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
7e848ae1 87 MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
47dd7a54 88 pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
7e848ae1 89 MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
47dd7a54
GC
90 return;
91}
92
7e848ae1 93static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
47dd7a54
GC
94 u32 dma_rx)
95{
96 u32 value = readl(ioaddr + DMA_BUS_MODE);
97 /* DMA SW reset */
98 value |= DMA_BUS_MODE_SFT_RESET;
99 writel(value, ioaddr + DMA_BUS_MODE);
100 do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
101
102 /* Enable Application Access by writing to DMA CSR0 */
103 writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
104 ioaddr + DMA_BUS_MODE);
105
106 /* Mask interrupts by writing to CSR7 */
107 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
108
109 /* The base address of the RX/TX descriptor lists must be written into
110 * DMA CSR3 and CSR4, respectively. */
111 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
112 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
113
114 return 0;
115}
116
117/* Store and Forward capability is not used at all..
118 * The transmit threshold can be programmed by
119 * setting the TTC bits in the DMA control register.*/
7e848ae1 120static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
47dd7a54
GC
121 int rxmode)
122{
123 u32 csr6 = readl(ioaddr + DMA_CONTROL);
124
125 if (txmode <= 32)
126 csr6 |= DMA_CONTROL_TTC_32;
127 else if (txmode <= 64)
128 csr6 |= DMA_CONTROL_TTC_64;
129 else
130 csr6 |= DMA_CONTROL_TTC_128;
131
132 writel(csr6, ioaddr + DMA_CONTROL);
133
134 return;
135}
136
7e848ae1 137static void dwmac100_dump_dma_regs(unsigned long ioaddr)
47dd7a54
GC
138{
139 int i;
140
2381a55c 141 DBG(KERN_DEBUG "DWMAC 100 DMA CSR\n");
47dd7a54
GC
142 for (i = 0; i < 9; i++)
143 pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
144 (DMA_BUS_MODE + i * 4),
145 readl(ioaddr + DMA_BUS_MODE + i * 4));
146 DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
147 DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
148 DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
149 DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
150 return;
151}
152
153/* DMA controller has two counters to track the number of
7e848ae1
GC
154 * the receive missed frames. */
155static void dwmac100_dma_diagnostic_fr(void *data,
156 struct stmmac_extra_stats *x,
47dd7a54
GC
157 unsigned long ioaddr)
158{
159 struct net_device_stats *stats = (struct net_device_stats *)data;
160 u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
161
162 if (unlikely(csr8)) {
163 if (csr8 & DMA_MISSED_FRAME_OVE) {
164 stats->rx_over_errors += 0x800;
165 x->rx_overflow_cntr += 0x800;
166 } else {
167 unsigned int ove_cntr;
168 ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
169 stats->rx_over_errors += ove_cntr;
170 x->rx_overflow_cntr += ove_cntr;
171 }
172
173 if (csr8 & DMA_MISSED_FRAME_OVE_M) {
174 stats->rx_missed_errors += 0xffff;
175 x->rx_missed_cntr += 0xffff;
176 } else {
177 unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
178 stats->rx_missed_errors += miss_f;
179 x->rx_missed_cntr += miss_f;
180 }
181 }
182 return;
183}
184
7e848ae1
GC
185static int dwmac100_get_tx_frame_status(void *data,
186 struct stmmac_extra_stats *x,
47dd7a54
GC
187 struct dma_desc *p, unsigned long ioaddr)
188{
189 int ret = 0;
190 struct net_device_stats *stats = (struct net_device_stats *)data;
191
192 if (unlikely(p->des01.tx.error_summary)) {
193 if (unlikely(p->des01.tx.underflow_error)) {
194 x->tx_underflow++;
195 stats->tx_fifo_errors++;
196 }
197 if (unlikely(p->des01.tx.no_carrier)) {
198 x->tx_carrier++;
199 stats->tx_carrier_errors++;
200 }
201 if (unlikely(p->des01.tx.loss_carrier)) {
202 x->tx_losscarrier++;
203 stats->tx_carrier_errors++;
204 }
205 if (unlikely((p->des01.tx.excessive_deferral) ||
206 (p->des01.tx.excessive_collisions) ||
207 (p->des01.tx.late_collision)))
208 stats->collisions += p->des01.tx.collision_count;
209 ret = -1;
210 }
211 if (unlikely(p->des01.tx.heartbeat_fail)) {
212 x->tx_heartbeat++;
213 stats->tx_heartbeat_errors++;
214 ret = -1;
215 }
216 if (unlikely(p->des01.tx.deferred))
217 x->tx_deferred++;
218
219 return ret;
220}
221
7e848ae1 222static int dwmac100_get_tx_len(struct dma_desc *p)
47dd7a54
GC
223{
224 return p->des01.tx.buffer1_size;
225}
226
227/* This function verifies if each incoming frame has some errors
228 * and, if required, updates the multicast statistics.
229 * In case of success, it returns csum_none becasue the device
230 * is not able to compute the csum in HW. */
7e848ae1
GC
231static int dwmac100_get_rx_frame_status(void *data,
232 struct stmmac_extra_stats *x,
47dd7a54
GC
233 struct dma_desc *p)
234{
235 int ret = csum_none;
236 struct net_device_stats *stats = (struct net_device_stats *)data;
237
238 if (unlikely(p->des01.rx.last_descriptor == 0)) {
7e848ae1 239 pr_warning("dwmac100 Error: Oversized Ethernet "
47dd7a54
GC
240 "frame spanned multiple buffers\n");
241 stats->rx_length_errors++;
242 return discard_frame;
243 }
244
245 if (unlikely(p->des01.rx.error_summary)) {
246 if (unlikely(p->des01.rx.descriptor_error))
247 x->rx_desc++;
248 if (unlikely(p->des01.rx.partial_frame_error))
249 x->rx_partial++;
250 if (unlikely(p->des01.rx.run_frame))
251 x->rx_runt++;
252 if (unlikely(p->des01.rx.frame_too_long))
253 x->rx_toolong++;
254 if (unlikely(p->des01.rx.collision)) {
255 x->rx_collision++;
256 stats->collisions++;
257 }
258 if (unlikely(p->des01.rx.crc_error)) {
259 x->rx_crc++;
260 stats->rx_crc_errors++;
261 }
262 ret = discard_frame;
263 }
264 if (unlikely(p->des01.rx.dribbling))
265 ret = discard_frame;
266
267 if (unlikely(p->des01.rx.length_error)) {
1b924032 268 x->rx_length++;
47dd7a54
GC
269 ret = discard_frame;
270 }
271 if (unlikely(p->des01.rx.mii_error)) {
272 x->rx_mii++;
273 ret = discard_frame;
274 }
275 if (p->des01.rx.multicast_frame) {
276 x->rx_multicast++;
277 stats->multicast++;
278 }
279 return ret;
280}
281
7e848ae1 282static void dwmac100_irq_status(unsigned long ioaddr)
47dd7a54
GC
283{
284 return;
285}
286
7e848ae1 287static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
47dd7a54
GC
288 unsigned int reg_n)
289{
290 stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
291}
292
7e848ae1 293static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
47dd7a54
GC
294 unsigned int reg_n)
295{
296 stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
297}
298
7e848ae1 299static void dwmac100_set_filter(struct net_device *dev)
47dd7a54
GC
300{
301 unsigned long ioaddr = dev->base_addr;
302 u32 value = readl(ioaddr + MAC_CONTROL);
303
304 if (dev->flags & IFF_PROMISC) {
305 value |= MAC_CONTROL_PR;
306 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
307 MAC_CONTROL_HP);
4cd24eaf 308 } else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
47dd7a54
GC
309 || (dev->flags & IFF_ALLMULTI)) {
310 value |= MAC_CONTROL_PM;
311 value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
312 writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
313 writel(0xffffffff, ioaddr + MAC_HASH_LOW);
4cd24eaf 314 } else if (netdev_mc_empty(dev)) { /* no multicast */
47dd7a54
GC
315 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
316 MAC_CONTROL_HO | MAC_CONTROL_HP);
317 } else {
47dd7a54
GC
318 u32 mc_filter[2];
319 struct dev_mc_list *mclist;
320
321 /* Perfect filter mode for physical address and Hash
322 filter for multicast */
323 value |= MAC_CONTROL_HP;
7e848ae1
GC
324 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
325 MAC_CONTROL_IF | MAC_CONTROL_HO);
47dd7a54
GC
326
327 memset(mc_filter, 0, sizeof(mc_filter));
5508590c 328 netdev_for_each_mc_addr(mclist, dev) {
47dd7a54
GC
329 /* The upper 6 bits of the calculated CRC are used to
330 * index the contens of the hash table */
331 int bit_nr =
332 ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
333 /* The most significant bit determines the register to
334 * use (H/L) while the other 5 bits determine the bit
335 * within the register. */
336 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
337 }
338 writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
339 writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
340 }
341
342 writel(value, ioaddr + MAC_CONTROL);
343
344 DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
345 "HI 0x%08x, LO 0x%08x\n",
346 __func__, readl(ioaddr + MAC_CONTROL),
347 readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
348 return;
349}
350
7e848ae1 351static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
47dd7a54
GC
352 unsigned int fc, unsigned int pause_time)
353{
354 unsigned int flow = MAC_FLOW_CTRL_ENABLE;
355
356 if (duplex)
357 flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
358 writel(flow, ioaddr + MAC_FLOW_CTRL);
359
360 return;
361}
362
7e848ae1
GC
363/* No PMT module supported for this Ethernet Controller.
364 * Tested on ST platforms only.
365 */
366static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
47dd7a54
GC
367{
368 return;
369}
370
7e848ae1 371static void dwmac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
47dd7a54
GC
372 int disable_rx_ic)
373{
374 int i;
375 for (i = 0; i < ring_size; i++) {
376 p->des01.rx.own = 1;
377 p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
378 if (i == ring_size - 1)
379 p->des01.rx.end_ring = 1;
380 if (disable_rx_ic)
381 p->des01.rx.disable_ic = 1;
382 p++;
383 }
384 return;
385}
386
7e848ae1 387static void dwmac100_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
47dd7a54
GC
388{
389 int i;
390 for (i = 0; i < ring_size; i++) {
391 p->des01.tx.own = 0;
392 if (i == ring_size - 1)
393 p->des01.tx.end_ring = 1;
394 p++;
395 }
396 return;
397}
398
7e848ae1 399static int dwmac100_get_tx_owner(struct dma_desc *p)
47dd7a54
GC
400{
401 return p->des01.tx.own;
402}
403
7e848ae1 404static int dwmac100_get_rx_owner(struct dma_desc *p)
47dd7a54
GC
405{
406 return p->des01.rx.own;
407}
408
7e848ae1 409static void dwmac100_set_tx_owner(struct dma_desc *p)
47dd7a54
GC
410{
411 p->des01.tx.own = 1;
412}
413
7e848ae1 414static void dwmac100_set_rx_owner(struct dma_desc *p)
47dd7a54
GC
415{
416 p->des01.rx.own = 1;
417}
418
7e848ae1 419static int dwmac100_get_tx_ls(struct dma_desc *p)
47dd7a54
GC
420{
421 return p->des01.tx.last_segment;
422}
423
7e848ae1 424static void dwmac100_release_tx_desc(struct dma_desc *p)
47dd7a54
GC
425{
426 int ter = p->des01.tx.end_ring;
427
428 /* clean field used within the xmit */
429 p->des01.tx.first_segment = 0;
430 p->des01.tx.last_segment = 0;
431 p->des01.tx.buffer1_size = 0;
432
433 /* clean status reported */
434 p->des01.tx.error_summary = 0;
435 p->des01.tx.underflow_error = 0;
436 p->des01.tx.no_carrier = 0;
437 p->des01.tx.loss_carrier = 0;
438 p->des01.tx.excessive_deferral = 0;
439 p->des01.tx.excessive_collisions = 0;
440 p->des01.tx.late_collision = 0;
441 p->des01.tx.heartbeat_fail = 0;
442 p->des01.tx.deferred = 0;
443
444 /* set termination field */
445 p->des01.tx.end_ring = ter;
446
447 return;
448}
449
7e848ae1 450static void dwmac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
47dd7a54
GC
451 int csum_flag)
452{
453 p->des01.tx.first_segment = is_fs;
454 p->des01.tx.buffer1_size = len;
455}
456
7e848ae1 457static void dwmac100_clear_tx_ic(struct dma_desc *p)
47dd7a54
GC
458{
459 p->des01.tx.interrupt = 0;
460}
461
7e848ae1 462static void dwmac100_close_tx_desc(struct dma_desc *p)
47dd7a54
GC
463{
464 p->des01.tx.last_segment = 1;
465 p->des01.tx.interrupt = 1;
466}
467
7e848ae1 468static int dwmac100_get_rx_frame_len(struct dma_desc *p)
47dd7a54
GC
469{
470 return p->des01.rx.frame_length;
471}
472
7e848ae1
GC
473struct stmmac_ops dwmac100_ops = {
474 .core_init = dwmac100_core_init,
475 .dump_regs = dwmac100_dump_mac_regs,
476 .host_irq_status = dwmac100_irq_status,
477 .set_filter = dwmac100_set_filter,
478 .flow_ctrl = dwmac100_flow_ctrl,
479 .pmt = dwmac100_pmt,
480 .set_umac_addr = dwmac100_set_umac_addr,
481 .get_umac_addr = dwmac100_get_umac_addr,
db98a0b0
GC
482};
483
7e848ae1
GC
484struct stmmac_dma_ops dwmac100_dma_ops = {
485 .init = dwmac100_dma_init,
486 .dump_regs = dwmac100_dump_dma_regs,
487 .dma_mode = dwmac100_dma_operation_mode,
488 .dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
aec7ff27
GC
489 .enable_dma_transmission = dwmac_enable_dma_transmission,
490 .enable_dma_irq = dwmac_enable_dma_irq,
491 .disable_dma_irq = dwmac_disable_dma_irq,
492 .start_tx = dwmac_dma_start_tx,
493 .stop_tx = dwmac_dma_stop_tx,
494 .start_rx = dwmac_dma_start_rx,
495 .stop_rx = dwmac_dma_stop_rx,
496 .dma_interrupt = dwmac_dma_interrupt,
db98a0b0
GC
497};
498
7e848ae1
GC
499struct stmmac_desc_ops dwmac100_desc_ops = {
500 .tx_status = dwmac100_get_tx_frame_status,
501 .rx_status = dwmac100_get_rx_frame_status,
502 .get_tx_len = dwmac100_get_tx_len,
503 .init_rx_desc = dwmac100_init_rx_desc,
504 .init_tx_desc = dwmac100_init_tx_desc,
505 .get_tx_owner = dwmac100_get_tx_owner,
506 .get_rx_owner = dwmac100_get_rx_owner,
507 .release_tx_desc = dwmac100_release_tx_desc,
508 .prepare_tx_desc = dwmac100_prepare_tx_desc,
509 .clear_tx_ic = dwmac100_clear_tx_ic,
510 .close_tx_desc = dwmac100_close_tx_desc,
511 .get_tx_ls = dwmac100_get_tx_ls,
512 .set_tx_owner = dwmac100_set_tx_owner,
513 .set_rx_owner = dwmac100_set_rx_owner,
514 .get_rx_frame_len = dwmac100_get_rx_frame_len,
47dd7a54
GC
515};
516
7e848ae1 517struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
47dd7a54
GC
518{
519 struct mac_device_info *mac;
520
521 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
522
7e848ae1 523 pr_info("\tDWMAC100\n");
47dd7a54 524
7e848ae1
GC
525 mac->mac = &dwmac100_ops;
526 mac->desc = &dwmac100_desc_ops;
527 mac->dma = &dwmac100_dma_ops;
db98a0b0
GC
528
529 mac->pmt = PMT_NOT_SUPPORTED;
530 mac->link.port = MAC_CONTROL_PS;
531 mac->link.duplex = MAC_CONTROL_F;
532 mac->link.speed = 0;
533 mac->mii.addr = MAC_MII_ADDR;
534 mac->mii.data = MAC_MII_DATA;
47dd7a54
GC
535
536 return mac;
537}