diff options
author | Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com> | 2008-06-29 22:08:17 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-07-30 17:21:53 -0400 |
commit | b0ca2a21f769ae255bd6821cbc5af8af797f1da7 (patch) | |
tree | 35ae1995dc011fc890681dab6496b49436e1738d /drivers/net/sh_eth.c | |
parent | d02a4e31ed0385eb34fe49f19d69a860a020ca3c (diff) |
sh_eth: Add support of SH7763 to sh_eth
SH7763 has Ethernet core same as SH7710/SH7712.
Positions of some registry are different, but the basic part is the same.
I add support of ethernet of sh7763 to sh_eth.
Signed-off-by: Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sh_eth.c')
-rw-r--r-- | drivers/net/sh_eth.c | 202 |
1 files changed, 166 insertions, 36 deletions
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index c69ba1395fa9..6a06b9503e4f 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SuperH Ethernet device driver | 2 | * SuperH Ethernet device driver |
3 | * | 3 | * |
4 | * Copyright (C) 2006,2007 Nobuhiro Iwamatsu | 4 | * Copyright (C) 2006-2008 Nobuhiro Iwamatsu |
5 | * Copyright (C) 2008 Renesas Solutions Corp. | 5 | * Copyright (C) 2008 Renesas Solutions Corp. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
@@ -143,13 +143,39 @@ static struct mdiobb_ops bb_ops = { | |||
143 | .get_mdio_data = sh_get_mdio, | 143 | .get_mdio_data = sh_get_mdio, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | /* Chip Reset */ | ||
146 | static void sh_eth_reset(struct net_device *ndev) | 147 | static void sh_eth_reset(struct net_device *ndev) |
147 | { | 148 | { |
148 | u32 ioaddr = ndev->base_addr; | 149 | u32 ioaddr = ndev->base_addr; |
149 | 150 | ||
151 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
152 | int cnt = 100; | ||
153 | |||
154 | ctrl_outl(EDSR_ENALL, ioaddr + EDSR); | ||
155 | ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); | ||
156 | while (cnt > 0) { | ||
157 | if (!(ctrl_inl(ioaddr + EDMR) & 0x3)) | ||
158 | break; | ||
159 | mdelay(1); | ||
160 | cnt--; | ||
161 | } | ||
162 | if (cnt < 0) | ||
163 | printk(KERN_ERR "Device reset fail\n"); | ||
164 | |||
165 | /* Table Init */ | ||
166 | ctrl_outl(0x0, ioaddr + TDLAR); | ||
167 | ctrl_outl(0x0, ioaddr + TDFAR); | ||
168 | ctrl_outl(0x0, ioaddr + TDFXR); | ||
169 | ctrl_outl(0x0, ioaddr + TDFFR); | ||
170 | ctrl_outl(0x0, ioaddr + RDLAR); | ||
171 | ctrl_outl(0x0, ioaddr + RDFAR); | ||
172 | ctrl_outl(0x0, ioaddr + RDFXR); | ||
173 | ctrl_outl(0x0, ioaddr + RDFFR); | ||
174 | #else | ||
150 | ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); | 175 | ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); |
151 | mdelay(3); | 176 | mdelay(3); |
152 | ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); | 177 | ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); |
178 | #endif | ||
153 | } | 179 | } |
154 | 180 | ||
155 | /* free skb and descriptor buffer */ | 181 | /* free skb and descriptor buffer */ |
@@ -180,6 +206,7 @@ static void sh_eth_ring_free(struct net_device *ndev) | |||
180 | /* format skb and descriptor buffer */ | 206 | /* format skb and descriptor buffer */ |
181 | static void sh_eth_ring_format(struct net_device *ndev) | 207 | static void sh_eth_ring_format(struct net_device *ndev) |
182 | { | 208 | { |
209 | u32 ioaddr = ndev->base_addr, reserve = 0; | ||
183 | struct sh_eth_private *mdp = netdev_priv(ndev); | 210 | struct sh_eth_private *mdp = netdev_priv(ndev); |
184 | int i; | 211 | int i; |
185 | struct sk_buff *skb; | 212 | struct sk_buff *skb; |
@@ -201,9 +228,15 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
201 | mdp->rx_skbuff[i] = skb; | 228 | mdp->rx_skbuff[i] = skb; |
202 | if (skb == NULL) | 229 | if (skb == NULL) |
203 | break; | 230 | break; |
204 | skb->dev = ndev; /* Mark as being used by this device. */ | 231 | skb->dev = ndev; /* Mark as being used by this device. */ |
232 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
233 | reserve = SH7763_SKB_ALIGN | ||
234 | - ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1)); | ||
235 | if (reserve) | ||
236 | skb_reserve(skb, reserve); | ||
237 | #else | ||
205 | skb_reserve(skb, RX_OFFSET); | 238 | skb_reserve(skb, RX_OFFSET); |
206 | 239 | #endif | |
207 | /* RX descriptor */ | 240 | /* RX descriptor */ |
208 | rxdesc = &mdp->rx_ring[i]; | 241 | rxdesc = &mdp->rx_ring[i]; |
209 | rxdesc->addr = (u32)skb->data & ~0x3UL; | 242 | rxdesc->addr = (u32)skb->data & ~0x3UL; |
@@ -211,12 +244,25 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
211 | 244 | ||
212 | /* The size of the buffer is 16 byte boundary. */ | 245 | /* The size of the buffer is 16 byte boundary. */ |
213 | rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F; | 246 | rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F; |
247 | /* Rx descriptor address set */ | ||
248 | if (i == 0) { | ||
249 | ctrl_outl((u32)rxdesc, ioaddr + RDLAR); | ||
250 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
251 | ctrl_outl((u32)rxdesc, ioaddr + RDFAR); | ||
252 | #endif | ||
253 | } | ||
214 | } | 254 | } |
215 | 255 | ||
256 | /* Rx descriptor address set */ | ||
257 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
258 | ctrl_outl((u32)rxdesc, ioaddr + RDFXR); | ||
259 | ctrl_outl(0x1, ioaddr + RDFFR); | ||
260 | #endif | ||
261 | |||
216 | mdp->dirty_rx = (u32) (i - RX_RING_SIZE); | 262 | mdp->dirty_rx = (u32) (i - RX_RING_SIZE); |
217 | 263 | ||
218 | /* Mark the last entry as wrapping the ring. */ | 264 | /* Mark the last entry as wrapping the ring. */ |
219 | rxdesc->status |= cpu_to_le32(RC_RDEL); | 265 | rxdesc->status |= cpu_to_le32(RD_RDEL); |
220 | 266 | ||
221 | memset(mdp->tx_ring, 0, tx_ringsize); | 267 | memset(mdp->tx_ring, 0, tx_ringsize); |
222 | 268 | ||
@@ -226,8 +272,21 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
226 | txdesc = &mdp->tx_ring[i]; | 272 | txdesc = &mdp->tx_ring[i]; |
227 | txdesc->status = cpu_to_le32(TD_TFP); | 273 | txdesc->status = cpu_to_le32(TD_TFP); |
228 | txdesc->buffer_length = 0; | 274 | txdesc->buffer_length = 0; |
275 | if (i == 0) { | ||
276 | /* Rx descriptor address set */ | ||
277 | ctrl_outl((u32)txdesc, ioaddr + TDLAR); | ||
278 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
279 | ctrl_outl((u32)txdesc, ioaddr + TDFAR); | ||
280 | #endif | ||
281 | } | ||
229 | } | 282 | } |
230 | 283 | ||
284 | /* Rx descriptor address set */ | ||
285 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
286 | ctrl_outl((u32)txdesc, ioaddr + TDFXR); | ||
287 | ctrl_outl(0x1, ioaddr + TDFFR); | ||
288 | #endif | ||
289 | |||
231 | txdesc->status |= cpu_to_le32(TD_TDLE); | 290 | txdesc->status |= cpu_to_le32(TD_TDLE); |
232 | } | 291 | } |
233 | 292 | ||
@@ -311,31 +370,43 @@ static int sh_eth_dev_init(struct net_device *ndev) | |||
311 | /* Soft Reset */ | 370 | /* Soft Reset */ |
312 | sh_eth_reset(ndev); | 371 | sh_eth_reset(ndev); |
313 | 372 | ||
314 | ctrl_outl(RPADIR_PADS1, ioaddr + RPADIR); /* SH7712-DMA-RX-PAD2 */ | 373 | /* Descriptor format */ |
374 | sh_eth_ring_format(ndev); | ||
375 | ctrl_outl(RPADIR_INIT, ioaddr + RPADIR); | ||
315 | 376 | ||
316 | /* all sh_eth int mask */ | 377 | /* all sh_eth int mask */ |
317 | ctrl_outl(0, ioaddr + EESIPR); | 378 | ctrl_outl(0, ioaddr + EESIPR); |
318 | 379 | ||
319 | /* FIFO size set */ | 380 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) |
381 | ctrl_outl(EDMR_EL, ioaddr + EDMR); | ||
382 | #else | ||
320 | ctrl_outl(0, ioaddr + EDMR); /* Endian change */ | 383 | ctrl_outl(0, ioaddr + EDMR); /* Endian change */ |
384 | #endif | ||
321 | 385 | ||
386 | /* FIFO size set */ | ||
322 | ctrl_outl((FIFO_SIZE_T | FIFO_SIZE_R), ioaddr + FDR); | 387 | ctrl_outl((FIFO_SIZE_T | FIFO_SIZE_R), ioaddr + FDR); |
323 | ctrl_outl(0, ioaddr + TFTR); | 388 | ctrl_outl(0, ioaddr + TFTR); |
324 | 389 | ||
390 | /* Frame recv control */ | ||
325 | ctrl_outl(0, ioaddr + RMCR); | 391 | ctrl_outl(0, ioaddr + RMCR); |
326 | 392 | ||
327 | rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5; | 393 | rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5; |
328 | tx_int_var = mdp->tx_int_var = DESC_I_TINT2; | 394 | tx_int_var = mdp->tx_int_var = DESC_I_TINT2; |
329 | ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER); | 395 | ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER); |
330 | 396 | ||
397 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
398 | /* Burst sycle set */ | ||
399 | ctrl_outl(0x800, ioaddr + BCULR); | ||
400 | #endif | ||
401 | |||
331 | ctrl_outl((FIFO_F_D_RFF | FIFO_F_D_RFD), ioaddr + FCFTR); | 402 | ctrl_outl((FIFO_F_D_RFF | FIFO_F_D_RFD), ioaddr + FCFTR); |
332 | ctrl_outl(0, ioaddr + TRIMD); | ||
333 | 403 | ||
334 | /* Descriptor format */ | 404 | #if !defined(CONFIG_CPU_SUBTYPE_SH7763) |
335 | sh_eth_ring_format(ndev); | 405 | ctrl_outl(0, ioaddr + TRIMD); |
406 | #endif | ||
336 | 407 | ||
337 | ctrl_outl((u32)mdp->rx_ring, ioaddr + RDLAR); | 408 | /* Recv frame limit set register */ |
338 | ctrl_outl((u32)mdp->tx_ring, ioaddr + TDLAR); | 409 | ctrl_outl(RFLR_VALUE, ioaddr + RFLR); |
339 | 410 | ||
340 | ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR); | 411 | ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR); |
341 | ctrl_outl((DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff), ioaddr + EESIPR); | 412 | ctrl_outl((DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff), ioaddr + EESIPR); |
@@ -345,21 +416,26 @@ static int sh_eth_dev_init(struct net_device *ndev) | |||
345 | ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE; | 416 | ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE; |
346 | 417 | ||
347 | ctrl_outl(val, ioaddr + ECMR); | 418 | ctrl_outl(val, ioaddr + ECMR); |
348 | ctrl_outl(ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD | | 419 | |
349 | ECSIPR_MPDIP, ioaddr + ECSR); | 420 | /* E-MAC Status Register clear */ |
350 | ctrl_outl(ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | | 421 | ctrl_outl(ECSR_INIT, ioaddr + ECSR); |
351 | ECSIPR_ICDIP | ECSIPR_MPDIP, ioaddr + ECSIPR); | 422 | |
423 | /* E-MAC Interrupt Enable register */ | ||
424 | ctrl_outl(ECSIPR_INIT, ioaddr + ECSIPR); | ||
352 | 425 | ||
353 | /* Set MAC address */ | 426 | /* Set MAC address */ |
354 | update_mac_address(ndev); | 427 | update_mac_address(ndev); |
355 | 428 | ||
356 | /* mask reset */ | 429 | /* mask reset */ |
357 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) | 430 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7763) |
358 | ctrl_outl(APR_AP, ioaddr + APR); | 431 | ctrl_outl(APR_AP, ioaddr + APR); |
359 | ctrl_outl(MPR_MP, ioaddr + MPR); | 432 | ctrl_outl(MPR_MP, ioaddr + MPR); |
360 | ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER); | 433 | ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER); |
434 | #endif | ||
435 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) | ||
361 | ctrl_outl(BCFR_UNLIMITED, ioaddr + BCFR); | 436 | ctrl_outl(BCFR_UNLIMITED, ioaddr + BCFR); |
362 | #endif | 437 | #endif |
438 | |||
363 | /* Setting the Rx mode will start the Rx process. */ | 439 | /* Setting the Rx mode will start the Rx process. */ |
364 | ctrl_outl(EDRRR_R, ioaddr + EDRRR); | 440 | ctrl_outl(EDRRR_R, ioaddr + EDRRR); |
365 | 441 | ||
@@ -407,7 +483,7 @@ static int sh_eth_rx(struct net_device *ndev) | |||
407 | int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx; | 483 | int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx; |
408 | struct sk_buff *skb; | 484 | struct sk_buff *skb; |
409 | u16 pkt_len = 0; | 485 | u16 pkt_len = 0; |
410 | u32 desc_status; | 486 | u32 desc_status, reserve = 0; |
411 | 487 | ||
412 | rxdesc = &mdp->rx_ring[entry]; | 488 | rxdesc = &mdp->rx_ring[entry]; |
413 | while (!(rxdesc->status & cpu_to_le32(RD_RACT))) { | 489 | while (!(rxdesc->status & cpu_to_le32(RD_RACT))) { |
@@ -454,28 +530,38 @@ static int sh_eth_rx(struct net_device *ndev) | |||
454 | for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) { | 530 | for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) { |
455 | entry = mdp->dirty_rx % RX_RING_SIZE; | 531 | entry = mdp->dirty_rx % RX_RING_SIZE; |
456 | rxdesc = &mdp->rx_ring[entry]; | 532 | rxdesc = &mdp->rx_ring[entry]; |
533 | /* The size of the buffer is 16 byte boundary. */ | ||
534 | rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F; | ||
535 | |||
457 | if (mdp->rx_skbuff[entry] == NULL) { | 536 | if (mdp->rx_skbuff[entry] == NULL) { |
458 | skb = dev_alloc_skb(mdp->rx_buf_sz); | 537 | skb = dev_alloc_skb(mdp->rx_buf_sz); |
459 | mdp->rx_skbuff[entry] = skb; | 538 | mdp->rx_skbuff[entry] = skb; |
460 | if (skb == NULL) | 539 | if (skb == NULL) |
461 | break; /* Better luck next round. */ | 540 | break; /* Better luck next round. */ |
462 | skb->dev = ndev; | 541 | skb->dev = ndev; |
542 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
543 | reserve = SH7763_SKB_ALIGN | ||
544 | - ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1)); | ||
545 | if (reserve) | ||
546 | skb_reserve(skb, reserve); | ||
547 | #else | ||
463 | skb_reserve(skb, RX_OFFSET); | 548 | skb_reserve(skb, RX_OFFSET); |
549 | #endif | ||
550 | skb->ip_summed = CHECKSUM_NONE; | ||
464 | rxdesc->addr = (u32)skb->data & ~0x3UL; | 551 | rxdesc->addr = (u32)skb->data & ~0x3UL; |
465 | } | 552 | } |
466 | /* The size of the buffer is 16 byte boundary. */ | ||
467 | rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F; | ||
468 | if (entry >= RX_RING_SIZE - 1) | 553 | if (entry >= RX_RING_SIZE - 1) |
469 | rxdesc->status |= | 554 | rxdesc->status |= |
470 | cpu_to_le32(RD_RACT | RD_RFP | RC_RDEL); | 555 | cpu_to_le32(RD_RACT | RD_RFP | RD_RDEL); |
471 | else | 556 | else |
472 | rxdesc->status |= | 557 | rxdesc->status |= |
473 | cpu_to_le32(RD_RACT | RD_RFP); | 558 | cpu_to_le32(RD_RACT | RD_RFP); |
474 | } | 559 | } |
475 | 560 | ||
476 | /* Restart Rx engine if stopped. */ | 561 | /* Restart Rx engine if stopped. */ |
477 | /* If we don't need to check status, don't. -KDU */ | 562 | /* If we don't need to check status, don't. -KDU */ |
478 | ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR); | 563 | if (!(ctrl_inl(ndev->base_addr + EDRRR) & EDRRR_R)) |
564 | ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR); | ||
479 | 565 | ||
480 | return 0; | 566 | return 0; |
481 | } | 567 | } |
@@ -529,13 +615,14 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) | |||
529 | printk(KERN_ERR "Receive Frame Overflow\n"); | 615 | printk(KERN_ERR "Receive Frame Overflow\n"); |
530 | } | 616 | } |
531 | } | 617 | } |
532 | 618 | #if !defined(CONFIG_CPU_SUBTYPE_SH7763) | |
533 | if (intr_status & EESR_ADE) { | 619 | if (intr_status & EESR_ADE) { |
534 | if (intr_status & EESR_TDE) { | 620 | if (intr_status & EESR_TDE) { |
535 | if (intr_status & EESR_TFE) | 621 | if (intr_status & EESR_TFE) |
536 | mdp->stats.tx_fifo_errors++; | 622 | mdp->stats.tx_fifo_errors++; |
537 | } | 623 | } |
538 | } | 624 | } |
625 | #endif | ||
539 | 626 | ||
540 | if (intr_status & EESR_RDE) { | 627 | if (intr_status & EESR_RDE) { |
541 | /* Receive Descriptor Empty int */ | 628 | /* Receive Descriptor Empty int */ |
@@ -550,8 +637,11 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) | |||
550 | mdp->stats.rx_fifo_errors++; | 637 | mdp->stats.rx_fifo_errors++; |
551 | printk(KERN_ERR "Receive FIFO Overflow\n"); | 638 | printk(KERN_ERR "Receive FIFO Overflow\n"); |
552 | } | 639 | } |
553 | if (intr_status & | 640 | if (intr_status & (EESR_TWB | EESR_TABT | |
554 | (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)) { | 641 | #if !defined(CONFIG_CPU_SUBTYPE_SH7763) |
642 | EESR_ADE | | ||
643 | #endif | ||
644 | EESR_TDE | EESR_TFE)) { | ||
555 | /* Tx error */ | 645 | /* Tx error */ |
556 | u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR); | 646 | u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR); |
557 | /* dmesg */ | 647 | /* dmesg */ |
@@ -582,17 +672,23 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) | |||
582 | ioaddr = ndev->base_addr; | 672 | ioaddr = ndev->base_addr; |
583 | spin_lock(&mdp->lock); | 673 | spin_lock(&mdp->lock); |
584 | 674 | ||
675 | /* Get interrpt stat */ | ||
585 | intr_status = ctrl_inl(ioaddr + EESR); | 676 | intr_status = ctrl_inl(ioaddr + EESR); |
586 | /* Clear interrupt */ | 677 | /* Clear interrupt */ |
587 | ctrl_outl(intr_status, ioaddr + EESR); | 678 | ctrl_outl(intr_status, ioaddr + EESR); |
588 | 679 | ||
589 | if (intr_status & (EESR_FRC | EESR_RINT8 | | 680 | if (intr_status & (EESR_FRC | /* Frame recv*/ |
590 | EESR_RINT5 | EESR_RINT4 | EESR_RINT3 | EESR_RINT2 | | 681 | EESR_RMAF | /* Multi cast address recv*/ |
591 | EESR_RINT1)) | 682 | EESR_RRF | /* Bit frame recv */ |
683 | EESR_RTLF | /* Long frame recv*/ | ||
684 | EESR_RTSF | /* short frame recv */ | ||
685 | EESR_PRE | /* PHY-LSI recv error */ | ||
686 | EESR_CERF)){ /* recv frame CRC error */ | ||
592 | sh_eth_rx(ndev); | 687 | sh_eth_rx(ndev); |
593 | if (intr_status & (EESR_FTC | | 688 | } |
594 | EESR_TINT4 | EESR_TINT3 | EESR_TINT2 | EESR_TINT1)) { | ||
595 | 689 | ||
690 | /* Tx Check */ | ||
691 | if (intr_status & TX_CHECK) { | ||
596 | sh_eth_txfree(ndev); | 692 | sh_eth_txfree(ndev); |
597 | netif_wake_queue(ndev); | 693 | netif_wake_queue(ndev); |
598 | } | 694 | } |
@@ -631,11 +727,32 @@ static void sh_eth_adjust_link(struct net_device *ndev) | |||
631 | if (phydev->duplex != mdp->duplex) { | 727 | if (phydev->duplex != mdp->duplex) { |
632 | new_state = 1; | 728 | new_state = 1; |
633 | mdp->duplex = phydev->duplex; | 729 | mdp->duplex = phydev->duplex; |
730 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
731 | if (mdp->duplex) { /* FULL */ | ||
732 | ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, | ||
733 | ioaddr + ECMR); | ||
734 | } else { /* Half */ | ||
735 | ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, | ||
736 | ioaddr + ECMR); | ||
737 | } | ||
738 | #endif | ||
634 | } | 739 | } |
635 | 740 | ||
636 | if (phydev->speed != mdp->speed) { | 741 | if (phydev->speed != mdp->speed) { |
637 | new_state = 1; | 742 | new_state = 1; |
638 | mdp->speed = phydev->speed; | 743 | mdp->speed = phydev->speed; |
744 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
745 | switch (mdp->speed) { | ||
746 | case 10: /* 10BASE */ | ||
747 | ctrl_outl(GECMR_10, ioaddr + GECMR); break; | ||
748 | case 100:/* 100BASE */ | ||
749 | ctrl_outl(GECMR_100, ioaddr + GECMR); break; | ||
750 | case 1000: /* 1000BASE */ | ||
751 | ctrl_outl(GECMR_1000, ioaddr + GECMR); break; | ||
752 | default: | ||
753 | break; | ||
754 | } | ||
755 | #endif | ||
639 | } | 756 | } |
640 | if (mdp->link == PHY_DOWN) { | 757 | if (mdp->link == PHY_DOWN) { |
641 | ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF) | 758 | ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF) |
@@ -730,7 +847,7 @@ static int sh_eth_open(struct net_device *ndev) | |||
730 | /* Set the timer to check for link beat. */ | 847 | /* Set the timer to check for link beat. */ |
731 | init_timer(&mdp->timer); | 848 | init_timer(&mdp->timer); |
732 | mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */ | 849 | mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */ |
733 | setup_timer(&mdp->timer, sh_eth_timer, ndev); | 850 | setup_timer(&mdp->timer, sh_eth_timer, (unsigned long)ndev); |
734 | 851 | ||
735 | return ret; | 852 | return ret; |
736 | 853 | ||
@@ -820,7 +937,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
820 | 937 | ||
821 | mdp->cur_tx++; | 938 | mdp->cur_tx++; |
822 | 939 | ||
823 | ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); | 940 | if (!(ctrl_inl(ndev->base_addr + EDTRR) & EDTRR_TRNS)) |
941 | ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); | ||
942 | |||
824 | ndev->trans_start = jiffies; | 943 | ndev->trans_start = jiffies; |
825 | 944 | ||
826 | return 0; | 945 | return 0; |
@@ -877,9 +996,15 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) | |||
877 | ctrl_outl(0, ioaddr + CDCR); /* (write clear) */ | 996 | ctrl_outl(0, ioaddr + CDCR); /* (write clear) */ |
878 | mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR); | 997 | mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR); |
879 | ctrl_outl(0, ioaddr + LCCR); /* (write clear) */ | 998 | ctrl_outl(0, ioaddr + LCCR); /* (write clear) */ |
999 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
1000 | mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CERCR);/* CERCR */ | ||
1001 | ctrl_outl(0, ioaddr + CERCR); /* (write clear) */ | ||
1002 | mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CEECR);/* CEECR */ | ||
1003 | ctrl_outl(0, ioaddr + CEECR); /* (write clear) */ | ||
1004 | #else | ||
880 | mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR); | 1005 | mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR); |
881 | ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */ | 1006 | ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */ |
882 | 1007 | #endif | |
883 | return &mdp->stats; | 1008 | return &mdp->stats; |
884 | } | 1009 | } |
885 | 1010 | ||
@@ -929,8 +1054,13 @@ static void sh_eth_tsu_init(u32 ioaddr) | |||
929 | ctrl_outl(0, ioaddr + TSU_FWSL0); | 1054 | ctrl_outl(0, ioaddr + TSU_FWSL0); |
930 | ctrl_outl(0, ioaddr + TSU_FWSL1); | 1055 | ctrl_outl(0, ioaddr + TSU_FWSL1); |
931 | ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); | 1056 | ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); |
1057 | #if defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
1058 | ctrl_outl(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */ | ||
1059 | ctrl_outl(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */ | ||
1060 | #else | ||
932 | ctrl_outl(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ | 1061 | ctrl_outl(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ |
933 | ctrl_outl(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ | 1062 | ctrl_outl(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ |
1063 | #endif | ||
934 | ctrl_outl(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ | 1064 | ctrl_outl(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ |
935 | ctrl_outl(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ | 1065 | ctrl_outl(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ |
936 | ctrl_outl(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ | 1066 | ctrl_outl(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ |
@@ -1088,7 +1218,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
1088 | /* First device only init */ | 1218 | /* First device only init */ |
1089 | if (!devno) { | 1219 | if (!devno) { |
1090 | /* reset device */ | 1220 | /* reset device */ |
1091 | ctrl_outl(ARSTR_ARSTR, ndev->base_addr + ARSTR); | 1221 | ctrl_outl(ARSTR_ARSTR, ARSTR); |
1092 | mdelay(1); | 1222 | mdelay(1); |
1093 | 1223 | ||
1094 | /* TSU init (Init only)*/ | 1224 | /* TSU init (Init only)*/ |
@@ -1110,8 +1240,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
1110 | ndev->name, CARDNAME, (u32) ndev->base_addr); | 1240 | ndev->name, CARDNAME, (u32) ndev->base_addr); |
1111 | 1241 | ||
1112 | for (i = 0; i < 5; i++) | 1242 | for (i = 0; i < 5; i++) |
1113 | printk(KERN_INFO "%2.2x:", ndev->dev_addr[i]); | 1243 | printk(KERN_INFO "%02X:", ndev->dev_addr[i]); |
1114 | printk(KERN_INFO "%2.2x, IRQ %d.\n", ndev->dev_addr[i], ndev->irq); | 1244 | printk(KERN_INFO "%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq); |
1115 | 1245 | ||
1116 | platform_set_drvdata(pdev, ndev); | 1246 | platform_set_drvdata(pdev, ndev); |
1117 | 1247 | ||