diff options
| author | Jesper Nilsson <jesper.nilsson@axis.com> | 2007-11-14 20:00:55 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-14 21:45:45 -0500 |
| commit | bafef0ae9d3651540c442aebf242f7b68e183bff (patch) | |
| tree | eda2e9d52ba11602d22f70749930fc5dec9d868f /drivers/net/cris | |
| parent | eda35b64a7739691839ea997c836163ea12f123b (diff) | |
cris build fixes: update eth_v10.c ethernet driver
New (updated) version of ethernet driver for cris v10.
- First steps to simplify and make the MII code more similar
between the etrax100 and etraxfs ports.
- Start the transmit queue before enabling tx interrupts
to avoid race with the first frame.
- Flip the comparition statement to stick to physical addresses
to avoid phys_to_virt mapping a potential null pointer.
This was not an error but the change simplifies debugging
of address-space mappings.
- Made myPrevRxDesc local to e100_rx since it was only used there.
Fixed out of memory handling in e100_rx. If dev_alloc_skb() fails
persistently the system is hosed anyway but at least it won't
loop in an interrupt handler.
- Correct some code formatting issues.
- Add defines SET_ETH_ENABLE_LEDS, SET_ETH_DISABLE_LEDS
and SET_ETH_AUTONEG used in new cris v10 ethernet driver.
Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Acked-by: Mikael Starvik <starvik@axis.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/net/cris')
| -rw-r--r-- | drivers/net/cris/eth_v10.c | 428 |
1 files changed, 276 insertions, 152 deletions
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index edd6828f0a78..26ffa810e581 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c | |||
| @@ -250,6 +250,7 @@ | |||
| 250 | #include <asm/system.h> | 250 | #include <asm/system.h> |
| 251 | #include <asm/ethernet.h> | 251 | #include <asm/ethernet.h> |
| 252 | #include <asm/cache.h> | 252 | #include <asm/cache.h> |
| 253 | #include <asm/arch/io_interface_mux.h> | ||
| 253 | 254 | ||
| 254 | //#define ETHDEBUG | 255 | //#define ETHDEBUG |
| 255 | #define D(x) | 256 | #define D(x) |
| @@ -279,6 +280,9 @@ struct net_local { | |||
| 279 | * by this lock as well. | 280 | * by this lock as well. |
| 280 | */ | 281 | */ |
| 281 | spinlock_t lock; | 282 | spinlock_t lock; |
| 283 | |||
| 284 | spinlock_t led_lock; /* Protect LED state */ | ||
| 285 | spinlock_t transceiver_lock; /* Protect transceiver state. */ | ||
| 282 | }; | 286 | }; |
| 283 | 287 | ||
| 284 | typedef struct etrax_eth_descr | 288 | typedef struct etrax_eth_descr |
| @@ -295,8 +299,6 @@ struct transceiver_ops | |||
| 295 | void (*check_duplex)(struct net_device* dev); | 299 | void (*check_duplex)(struct net_device* dev); |
| 296 | }; | 300 | }; |
| 297 | 301 | ||
| 298 | struct transceiver_ops* transceiver; | ||
| 299 | |||
| 300 | /* Duplex settings */ | 302 | /* Duplex settings */ |
| 301 | enum duplex | 303 | enum duplex |
| 302 | { | 304 | { |
| @@ -307,7 +309,7 @@ enum duplex | |||
| 307 | 309 | ||
| 308 | /* Dma descriptors etc. */ | 310 | /* Dma descriptors etc. */ |
| 309 | 311 | ||
| 310 | #define MAX_MEDIA_DATA_SIZE 1518 | 312 | #define MAX_MEDIA_DATA_SIZE 1522 |
| 311 | 313 | ||
| 312 | #define MIN_PACKET_LEN 46 | 314 | #define MIN_PACKET_LEN 46 |
| 313 | #define ETHER_HEAD_LEN 14 | 315 | #define ETHER_HEAD_LEN 14 |
| @@ -332,8 +334,8 @@ enum duplex | |||
| 332 | 334 | ||
| 333 | /*Intel LXT972A specific*/ | 335 | /*Intel LXT972A specific*/ |
| 334 | #define MDIO_INT_STATUS_REG_2 0x0011 | 336 | #define MDIO_INT_STATUS_REG_2 0x0011 |
| 335 | #define MDIO_INT_FULL_DUPLEX_IND ( 1 << 9 ) | 337 | #define MDIO_INT_FULL_DUPLEX_IND (1 << 9) |
| 336 | #define MDIO_INT_SPEED ( 1 << 14 ) | 338 | #define MDIO_INT_SPEED (1 << 14) |
| 337 | 339 | ||
| 338 | /* Network flash constants */ | 340 | /* Network flash constants */ |
| 339 | #define NET_FLASH_TIME (HZ/50) /* 20 ms */ | 341 | #define NET_FLASH_TIME (HZ/50) /* 20 ms */ |
| @@ -344,8 +346,8 @@ enum duplex | |||
| 344 | #define NO_NETWORK_ACTIVITY 0 | 346 | #define NO_NETWORK_ACTIVITY 0 |
| 345 | #define NETWORK_ACTIVITY 1 | 347 | #define NETWORK_ACTIVITY 1 |
| 346 | 348 | ||
| 347 | #define NBR_OF_RX_DESC 64 | 349 | #define NBR_OF_RX_DESC 32 |
| 348 | #define NBR_OF_TX_DESC 256 | 350 | #define NBR_OF_TX_DESC 16 |
| 349 | 351 | ||
| 350 | /* Large packets are sent directly to upper layers while small packets are */ | 352 | /* Large packets are sent directly to upper layers while small packets are */ |
| 351 | /* copied (to reduce memory waste). The following constant decides the breakpoint */ | 353 | /* copied (to reduce memory waste). The following constant decides the breakpoint */ |
| @@ -367,7 +369,6 @@ enum duplex | |||
| 367 | static etrax_eth_descr *myNextRxDesc; /* Points to the next descriptor to | 369 | static etrax_eth_descr *myNextRxDesc; /* Points to the next descriptor to |
| 368 | to be processed */ | 370 | to be processed */ |
| 369 | static etrax_eth_descr *myLastRxDesc; /* The last processed descriptor */ | 371 | static etrax_eth_descr *myLastRxDesc; /* The last processed descriptor */ |
| 370 | static etrax_eth_descr *myPrevRxDesc; /* The descriptor right before myNextRxDesc */ | ||
| 371 | 372 | ||
| 372 | static etrax_eth_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(32))); | 373 | static etrax_eth_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(32))); |
| 373 | 374 | ||
| @@ -377,7 +378,6 @@ static etrax_eth_descr* myNextTxDesc; /* Next descriptor to use */ | |||
| 377 | static etrax_eth_descr TxDescList[NBR_OF_TX_DESC] __attribute__ ((aligned(32))); | 378 | static etrax_eth_descr TxDescList[NBR_OF_TX_DESC] __attribute__ ((aligned(32))); |
| 378 | 379 | ||
| 379 | static unsigned int network_rec_config_shadow = 0; | 380 | static unsigned int network_rec_config_shadow = 0; |
| 380 | static unsigned int mdio_phy_addr; /* Transciever address */ | ||
| 381 | 381 | ||
| 382 | static unsigned int network_tr_ctrl_shadow = 0; | 382 | static unsigned int network_tr_ctrl_shadow = 0; |
| 383 | 383 | ||
| @@ -411,7 +411,7 @@ static int e100_set_config(struct net_device* dev, struct ifmap* map); | |||
| 411 | static void e100_tx_timeout(struct net_device *dev); | 411 | static void e100_tx_timeout(struct net_device *dev); |
| 412 | static struct net_device_stats *e100_get_stats(struct net_device *dev); | 412 | static struct net_device_stats *e100_get_stats(struct net_device *dev); |
| 413 | static void set_multicast_list(struct net_device *dev); | 413 | static void set_multicast_list(struct net_device *dev); |
| 414 | static void e100_hardware_send_packet(char *buf, int length); | 414 | static void e100_hardware_send_packet(struct net_local* np, char *buf, int length); |
| 415 | static void update_rx_stats(struct net_device_stats *); | 415 | static void update_rx_stats(struct net_device_stats *); |
| 416 | static void update_tx_stats(struct net_device_stats *); | 416 | static void update_tx_stats(struct net_device_stats *); |
| 417 | static int e100_probe_transceiver(struct net_device* dev); | 417 | static int e100_probe_transceiver(struct net_device* dev); |
| @@ -434,7 +434,10 @@ static void e100_clear_network_leds(unsigned long dummy); | |||
| 434 | static void e100_set_network_leds(int active); | 434 | static void e100_set_network_leds(int active); |
| 435 | 435 | ||
| 436 | static const struct ethtool_ops e100_ethtool_ops; | 436 | static const struct ethtool_ops e100_ethtool_ops; |
| 437 | 437 | #if defined(CONFIG_ETRAX_NO_PHY) | |
| 438 | static void dummy_check_speed(struct net_device* dev); | ||
| 439 | static void dummy_check_duplex(struct net_device* dev); | ||
| 440 | #else | ||
| 438 | static void broadcom_check_speed(struct net_device* dev); | 441 | static void broadcom_check_speed(struct net_device* dev); |
| 439 | static void broadcom_check_duplex(struct net_device* dev); | 442 | static void broadcom_check_duplex(struct net_device* dev); |
| 440 | static void tdk_check_speed(struct net_device* dev); | 443 | static void tdk_check_speed(struct net_device* dev); |
| @@ -443,16 +446,28 @@ static void intel_check_speed(struct net_device* dev); | |||
| 443 | static void intel_check_duplex(struct net_device* dev); | 446 | static void intel_check_duplex(struct net_device* dev); |
| 444 | static void generic_check_speed(struct net_device* dev); | 447 | static void generic_check_speed(struct net_device* dev); |
| 445 | static void generic_check_duplex(struct net_device* dev); | 448 | static void generic_check_duplex(struct net_device* dev); |
| 449 | #endif | ||
| 450 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 451 | static void e100_netpoll(struct net_device* dev); | ||
| 452 | #endif | ||
| 453 | |||
| 454 | static int autoneg_normal = 1; | ||
| 446 | 455 | ||
| 447 | struct transceiver_ops transceivers[] = | 456 | struct transceiver_ops transceivers[] = |
| 448 | { | 457 | { |
| 458 | #if defined(CONFIG_ETRAX_NO_PHY) | ||
| 459 | {0x0000, dummy_check_speed, dummy_check_duplex} /* Dummy */ | ||
| 460 | #else | ||
| 449 | {0x1018, broadcom_check_speed, broadcom_check_duplex}, /* Broadcom */ | 461 | {0x1018, broadcom_check_speed, broadcom_check_duplex}, /* Broadcom */ |
| 450 | {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK 2120 */ | 462 | {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK 2120 */ |
| 451 | {0x039C, tdk_check_speed, tdk_check_duplex}, /* TDK 2120C */ | 463 | {0x039C, tdk_check_speed, tdk_check_duplex}, /* TDK 2120C */ |
| 452 | {0x04de, intel_check_speed, intel_check_duplex}, /* Intel LXT972A*/ | 464 | {0x04de, intel_check_speed, intel_check_duplex}, /* Intel LXT972A*/ |
| 453 | {0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */ | 465 | {0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */ |
| 466 | #endif | ||
| 454 | }; | 467 | }; |
| 455 | 468 | ||
| 469 | struct transceiver_ops* transceiver = &transceivers[0]; | ||
| 470 | |||
| 456 | #define tx_done(dev) (*R_DMA_CH0_CMD == 0) | 471 | #define tx_done(dev) (*R_DMA_CH0_CMD == 0) |
| 457 | 472 | ||
| 458 | /* | 473 | /* |
| @@ -471,14 +486,22 @@ etrax_ethernet_init(void) | |||
| 471 | int i, err; | 486 | int i, err; |
| 472 | 487 | ||
| 473 | printk(KERN_INFO | 488 | printk(KERN_INFO |
| 474 | "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2003 Axis Communications AB\n"); | 489 | "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 1998-2007 Axis Communications AB\n"); |
| 475 | 490 | ||
| 476 | dev = alloc_etherdev(sizeof(struct net_local)); | 491 | if (cris_request_io_interface(if_eth, cardname)) { |
| 477 | np = dev->priv; | 492 | printk(KERN_CRIT "etrax_ethernet_init failed to get IO interface\n"); |
| 493 | return -EBUSY; | ||
| 494 | } | ||
| 478 | 495 | ||
| 496 | dev = alloc_etherdev(sizeof(struct net_local)); | ||
| 479 | if (!dev) | 497 | if (!dev) |
| 480 | return -ENOMEM; | 498 | return -ENOMEM; |
| 481 | 499 | ||
| 500 | np = netdev_priv(dev); | ||
| 501 | |||
| 502 | /* we do our own locking */ | ||
| 503 | dev->features |= NETIF_F_LLTX; | ||
| 504 | |||
| 482 | dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */ | 505 | dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */ |
| 483 | 506 | ||
| 484 | /* now setup our etrax specific stuff */ | 507 | /* now setup our etrax specific stuff */ |
| @@ -498,14 +521,22 @@ etrax_ethernet_init(void) | |||
| 498 | dev->do_ioctl = e100_ioctl; | 521 | dev->do_ioctl = e100_ioctl; |
| 499 | dev->set_config = e100_set_config; | 522 | dev->set_config = e100_set_config; |
| 500 | dev->tx_timeout = e100_tx_timeout; | 523 | dev->tx_timeout = e100_tx_timeout; |
| 524 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 525 | dev->poll_controller = e100_netpoll; | ||
| 526 | #endif | ||
| 527 | |||
| 528 | spin_lock_init(&np->lock); | ||
| 529 | spin_lock_init(&np->led_lock); | ||
| 530 | spin_lock_init(&np->transceiver_lock); | ||
| 501 | 531 | ||
| 502 | /* Initialise the list of Etrax DMA-descriptors */ | 532 | /* Initialise the list of Etrax DMA-descriptors */ |
| 503 | 533 | ||
| 504 | /* Initialise receive descriptors */ | 534 | /* Initialise receive descriptors */ |
| 505 | 535 | ||
| 506 | for (i = 0; i < NBR_OF_RX_DESC; i++) { | 536 | for (i = 0; i < NBR_OF_RX_DESC; i++) { |
| 507 | /* Allocate two extra cachelines to make sure that buffer used by DMA | 537 | /* Allocate two extra cachelines to make sure that buffer used |
| 508 | * does not share cacheline with any other data (to avoid cache bug) | 538 | * by DMA does not share cacheline with any other data (to |
| 539 | * avoid cache bug) | ||
| 509 | */ | 540 | */ |
| 510 | RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); | 541 | RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); |
| 511 | if (!RxDescList[i].skb) | 542 | if (!RxDescList[i].skb) |
| @@ -541,7 +572,6 @@ etrax_ethernet_init(void) | |||
| 541 | 572 | ||
| 542 | myNextRxDesc = &RxDescList[0]; | 573 | myNextRxDesc = &RxDescList[0]; |
| 543 | myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1]; | 574 | myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1]; |
| 544 | myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1]; | ||
| 545 | myFirstTxDesc = &TxDescList[0]; | 575 | myFirstTxDesc = &TxDescList[0]; |
| 546 | myNextTxDesc = &TxDescList[0]; | 576 | myNextTxDesc = &TxDescList[0]; |
| 547 | myLastTxDesc = &TxDescList[NBR_OF_TX_DESC - 1]; | 577 | myLastTxDesc = &TxDescList[NBR_OF_TX_DESC - 1]; |
| @@ -562,10 +592,11 @@ etrax_ethernet_init(void) | |||
| 562 | current_speed = 10; | 592 | current_speed = 10; |
| 563 | current_speed_selection = 0; /* Auto */ | 593 | current_speed_selection = 0; /* Auto */ |
| 564 | speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; | 594 | speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; |
| 565 | duplex_timer.data = (unsigned long)dev; | 595 | speed_timer.data = (unsigned long)dev; |
| 566 | speed_timer.function = e100_check_speed; | 596 | speed_timer.function = e100_check_speed; |
| 567 | 597 | ||
| 568 | clear_led_timer.function = e100_clear_network_leds; | 598 | clear_led_timer.function = e100_clear_network_leds; |
| 599 | clear_led_timer.data = (unsigned long)dev; | ||
| 569 | 600 | ||
| 570 | full_duplex = 0; | 601 | full_duplex = 0; |
| 571 | current_duplex = autoneg; | 602 | current_duplex = autoneg; |
| @@ -574,7 +605,6 @@ etrax_ethernet_init(void) | |||
| 574 | duplex_timer.function = e100_check_duplex; | 605 | duplex_timer.function = e100_check_duplex; |
| 575 | 606 | ||
| 576 | /* Initialize mii interface */ | 607 | /* Initialize mii interface */ |
| 577 | np->mii_if.phy_id = mdio_phy_addr; | ||
| 578 | np->mii_if.phy_id_mask = 0x1f; | 608 | np->mii_if.phy_id_mask = 0x1f; |
| 579 | np->mii_if.reg_num_mask = 0x1f; | 609 | np->mii_if.reg_num_mask = 0x1f; |
| 580 | np->mii_if.dev = dev; | 610 | np->mii_if.dev = dev; |
| @@ -585,6 +615,9 @@ etrax_ethernet_init(void) | |||
| 585 | /* unwanted addresses are matched */ | 615 | /* unwanted addresses are matched */ |
| 586 | *R_NETWORK_GA_0 = 0x00000000; | 616 | *R_NETWORK_GA_0 = 0x00000000; |
| 587 | *R_NETWORK_GA_1 = 0x00000000; | 617 | *R_NETWORK_GA_1 = 0x00000000; |
| 618 | |||
| 619 | /* Initialize next time the led can flash */ | ||
| 620 | led_next_time = jiffies; | ||
| 588 | return 0; | 621 | return 0; |
| 589 | } | 622 | } |
| 590 | 623 | ||
| @@ -595,7 +628,7 @@ etrax_ethernet_init(void) | |||
| 595 | static int | 628 | static int |
| 596 | e100_set_mac_address(struct net_device *dev, void *p) | 629 | e100_set_mac_address(struct net_device *dev, void *p) |
| 597 | { | 630 | { |
| 598 | struct net_local *np = (struct net_local *)dev->priv; | 631 | struct net_local *np = netdev_priv(dev); |
| 599 | struct sockaddr *addr = p; | 632 | struct sockaddr *addr = p; |
| 600 | int i; | 633 | int i; |
| 601 | 634 | ||
| @@ -686,6 +719,25 @@ e100_open(struct net_device *dev) | |||
| 686 | goto grace_exit2; | 719 | goto grace_exit2; |
| 687 | } | 720 | } |
| 688 | 721 | ||
| 722 | /* | ||
| 723 | * Always allocate the DMA channels after the IRQ, | ||
| 724 | * and clean up on failure. | ||
| 725 | */ | ||
| 726 | |||
| 727 | if (cris_request_dma(NETWORK_TX_DMA_NBR, | ||
| 728 | cardname, | ||
| 729 | DMA_VERBOSE_ON_ERROR, | ||
| 730 | dma_eth)) { | ||
| 731 | goto grace_exit3; | ||
| 732 | } | ||
| 733 | |||
| 734 | if (cris_request_dma(NETWORK_RX_DMA_NBR, | ||
| 735 | cardname, | ||
| 736 | DMA_VERBOSE_ON_ERROR, | ||
| 737 | dma_eth)) { | ||
| 738 | goto grace_exit4; | ||
| 739 | } | ||
| 740 | |||
| 689 | /* give the HW an idea of what MAC address we want */ | 741 | /* give the HW an idea of what MAC address we want */ |
| 690 | 742 | ||
| 691 | *R_NETWORK_SA_0 = dev->dev_addr[0] | (dev->dev_addr[1] << 8) | | 743 | *R_NETWORK_SA_0 = dev->dev_addr[0] | (dev->dev_addr[1] << 8) | |
| @@ -700,6 +752,7 @@ e100_open(struct net_device *dev) | |||
| 700 | 752 | ||
| 701 | *R_NETWORK_REC_CONFIG = 0xd; /* broadcast rec, individ. rec, ma0 enabled */ | 753 | *R_NETWORK_REC_CONFIG = 0xd; /* broadcast rec, individ. rec, ma0 enabled */ |
| 702 | #else | 754 | #else |
| 755 | SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, max_size, size1522); | ||
| 703 | SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, broadcast, receive); | 756 | SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, broadcast, receive); |
| 704 | SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, ma0, enable); | 757 | SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, ma0, enable); |
| 705 | SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); | 758 | SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); |
| @@ -719,8 +772,7 @@ e100_open(struct net_device *dev) | |||
| 719 | SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, crc, enable); | 772 | SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, crc, enable); |
| 720 | *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; | 773 | *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; |
| 721 | 774 | ||
| 722 | save_flags(flags); | 775 | local_irq_save(flags); |
| 723 | cli(); | ||
| 724 | 776 | ||
| 725 | /* enable the irq's for ethernet DMA */ | 777 | /* enable the irq's for ethernet DMA */ |
| 726 | 778 | ||
| @@ -752,12 +804,13 @@ e100_open(struct net_device *dev) | |||
| 752 | 804 | ||
| 753 | *R_DMA_CH0_FIRST = 0; | 805 | *R_DMA_CH0_FIRST = 0; |
| 754 | *R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc); | 806 | *R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc); |
| 807 | netif_start_queue(dev); | ||
| 755 | 808 | ||
| 756 | restore_flags(flags); | 809 | local_irq_restore(flags); |
| 757 | 810 | ||
| 758 | /* Probe for transceiver */ | 811 | /* Probe for transceiver */ |
| 759 | if (e100_probe_transceiver(dev)) | 812 | if (e100_probe_transceiver(dev)) |
| 760 | goto grace_exit3; | 813 | goto grace_exit5; |
| 761 | 814 | ||
| 762 | /* Start duplex/speed timers */ | 815 | /* Start duplex/speed timers */ |
| 763 | add_timer(&speed_timer); | 816 | add_timer(&speed_timer); |
| @@ -766,10 +819,14 @@ e100_open(struct net_device *dev) | |||
| 766 | /* We are now ready to accept transmit requeusts from | 819 | /* We are now ready to accept transmit requeusts from |
| 767 | * the queueing layer of the networking. | 820 | * the queueing layer of the networking. |
| 768 | */ | 821 | */ |
| 769 | netif_start_queue(dev); | 822 | netif_carrier_on(dev); |
| 770 | 823 | ||
| 771 | return 0; | 824 | return 0; |
| 772 | 825 | ||
| 826 | grace_exit5: | ||
| 827 | cris_free_dma(NETWORK_RX_DMA_NBR, cardname); | ||
| 828 | grace_exit4: | ||
| 829 | cris_free_dma(NETWORK_TX_DMA_NBR, cardname); | ||
| 773 | grace_exit3: | 830 | grace_exit3: |
| 774 | free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev); | 831 | free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev); |
| 775 | grace_exit2: | 832 | grace_exit2: |
| @@ -780,12 +837,20 @@ grace_exit0: | |||
| 780 | return -EAGAIN; | 837 | return -EAGAIN; |
| 781 | } | 838 | } |
| 782 | 839 | ||
| 783 | 840 | #if defined(CONFIG_ETRAX_NO_PHY) | |
| 841 | static void | ||
| 842 | dummy_check_speed(struct net_device* dev) | ||
| 843 | { | ||
| 844 | current_speed = 100; | ||
| 845 | } | ||
| 846 | #else | ||
| 784 | static void | 847 | static void |
| 785 | generic_check_speed(struct net_device* dev) | 848 | generic_check_speed(struct net_device* dev) |
| 786 | { | 849 | { |
| 787 | unsigned long data; | 850 | unsigned long data; |
| 788 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE); | 851 | struct net_local *np = netdev_priv(dev); |
| 852 | |||
| 853 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE); | ||
| 789 | if ((data & ADVERTISE_100FULL) || | 854 | if ((data & ADVERTISE_100FULL) || |
| 790 | (data & ADVERTISE_100HALF)) | 855 | (data & ADVERTISE_100HALF)) |
| 791 | current_speed = 100; | 856 | current_speed = 100; |
| @@ -797,7 +862,10 @@ static void | |||
| 797 | tdk_check_speed(struct net_device* dev) | 862 | tdk_check_speed(struct net_device* dev) |
| 798 | { | 863 | { |
| 799 | unsigned long data; | 864 | unsigned long data; |
| 800 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_TDK_DIAGNOSTIC_REG); | 865 | struct net_local *np = netdev_priv(dev); |
| 866 | |||
| 867 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, | ||
| 868 | MDIO_TDK_DIAGNOSTIC_REG); | ||
| 801 | current_speed = (data & MDIO_TDK_DIAGNOSTIC_RATE ? 100 : 10); | 869 | current_speed = (data & MDIO_TDK_DIAGNOSTIC_RATE ? 100 : 10); |
| 802 | } | 870 | } |
| 803 | 871 | ||
| @@ -805,7 +873,10 @@ static void | |||
| 805 | broadcom_check_speed(struct net_device* dev) | 873 | broadcom_check_speed(struct net_device* dev) |
| 806 | { | 874 | { |
| 807 | unsigned long data; | 875 | unsigned long data; |
| 808 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_AUX_CTRL_STATUS_REG); | 876 | struct net_local *np = netdev_priv(dev); |
| 877 | |||
| 878 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, | ||
| 879 | MDIO_AUX_CTRL_STATUS_REG); | ||
| 809 | current_speed = (data & MDIO_BC_SPEED ? 100 : 10); | 880 | current_speed = (data & MDIO_BC_SPEED ? 100 : 10); |
| 810 | } | 881 | } |
| 811 | 882 | ||
| @@ -813,46 +884,62 @@ static void | |||
| 813 | intel_check_speed(struct net_device* dev) | 884 | intel_check_speed(struct net_device* dev) |
| 814 | { | 885 | { |
| 815 | unsigned long data; | 886 | unsigned long data; |
| 816 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_INT_STATUS_REG_2); | 887 | struct net_local *np = netdev_priv(dev); |
| 888 | |||
| 889 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, | ||
| 890 | MDIO_INT_STATUS_REG_2); | ||
| 817 | current_speed = (data & MDIO_INT_SPEED ? 100 : 10); | 891 | current_speed = (data & MDIO_INT_SPEED ? 100 : 10); |
| 818 | } | 892 | } |
| 819 | 893 | #endif | |
| 820 | static void | 894 | static void |
| 821 | e100_check_speed(unsigned long priv) | 895 | e100_check_speed(unsigned long priv) |
| 822 | { | 896 | { |
| 823 | struct net_device* dev = (struct net_device*)priv; | 897 | struct net_device* dev = (struct net_device*)priv; |
| 898 | struct net_local *np = netdev_priv(dev); | ||
| 824 | static int led_initiated = 0; | 899 | static int led_initiated = 0; |
| 825 | unsigned long data; | 900 | unsigned long data; |
| 826 | int old_speed = current_speed; | 901 | int old_speed = current_speed; |
| 827 | 902 | ||
| 828 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMSR); | 903 | spin_lock(&np->transceiver_lock); |
| 904 | |||
| 905 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMSR); | ||
| 829 | if (!(data & BMSR_LSTATUS)) { | 906 | if (!(data & BMSR_LSTATUS)) { |
| 830 | current_speed = 0; | 907 | current_speed = 0; |
| 831 | } else { | 908 | } else { |
| 832 | transceiver->check_speed(dev); | 909 | transceiver->check_speed(dev); |
| 833 | } | 910 | } |
| 834 | 911 | ||
| 912 | spin_lock(&np->led_lock); | ||
| 835 | if ((old_speed != current_speed) || !led_initiated) { | 913 | if ((old_speed != current_speed) || !led_initiated) { |
| 836 | led_initiated = 1; | 914 | led_initiated = 1; |
| 837 | e100_set_network_leds(NO_NETWORK_ACTIVITY); | 915 | e100_set_network_leds(NO_NETWORK_ACTIVITY); |
| 916 | if (current_speed) | ||
| 917 | netif_carrier_on(dev); | ||
| 918 | else | ||
| 919 | netif_carrier_off(dev); | ||
| 838 | } | 920 | } |
| 921 | spin_unlock(&np->led_lock); | ||
| 839 | 922 | ||
| 840 | /* Reinitialize the timer. */ | 923 | /* Reinitialize the timer. */ |
| 841 | speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; | 924 | speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; |
| 842 | add_timer(&speed_timer); | 925 | add_timer(&speed_timer); |
| 926 | |||
| 927 | spin_unlock(&np->transceiver_lock); | ||
| 843 | } | 928 | } |
| 844 | 929 | ||
| 845 | static void | 930 | static void |
| 846 | e100_negotiate(struct net_device* dev) | 931 | e100_negotiate(struct net_device* dev) |
| 847 | { | 932 | { |
| 848 | unsigned short data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE); | 933 | struct net_local *np = netdev_priv(dev); |
| 934 | unsigned short data = e100_get_mdio_reg(dev, np->mii_if.phy_id, | ||
| 935 | MII_ADVERTISE); | ||
| 849 | 936 | ||
| 850 | /* Discard old speed and duplex settings */ | 937 | /* Discard old speed and duplex settings */ |
| 851 | data &= ~(ADVERTISE_100HALF | ADVERTISE_100FULL | | 938 | data &= ~(ADVERTISE_100HALF | ADVERTISE_100FULL | |
| 852 | ADVERTISE_10HALF | ADVERTISE_10FULL); | 939 | ADVERTISE_10HALF | ADVERTISE_10FULL); |
| 853 | 940 | ||
| 854 | switch (current_speed_selection) { | 941 | switch (current_speed_selection) { |
| 855 | case 10 : | 942 | case 10: |
| 856 | if (current_duplex == full) | 943 | if (current_duplex == full) |
| 857 | data |= ADVERTISE_10FULL; | 944 | data |= ADVERTISE_10FULL; |
| 858 | else if (current_duplex == half) | 945 | else if (current_duplex == half) |
| @@ -861,7 +948,7 @@ e100_negotiate(struct net_device* dev) | |||
| 861 | data |= ADVERTISE_10HALF | ADVERTISE_10FULL; | 948 | data |= ADVERTISE_10HALF | ADVERTISE_10FULL; |
| 862 | break; | 949 | break; |
| 863 | 950 | ||
| 864 | case 100 : | 951 | case 100: |
| 865 | if (current_duplex == full) | 952 | if (current_duplex == full) |
| 866 | data |= ADVERTISE_100FULL; | 953 | data |= ADVERTISE_100FULL; |
| 867 | else if (current_duplex == half) | 954 | else if (current_duplex == half) |
| @@ -870,7 +957,7 @@ e100_negotiate(struct net_device* dev) | |||
| 870 | data |= ADVERTISE_100HALF | ADVERTISE_100FULL; | 957 | data |= ADVERTISE_100HALF | ADVERTISE_100FULL; |
| 871 | break; | 958 | break; |
| 872 | 959 | ||
| 873 | case 0 : /* Auto */ | 960 | case 0: /* Auto */ |
| 874 | if (current_duplex == full) | 961 | if (current_duplex == full) |
| 875 | data |= ADVERTISE_100FULL | ADVERTISE_10FULL; | 962 | data |= ADVERTISE_100FULL | ADVERTISE_10FULL; |
| 876 | else if (current_duplex == half) | 963 | else if (current_duplex == half) |
| @@ -880,35 +967,44 @@ e100_negotiate(struct net_device* dev) | |||
| 880 | ADVERTISE_100HALF | ADVERTISE_100FULL; | 967 | ADVERTISE_100HALF | ADVERTISE_100FULL; |
| 881 | break; | 968 | break; |
| 882 | 969 | ||
| 883 | default : /* assume autoneg speed and duplex */ | 970 | default: /* assume autoneg speed and duplex */ |
| 884 | data |= ADVERTISE_10HALF | ADVERTISE_10FULL | | 971 | data |= ADVERTISE_10HALF | ADVERTISE_10FULL | |
| 885 | ADVERTISE_100HALF | ADVERTISE_100FULL; | 972 | ADVERTISE_100HALF | ADVERTISE_100FULL; |
| 973 | break; | ||
| 886 | } | 974 | } |
| 887 | 975 | ||
| 888 | e100_set_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE, data); | 976 | e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE, data); |
| 889 | 977 | ||
| 890 | /* Renegotiate with link partner */ | 978 | /* Renegotiate with link partner */ |
| 891 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMCR); | 979 | if (autoneg_normal) { |
| 980 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR); | ||
| 892 | data |= BMCR_ANENABLE | BMCR_ANRESTART; | 981 | data |= BMCR_ANENABLE | BMCR_ANRESTART; |
| 893 | 982 | } | |
| 894 | e100_set_mdio_reg(dev, mdio_phy_addr, MII_BMCR, data); | 983 | e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR, data); |
| 895 | } | 984 | } |
| 896 | 985 | ||
| 897 | static void | 986 | static void |
| 898 | e100_set_speed(struct net_device* dev, unsigned long speed) | 987 | e100_set_speed(struct net_device* dev, unsigned long speed) |
| 899 | { | 988 | { |
| 989 | struct net_local *np = netdev_priv(dev); | ||
| 990 | |||
| 991 | spin_lock(&np->transceiver_lock); | ||
| 900 | if (speed != current_speed_selection) { | 992 | if (speed != current_speed_selection) { |
| 901 | current_speed_selection = speed; | 993 | current_speed_selection = speed; |
| 902 | e100_negotiate(dev); | 994 | e100_negotiate(dev); |
| 903 | } | 995 | } |
| 996 | spin_unlock(&np->transceiver_lock); | ||
| 904 | } | 997 | } |
| 905 | 998 | ||
| 906 | static void | 999 | static void |
| 907 | e100_check_duplex(unsigned long priv) | 1000 | e100_check_duplex(unsigned long priv) |
| 908 | { | 1001 | { |
| 909 | struct net_device *dev = (struct net_device *)priv; | 1002 | struct net_device *dev = (struct net_device *)priv; |
| 910 | struct net_local *np = (struct net_local *)dev->priv; | 1003 | struct net_local *np = netdev_priv(dev); |
| 911 | int old_duplex = full_duplex; | 1004 | int old_duplex; |
| 1005 | |||
| 1006 | spin_lock(&np->transceiver_lock); | ||
| 1007 | old_duplex = full_duplex; | ||
| 912 | transceiver->check_duplex(dev); | 1008 | transceiver->check_duplex(dev); |
| 913 | if (old_duplex != full_duplex) { | 1009 | if (old_duplex != full_duplex) { |
| 914 | /* Duplex changed */ | 1010 | /* Duplex changed */ |
| @@ -920,13 +1016,22 @@ e100_check_duplex(unsigned long priv) | |||
| 920 | duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL; | 1016 | duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL; |
| 921 | add_timer(&duplex_timer); | 1017 | add_timer(&duplex_timer); |
| 922 | np->mii_if.full_duplex = full_duplex; | 1018 | np->mii_if.full_duplex = full_duplex; |
| 1019 | spin_unlock(&np->transceiver_lock); | ||
| 923 | } | 1020 | } |
| 924 | 1021 | #if defined(CONFIG_ETRAX_NO_PHY) | |
| 1022 | static void | ||
| 1023 | dummy_check_duplex(struct net_device* dev) | ||
| 1024 | { | ||
| 1025 | full_duplex = 1; | ||
| 1026 | } | ||
| 1027 | #else | ||
| 925 | static void | 1028 | static void |
| 926 | generic_check_duplex(struct net_device* dev) | 1029 | generic_check_duplex(struct net_device* dev) |
| 927 | { | 1030 | { |
| 928 | unsigned long data; | 1031 | unsigned long data; |
| 929 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE); | 1032 | struct net_local *np = netdev_priv(dev); |
| 1033 | |||
| 1034 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE); | ||
| 930 | if ((data & ADVERTISE_10FULL) || | 1035 | if ((data & ADVERTISE_10FULL) || |
| 931 | (data & ADVERTISE_100FULL)) | 1036 | (data & ADVERTISE_100FULL)) |
| 932 | full_duplex = 1; | 1037 | full_duplex = 1; |
| @@ -938,7 +1043,10 @@ static void | |||
| 938 | tdk_check_duplex(struct net_device* dev) | 1043 | tdk_check_duplex(struct net_device* dev) |
| 939 | { | 1044 | { |
| 940 | unsigned long data; | 1045 | unsigned long data; |
| 941 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_TDK_DIAGNOSTIC_REG); | 1046 | struct net_local *np = netdev_priv(dev); |
| 1047 | |||
| 1048 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, | ||
| 1049 | MDIO_TDK_DIAGNOSTIC_REG); | ||
| 942 | full_duplex = (data & MDIO_TDK_DIAGNOSTIC_DPLX) ? 1 : 0; | 1050 | full_duplex = (data & MDIO_TDK_DIAGNOSTIC_DPLX) ? 1 : 0; |
| 943 | } | 1051 | } |
| 944 | 1052 | ||
| @@ -946,7 +1054,10 @@ static void | |||
| 946 | broadcom_check_duplex(struct net_device* dev) | 1054 | broadcom_check_duplex(struct net_device* dev) |
| 947 | { | 1055 | { |
| 948 | unsigned long data; | 1056 | unsigned long data; |
| 949 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_AUX_CTRL_STATUS_REG); | 1057 | struct net_local *np = netdev_priv(dev); |
| 1058 | |||
| 1059 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, | ||
| 1060 | MDIO_AUX_CTRL_STATUS_REG); | ||
| 950 | full_duplex = (data & MDIO_BC_FULL_DUPLEX_IND) ? 1 : 0; | 1061 | full_duplex = (data & MDIO_BC_FULL_DUPLEX_IND) ? 1 : 0; |
| 951 | } | 1062 | } |
| 952 | 1063 | ||
| @@ -954,38 +1065,51 @@ static void | |||
| 954 | intel_check_duplex(struct net_device* dev) | 1065 | intel_check_duplex(struct net_device* dev) |
| 955 | { | 1066 | { |
| 956 | unsigned long data; | 1067 | unsigned long data; |
| 957 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_INT_STATUS_REG_2); | 1068 | struct net_local *np = netdev_priv(dev); |
| 1069 | |||
| 1070 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, | ||
| 1071 | MDIO_INT_STATUS_REG_2); | ||
| 958 | full_duplex = (data & MDIO_INT_FULL_DUPLEX_IND) ? 1 : 0; | 1072 | full_duplex = (data & MDIO_INT_FULL_DUPLEX_IND) ? 1 : 0; |
| 959 | } | 1073 | } |
| 960 | 1074 | #endif | |
| 961 | static void | 1075 | static void |
| 962 | e100_set_duplex(struct net_device* dev, enum duplex new_duplex) | 1076 | e100_set_duplex(struct net_device* dev, enum duplex new_duplex) |
| 963 | { | 1077 | { |
| 1078 | struct net_local *np = netdev_priv(dev); | ||
| 1079 | |||
| 1080 | spin_lock(&np->transceiver_lock); | ||
| 964 | if (new_duplex != current_duplex) { | 1081 | if (new_duplex != current_duplex) { |
| 965 | current_duplex = new_duplex; | 1082 | current_duplex = new_duplex; |
| 966 | e100_negotiate(dev); | 1083 | e100_negotiate(dev); |
| 967 | } | 1084 | } |
| 1085 | spin_unlock(&np->transceiver_lock); | ||
| 968 | } | 1086 | } |
| 969 | 1087 | ||
| 970 | static int | 1088 | static int |
| 971 | e100_probe_transceiver(struct net_device* dev) | 1089 | e100_probe_transceiver(struct net_device* dev) |
| 972 | { | 1090 | { |
| 1091 | #if !defined(CONFIG_ETRAX_NO_PHY) | ||
| 973 | unsigned int phyid_high; | 1092 | unsigned int phyid_high; |
| 974 | unsigned int phyid_low; | 1093 | unsigned int phyid_low; |
| 975 | unsigned int oui; | 1094 | unsigned int oui; |
| 976 | struct transceiver_ops* ops = NULL; | 1095 | struct transceiver_ops* ops = NULL; |
| 1096 | struct net_local *np = netdev_priv(dev); | ||
| 1097 | |||
| 1098 | spin_lock(&np->transceiver_lock); | ||
| 977 | 1099 | ||
| 978 | /* Probe MDIO physical address */ | 1100 | /* Probe MDIO physical address */ |
| 979 | for (mdio_phy_addr = 0; mdio_phy_addr <= 31; mdio_phy_addr++) { | 1101 | for (np->mii_if.phy_id = 0; np->mii_if.phy_id <= 31; |
| 980 | if (e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMSR) != 0xffff) | 1102 | np->mii_if.phy_id++) { |
| 1103 | if (e100_get_mdio_reg(dev, | ||
| 1104 | np->mii_if.phy_id, MII_BMSR) != 0xffff) | ||
| 981 | break; | 1105 | break; |
| 982 | } | 1106 | } |
| 983 | if (mdio_phy_addr == 32) | 1107 | if (np->mii_if.phy_id == 32) |
| 984 | return -ENODEV; | 1108 | return -ENODEV; |
| 985 | 1109 | ||
| 986 | /* Get manufacturer */ | 1110 | /* Get manufacturer */ |
| 987 | phyid_high = e100_get_mdio_reg(dev, mdio_phy_addr, MII_PHYSID1); | 1111 | phyid_high = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_PHYSID1); |
| 988 | phyid_low = e100_get_mdio_reg(dev, mdio_phy_addr, MII_PHYSID2); | 1112 | phyid_low = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_PHYSID2); |
| 989 | oui = (phyid_high << 6) | (phyid_low >> 10); | 1113 | oui = (phyid_high << 6) | (phyid_low >> 10); |
| 990 | 1114 | ||
| 991 | for (ops = &transceivers[0]; ops->oui; ops++) { | 1115 | for (ops = &transceivers[0]; ops->oui; ops++) { |
| @@ -994,6 +1118,8 @@ e100_probe_transceiver(struct net_device* dev) | |||
| 994 | } | 1118 | } |
| 995 | transceiver = ops; | 1119 | transceiver = ops; |
| 996 | 1120 | ||
| 1121 | spin_unlock(&np->transceiver_lock); | ||
| 1122 | #endif | ||
| 997 | return 0; | 1123 | return 0; |
| 998 | } | 1124 | } |
| 999 | 1125 | ||
| @@ -1088,13 +1214,14 @@ e100_receive_mdio_bit() | |||
| 1088 | static void | 1214 | static void |
| 1089 | e100_reset_transceiver(struct net_device* dev) | 1215 | e100_reset_transceiver(struct net_device* dev) |
| 1090 | { | 1216 | { |
| 1217 | struct net_local *np = netdev_priv(dev); | ||
| 1091 | unsigned short cmd; | 1218 | unsigned short cmd; |
| 1092 | unsigned short data; | 1219 | unsigned short data; |
| 1093 | int bitCounter; | 1220 | int bitCounter; |
| 1094 | 1221 | ||
| 1095 | data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMCR); | 1222 | data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR); |
| 1096 | 1223 | ||
| 1097 | cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (MII_BMCR << 2); | 1224 | cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (np->mii_if.phy_id << 7) | (MII_BMCR << 2); |
| 1098 | 1225 | ||
| 1099 | e100_send_mdio_cmd(cmd, 1); | 1226 | e100_send_mdio_cmd(cmd, 1); |
| 1100 | 1227 | ||
| @@ -1112,7 +1239,7 @@ e100_reset_transceiver(struct net_device* dev) | |||
| 1112 | static void | 1239 | static void |
| 1113 | e100_tx_timeout(struct net_device *dev) | 1240 | e100_tx_timeout(struct net_device *dev) |
| 1114 | { | 1241 | { |
| 1115 | struct net_local *np = (struct net_local *)dev->priv; | 1242 | struct net_local *np = netdev_priv(dev); |
| 1116 | unsigned long flags; | 1243 | unsigned long flags; |
| 1117 | 1244 | ||
| 1118 | spin_lock_irqsave(&np->lock, flags); | 1245 | spin_lock_irqsave(&np->lock, flags); |
| @@ -1134,8 +1261,7 @@ e100_tx_timeout(struct net_device *dev) | |||
| 1134 | e100_reset_transceiver(dev); | 1261 | e100_reset_transceiver(dev); |
| 1135 | 1262 | ||
| 1136 | /* and get rid of the packets that never got an interrupt */ | 1263 | /* and get rid of the packets that never got an interrupt */ |
| 1137 | while (myFirstTxDesc != myNextTxDesc) | 1264 | while (myFirstTxDesc != myNextTxDesc) { |
| 1138 | { | ||
| 1139 | dev_kfree_skb(myFirstTxDesc->skb); | 1265 | dev_kfree_skb(myFirstTxDesc->skb); |
| 1140 | myFirstTxDesc->skb = 0; | 1266 | myFirstTxDesc->skb = 0; |
| 1141 | myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next); | 1267 | myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next); |
| @@ -1161,7 +1287,7 @@ e100_tx_timeout(struct net_device *dev) | |||
| 1161 | static int | 1287 | static int |
| 1162 | e100_send_packet(struct sk_buff *skb, struct net_device *dev) | 1288 | e100_send_packet(struct sk_buff *skb, struct net_device *dev) |
| 1163 | { | 1289 | { |
| 1164 | struct net_local *np = (struct net_local *)dev->priv; | 1290 | struct net_local *np = netdev_priv(dev); |
| 1165 | unsigned char *buf = skb->data; | 1291 | unsigned char *buf = skb->data; |
| 1166 | unsigned long flags; | 1292 | unsigned long flags; |
| 1167 | 1293 | ||
| @@ -1174,7 +1300,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 1174 | 1300 | ||
| 1175 | dev->trans_start = jiffies; | 1301 | dev->trans_start = jiffies; |
| 1176 | 1302 | ||
| 1177 | e100_hardware_send_packet(buf, skb->len); | 1303 | e100_hardware_send_packet(np, buf, skb->len); |
| 1178 | 1304 | ||
| 1179 | myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next); | 1305 | myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next); |
| 1180 | 1306 | ||
| @@ -1197,13 +1323,15 @@ static irqreturn_t | |||
| 1197 | e100rxtx_interrupt(int irq, void *dev_id) | 1323 | e100rxtx_interrupt(int irq, void *dev_id) |
| 1198 | { | 1324 | { |
| 1199 | struct net_device *dev = (struct net_device *)dev_id; | 1325 | struct net_device *dev = (struct net_device *)dev_id; |
| 1200 | struct net_local *np = (struct net_local *)dev->priv; | 1326 | struct net_local *np = netdev_priv(dev); |
| 1201 | unsigned long irqbits = *R_IRQ_MASK2_RD; | 1327 | unsigned long irqbits; |
| 1202 | 1328 | ||
| 1203 | /* Disable RX/TX IRQs to avoid reentrancy */ | 1329 | /* |
| 1204 | *R_IRQ_MASK2_CLR = | 1330 | * Note that both rx and tx interrupts are blocked at this point, |
| 1205 | IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) | | 1331 | * regardless of which got us here. |
| 1206 | IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr); | 1332 | */ |
| 1333 | |||
| 1334 | irqbits = *R_IRQ_MASK2_RD; | ||
| 1207 | 1335 | ||
| 1208 | /* Handle received packets */ | 1336 | /* Handle received packets */ |
| 1209 | if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma1_eop, active)) { | 1337 | if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma1_eop, active)) { |
| @@ -1219,7 +1347,7 @@ e100rxtx_interrupt(int irq, void *dev_id) | |||
| 1219 | * allocate a new buffer to put a packet in. | 1347 | * allocate a new buffer to put a packet in. |
| 1220 | */ | 1348 | */ |
| 1221 | e100_rx(dev); | 1349 | e100_rx(dev); |
| 1222 | ((struct net_local *)dev->priv)->stats.rx_packets++; | 1350 | np->stats.rx_packets++; |
| 1223 | /* restart/continue on the channel, for safety */ | 1351 | /* restart/continue on the channel, for safety */ |
| 1224 | *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart); | 1352 | *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart); |
| 1225 | /* clear dma channel 1 eop/descr irq bits */ | 1353 | /* clear dma channel 1 eop/descr irq bits */ |
| @@ -1233,9 +1361,8 @@ e100rxtx_interrupt(int irq, void *dev_id) | |||
| 1233 | } | 1361 | } |
| 1234 | 1362 | ||
| 1235 | /* Report any packets that have been sent */ | 1363 | /* Report any packets that have been sent */ |
| 1236 | while (myFirstTxDesc != phys_to_virt(*R_DMA_CH0_FIRST) && | 1364 | while (virt_to_phys(myFirstTxDesc) != *R_DMA_CH0_FIRST && |
| 1237 | myFirstTxDesc != myNextTxDesc) | 1365 | (netif_queue_stopped(dev) || myFirstTxDesc != myNextTxDesc)) { |
| 1238 | { | ||
| 1239 | np->stats.tx_bytes += myFirstTxDesc->skb->len; | 1366 | np->stats.tx_bytes += myFirstTxDesc->skb->len; |
| 1240 | np->stats.tx_packets++; | 1367 | np->stats.tx_packets++; |
| 1241 | 1368 | ||
| @@ -1244,19 +1371,15 @@ e100rxtx_interrupt(int irq, void *dev_id) | |||
| 1244 | dev_kfree_skb_irq(myFirstTxDesc->skb); | 1371 | dev_kfree_skb_irq(myFirstTxDesc->skb); |
| 1245 | myFirstTxDesc->skb = 0; | 1372 | myFirstTxDesc->skb = 0; |
| 1246 | myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next); | 1373 | myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next); |
| 1374 | /* Wake up queue. */ | ||
| 1375 | netif_wake_queue(dev); | ||
| 1247 | } | 1376 | } |
| 1248 | 1377 | ||
| 1249 | if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) { | 1378 | if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) { |
| 1250 | /* acknowledge the eop interrupt and wake up queue */ | 1379 | /* acknowledge the eop interrupt. */ |
| 1251 | *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do); | 1380 | *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do); |
| 1252 | netif_wake_queue(dev); | ||
| 1253 | } | 1381 | } |
| 1254 | 1382 | ||
| 1255 | /* Enable RX/TX IRQs again */ | ||
| 1256 | *R_IRQ_MASK2_SET = | ||
| 1257 | IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) | | ||
| 1258 | IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); | ||
| 1259 | |||
| 1260 | return IRQ_HANDLED; | 1383 | return IRQ_HANDLED; |
| 1261 | } | 1384 | } |
| 1262 | 1385 | ||
| @@ -1264,7 +1387,7 @@ static irqreturn_t | |||
| 1264 | e100nw_interrupt(int irq, void *dev_id) | 1387 | e100nw_interrupt(int irq, void *dev_id) |
| 1265 | { | 1388 | { |
| 1266 | struct net_device *dev = (struct net_device *)dev_id; | 1389 | struct net_device *dev = (struct net_device *)dev_id; |
| 1267 | struct net_local *np = (struct net_local *)dev->priv; | 1390 | struct net_local *np = netdev_priv(dev); |
| 1268 | unsigned long irqbits = *R_IRQ_MASK0_RD; | 1391 | unsigned long irqbits = *R_IRQ_MASK0_RD; |
| 1269 | 1392 | ||
| 1270 | /* check for underrun irq */ | 1393 | /* check for underrun irq */ |
| @@ -1286,7 +1409,6 @@ e100nw_interrupt(int irq, void *dev_id) | |||
| 1286 | SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); | 1409 | SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); |
| 1287 | *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; | 1410 | *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; |
| 1288 | SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop); | 1411 | SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop); |
| 1289 | *R_NETWORK_TR_CTRL = IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr); | ||
| 1290 | np->stats.tx_errors++; | 1412 | np->stats.tx_errors++; |
| 1291 | D(printk("ethernet excessive collisions!\n")); | 1413 | D(printk("ethernet excessive collisions!\n")); |
| 1292 | } | 1414 | } |
| @@ -1299,12 +1421,13 @@ e100_rx(struct net_device *dev) | |||
| 1299 | { | 1421 | { |
| 1300 | struct sk_buff *skb; | 1422 | struct sk_buff *skb; |
| 1301 | int length = 0; | 1423 | int length = 0; |
| 1302 | struct net_local *np = (struct net_local *)dev->priv; | 1424 | struct net_local *np = netdev_priv(dev); |
| 1303 | unsigned char *skb_data_ptr; | 1425 | unsigned char *skb_data_ptr; |
| 1304 | #ifdef ETHDEBUG | 1426 | #ifdef ETHDEBUG |
| 1305 | int i; | 1427 | int i; |
| 1306 | #endif | 1428 | #endif |
| 1307 | 1429 | etrax_eth_descr *prevRxDesc; /* The descriptor right before myNextRxDesc */ | |
| 1430 | spin_lock(&np->led_lock); | ||
| 1308 | if (!led_active && time_after(jiffies, led_next_time)) { | 1431 | if (!led_active && time_after(jiffies, led_next_time)) { |
| 1309 | /* light the network leds depending on the current speed. */ | 1432 | /* light the network leds depending on the current speed. */ |
| 1310 | e100_set_network_leds(NETWORK_ACTIVITY); | 1433 | e100_set_network_leds(NETWORK_ACTIVITY); |
| @@ -1314,9 +1437,10 @@ e100_rx(struct net_device *dev) | |||
| 1314 | led_active = 1; | 1437 | led_active = 1; |
| 1315 | mod_timer(&clear_led_timer, jiffies + HZ/10); | 1438 | mod_timer(&clear_led_timer, jiffies + HZ/10); |
| 1316 | } | 1439 | } |
| 1440 | spin_unlock(&np->led_lock); | ||
| 1317 | 1441 | ||
| 1318 | length = myNextRxDesc->descr.hw_len - 4; | 1442 | length = myNextRxDesc->descr.hw_len - 4; |
| 1319 | ((struct net_local *)dev->priv)->stats.rx_bytes += length; | 1443 | np->stats.rx_bytes += length; |
| 1320 | 1444 | ||
| 1321 | #ifdef ETHDEBUG | 1445 | #ifdef ETHDEBUG |
| 1322 | printk("Got a packet of length %d:\n", length); | 1446 | printk("Got a packet of length %d:\n", length); |
| @@ -1336,7 +1460,7 @@ e100_rx(struct net_device *dev) | |||
| 1336 | if (!skb) { | 1460 | if (!skb) { |
| 1337 | np->stats.rx_errors++; | 1461 | np->stats.rx_errors++; |
| 1338 | printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); | 1462 | printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); |
| 1339 | return; | 1463 | goto update_nextrxdesc; |
| 1340 | } | 1464 | } |
| 1341 | 1465 | ||
| 1342 | skb_put(skb, length - ETHER_HEAD_LEN); /* allocate room for the packet body */ | 1466 | skb_put(skb, length - ETHER_HEAD_LEN); /* allocate room for the packet body */ |
| @@ -1354,15 +1478,15 @@ e100_rx(struct net_device *dev) | |||
| 1354 | else { | 1478 | else { |
| 1355 | /* Large packet, send directly to upper layers and allocate new | 1479 | /* Large packet, send directly to upper layers and allocate new |
| 1356 | * memory (aligned to cache line boundary to avoid bug). | 1480 | * memory (aligned to cache line boundary to avoid bug). |
| 1357 | * Before sending the skb to upper layers we must make sure that | 1481 | * Before sending the skb to upper layers we must make sure |
| 1358 | * skb->data points to the aligned start of the packet. | 1482 | * that skb->data points to the aligned start of the packet. |
| 1359 | */ | 1483 | */ |
| 1360 | int align; | 1484 | int align; |
| 1361 | struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); | 1485 | struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); |
| 1362 | if (!new_skb) { | 1486 | if (!new_skb) { |
| 1363 | np->stats.rx_errors++; | 1487 | np->stats.rx_errors++; |
| 1364 | printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); | 1488 | printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); |
| 1365 | return; | 1489 | goto update_nextrxdesc; |
| 1366 | } | 1490 | } |
| 1367 | skb = myNextRxDesc->skb; | 1491 | skb = myNextRxDesc->skb; |
| 1368 | align = (int)phys_to_virt(myNextRxDesc->descr.buf) - (int)skb->data; | 1492 | align = (int)phys_to_virt(myNextRxDesc->descr.buf) - (int)skb->data; |
| @@ -1377,9 +1501,10 @@ e100_rx(struct net_device *dev) | |||
| 1377 | /* Send the packet to the upper layers */ | 1501 | /* Send the packet to the upper layers */ |
| 1378 | netif_rx(skb); | 1502 | netif_rx(skb); |
| 1379 | 1503 | ||
| 1504 | update_nextrxdesc: | ||
| 1380 | /* Prepare for next packet */ | 1505 | /* Prepare for next packet */ |
| 1381 | myNextRxDesc->descr.status = 0; | 1506 | myNextRxDesc->descr.status = 0; |
| 1382 | myPrevRxDesc = myNextRxDesc; | 1507 | prevRxDesc = myNextRxDesc; |
| 1383 | myNextRxDesc = phys_to_virt(myNextRxDesc->descr.next); | 1508 | myNextRxDesc = phys_to_virt(myNextRxDesc->descr.next); |
| 1384 | 1509 | ||
| 1385 | rx_queue_len++; | 1510 | rx_queue_len++; |
| @@ -1387,9 +1512,9 @@ e100_rx(struct net_device *dev) | |||
| 1387 | /* Check if descriptors should be returned */ | 1512 | /* Check if descriptors should be returned */ |
| 1388 | if (rx_queue_len == RX_QUEUE_THRESHOLD) { | 1513 | if (rx_queue_len == RX_QUEUE_THRESHOLD) { |
| 1389 | flush_etrax_cache(); | 1514 | flush_etrax_cache(); |
| 1390 | myPrevRxDesc->descr.ctrl |= d_eol; | 1515 | prevRxDesc->descr.ctrl |= d_eol; |
| 1391 | myLastRxDesc->descr.ctrl &= ~d_eol; | 1516 | myLastRxDesc->descr.ctrl &= ~d_eol; |
| 1392 | myLastRxDesc = myPrevRxDesc; | 1517 | myLastRxDesc = prevRxDesc; |
| 1393 | rx_queue_len = 0; | 1518 | rx_queue_len = 0; |
| 1394 | } | 1519 | } |
| 1395 | } | 1520 | } |
| @@ -1398,7 +1523,7 @@ e100_rx(struct net_device *dev) | |||
| 1398 | static int | 1523 | static int |
| 1399 | e100_close(struct net_device *dev) | 1524 | e100_close(struct net_device *dev) |
| 1400 | { | 1525 | { |
| 1401 | struct net_local *np = (struct net_local *)dev->priv; | 1526 | struct net_local *np = netdev_priv(dev); |
| 1402 | 1527 | ||
| 1403 | printk(KERN_INFO "Closing %s.\n", dev->name); | 1528 | printk(KERN_INFO "Closing %s.\n", dev->name); |
| 1404 | 1529 | ||
| @@ -1426,6 +1551,9 @@ e100_close(struct net_device *dev) | |||
| 1426 | free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev); | 1551 | free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev); |
| 1427 | free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev); | 1552 | free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev); |
| 1428 | 1553 | ||
| 1554 | cris_free_dma(NETWORK_TX_DMA_NBR, cardname); | ||
| 1555 | cris_free_dma(NETWORK_RX_DMA_NBR, cardname); | ||
| 1556 | |||
| 1429 | /* Update the statistics here. */ | 1557 | /* Update the statistics here. */ |
| 1430 | 1558 | ||
| 1431 | update_rx_stats(&np->stats); | 1559 | update_rx_stats(&np->stats); |
| @@ -1443,18 +1571,11 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 1443 | { | 1571 | { |
| 1444 | struct mii_ioctl_data *data = if_mii(ifr); | 1572 | struct mii_ioctl_data *data = if_mii(ifr); |
| 1445 | struct net_local *np = netdev_priv(dev); | 1573 | struct net_local *np = netdev_priv(dev); |
| 1574 | int rc = 0; | ||
| 1575 | int old_autoneg; | ||
| 1446 | 1576 | ||
| 1447 | spin_lock(&np->lock); /* Preempt protection */ | 1577 | spin_lock(&np->lock); /* Preempt protection */ |
| 1448 | switch (cmd) { | 1578 | switch (cmd) { |
| 1449 | case SIOCGMIIPHY: /* Get PHY address */ | ||
| 1450 | data->phy_id = mdio_phy_addr; | ||
| 1451 | break; | ||
| 1452 | case SIOCGMIIREG: /* Read MII register */ | ||
| 1453 | data->val_out = e100_get_mdio_reg(dev, mdio_phy_addr, data->reg_num); | ||
| 1454 | break; | ||
| 1455 | case SIOCSMIIREG: /* Write MII register */ | ||
| 1456 | e100_set_mdio_reg(dev, mdio_phy_addr, data->reg_num, data->val_in); | ||
| 1457 | break; | ||
| 1458 | /* The ioctls below should be considered obsolete but are */ | 1579 | /* The ioctls below should be considered obsolete but are */ |
| 1459 | /* still present for compatability with old scripts/apps */ | 1580 | /* still present for compatability with old scripts/apps */ |
| 1460 | case SET_ETH_SPEED_10: /* 10 Mbps */ | 1581 | case SET_ETH_SPEED_10: /* 10 Mbps */ |
| @@ -1463,60 +1584,47 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 1463 | case SET_ETH_SPEED_100: /* 100 Mbps */ | 1584 | case SET_ETH_SPEED_100: /* 100 Mbps */ |
| 1464 | e100_set_speed(dev, 100); | 1585 | e100_set_speed(dev, 100); |
| 1465 | break; | 1586 | break; |
| 1466 | case SET_ETH_SPEED_AUTO: /* Auto negotiate speed */ | 1587 | case SET_ETH_SPEED_AUTO: /* Auto-negotiate speed */ |
| 1467 | e100_set_speed(dev, 0); | 1588 | e100_set_speed(dev, 0); |
| 1468 | break; | 1589 | break; |
| 1469 | case SET_ETH_DUPLEX_HALF: /* Half duplex. */ | 1590 | case SET_ETH_DUPLEX_HALF: /* Half duplex */ |
| 1470 | e100_set_duplex(dev, half); | 1591 | e100_set_duplex(dev, half); |
| 1471 | break; | 1592 | break; |
| 1472 | case SET_ETH_DUPLEX_FULL: /* Full duplex. */ | 1593 | case SET_ETH_DUPLEX_FULL: /* Full duplex */ |
| 1473 | e100_set_duplex(dev, full); | 1594 | e100_set_duplex(dev, full); |
| 1474 | break; | 1595 | break; |
| 1475 | case SET_ETH_DUPLEX_AUTO: /* Autonegotiate duplex*/ | 1596 | case SET_ETH_DUPLEX_AUTO: /* Auto-negotiate duplex */ |
| 1476 | e100_set_duplex(dev, autoneg); | 1597 | e100_set_duplex(dev, autoneg); |
| 1477 | break; | 1598 | break; |
| 1599 | case SET_ETH_AUTONEG: | ||
| 1600 | old_autoneg = autoneg_normal; | ||
| 1601 | autoneg_normal = *(int*)data; | ||
| 1602 | if (autoneg_normal != old_autoneg) | ||
| 1603 | e100_negotiate(dev); | ||
| 1604 | break; | ||
| 1478 | default: | 1605 | default: |
| 1479 | return -EINVAL; | 1606 | rc = generic_mii_ioctl(&np->mii_if, if_mii(ifr), |
| 1607 | cmd, NULL); | ||
| 1608 | break; | ||
| 1480 | } | 1609 | } |
| 1481 | spin_unlock(&np->lock); | 1610 | spin_unlock(&np->lock); |
| 1482 | return 0; | 1611 | return rc; |
| 1483 | } | 1612 | } |
| 1484 | 1613 | ||
| 1485 | static int e100_set_settings(struct net_device *dev, | 1614 | static int e100_get_settings(struct net_device *dev, |
| 1486 | struct ethtool_cmd *ecmd) | 1615 | struct ethtool_cmd *cmd) |
| 1487 | { | 1616 | { |
| 1488 | ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | | 1617 | struct net_local *np = netdev_priv(dev); |
| 1489 | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | | 1618 | int err; |
| 1490 | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; | ||
| 1491 | ecmd->port = PORT_TP; | ||
| 1492 | ecmd->transceiver = XCVR_EXTERNAL; | ||
| 1493 | ecmd->phy_address = mdio_phy_addr; | ||
| 1494 | ecmd->speed = current_speed; | ||
| 1495 | ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; | ||
| 1496 | ecmd->advertising = ADVERTISED_TP; | ||
| 1497 | 1619 | ||
| 1498 | if (current_duplex == autoneg && current_speed_selection == 0) | 1620 | spin_lock_irq(&np->lock); |
| 1499 | ecmd->advertising |= ADVERTISED_Autoneg; | 1621 | err = mii_ethtool_gset(&np->mii_if, cmd); |
| 1500 | else { | 1622 | spin_unlock_irq(&np->lock); |
| 1501 | ecmd->advertising |= | ||
| 1502 | ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | | ||
| 1503 | ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; | ||
| 1504 | if (current_speed_selection == 10) | ||
| 1505 | ecmd->advertising &= ~(ADVERTISED_100baseT_Half | | ||
| 1506 | ADVERTISED_100baseT_Full); | ||
| 1507 | else if (current_speed_selection == 100) | ||
| 1508 | ecmd->advertising &= ~(ADVERTISED_10baseT_Half | | ||
| 1509 | ADVERTISED_10baseT_Full); | ||
| 1510 | if (current_duplex == half) | ||
| 1511 | ecmd->advertising &= ~(ADVERTISED_10baseT_Full | | ||
| 1512 | ADVERTISED_100baseT_Full); | ||
| 1513 | else if (current_duplex == full) | ||
| 1514 | ecmd->advertising &= ~(ADVERTISED_10baseT_Half | | ||
| 1515 | ADVERTISED_100baseT_Half); | ||
| 1516 | } | ||
| 1517 | 1623 | ||
| 1518 | ecmd->autoneg = AUTONEG_ENABLE; | 1624 | /* The PHY may support 1000baseT, but the Etrax100 does not. */ |
| 1519 | return 0; | 1625 | cmd->supported &= ~(SUPPORTED_1000baseT_Half |
| 1626 | | SUPPORTED_1000baseT_Full); | ||
| 1627 | return err; | ||
| 1520 | } | 1628 | } |
| 1521 | 1629 | ||
| 1522 | static int e100_set_settings(struct net_device *dev, | 1630 | static int e100_set_settings(struct net_device *dev, |
| @@ -1560,7 +1668,8 @@ static const struct ethtool_ops e100_ethtool_ops = { | |||
| 1560 | static int | 1668 | static int |
| 1561 | e100_set_config(struct net_device *dev, struct ifmap *map) | 1669 | e100_set_config(struct net_device *dev, struct ifmap *map) |
| 1562 | { | 1670 | { |
| 1563 | struct net_local *np = (struct net_local *)dev->priv; | 1671 | struct net_local *np = netdev_priv(dev); |
| 1672 | |||
| 1564 | spin_lock(&np->lock); /* Preempt protection */ | 1673 | spin_lock(&np->lock); /* Preempt protection */ |
| 1565 | 1674 | ||
| 1566 | switch(map->port) { | 1675 | switch(map->port) { |
| @@ -1612,7 +1721,6 @@ update_tx_stats(struct net_device_stats *es) | |||
| 1612 | es->collisions += | 1721 | es->collisions += |
| 1613 | IO_EXTRACT(R_TR_COUNTERS, single_col, r) + | 1722 | IO_EXTRACT(R_TR_COUNTERS, single_col, r) + |
| 1614 | IO_EXTRACT(R_TR_COUNTERS, multiple_col, r); | 1723 | IO_EXTRACT(R_TR_COUNTERS, multiple_col, r); |
| 1615 | es->tx_errors += IO_EXTRACT(R_TR_COUNTERS, deferred, r); | ||
| 1616 | } | 1724 | } |
| 1617 | 1725 | ||
| 1618 | /* | 1726 | /* |
| @@ -1622,8 +1730,9 @@ update_tx_stats(struct net_device_stats *es) | |||
| 1622 | static struct net_device_stats * | 1730 | static struct net_device_stats * |
| 1623 | e100_get_stats(struct net_device *dev) | 1731 | e100_get_stats(struct net_device *dev) |
| 1624 | { | 1732 | { |
| 1625 | struct net_local *lp = (struct net_local *)dev->priv; | 1733 | struct net_local *lp = netdev_priv(dev); |
| 1626 | unsigned long flags; | 1734 | unsigned long flags; |
| 1735 | |||
| 1627 | spin_lock_irqsave(&lp->lock, flags); | 1736 | spin_lock_irqsave(&lp->lock, flags); |
| 1628 | 1737 | ||
| 1629 | update_rx_stats(&lp->stats); | 1738 | update_rx_stats(&lp->stats); |
| @@ -1643,13 +1752,13 @@ e100_get_stats(struct net_device *dev) | |||
| 1643 | static void | 1752 | static void |
| 1644 | set_multicast_list(struct net_device *dev) | 1753 | set_multicast_list(struct net_device *dev) |
| 1645 | { | 1754 | { |
| 1646 | struct net_local *lp = (struct net_local *)dev->priv; | 1755 | struct net_local *lp = netdev_priv(dev); |
| 1647 | int num_addr = dev->mc_count; | 1756 | int num_addr = dev->mc_count; |
| 1648 | unsigned long int lo_bits; | 1757 | unsigned long int lo_bits; |
| 1649 | unsigned long int hi_bits; | 1758 | unsigned long int hi_bits; |
| 1759 | |||
| 1650 | spin_lock(&lp->lock); | 1760 | spin_lock(&lp->lock); |
| 1651 | if (dev->flags & IFF_PROMISC) | 1761 | if (dev->flags & IFF_PROMISC) { |
| 1652 | { | ||
| 1653 | /* promiscuous mode */ | 1762 | /* promiscuous mode */ |
| 1654 | lo_bits = 0xfffffffful; | 1763 | lo_bits = 0xfffffffful; |
| 1655 | hi_bits = 0xfffffffful; | 1764 | hi_bits = 0xfffffffful; |
| @@ -1679,9 +1788,10 @@ set_multicast_list(struct net_device *dev) | |||
| 1679 | struct dev_mc_list *dmi = dev->mc_list; | 1788 | struct dev_mc_list *dmi = dev->mc_list; |
| 1680 | int i; | 1789 | int i; |
| 1681 | char *baddr; | 1790 | char *baddr; |
| 1791 | |||
| 1682 | lo_bits = 0x00000000ul; | 1792 | lo_bits = 0x00000000ul; |
| 1683 | hi_bits = 0x00000000ul; | 1793 | hi_bits = 0x00000000ul; |
| 1684 | for (i=0; i<num_addr; i++) { | 1794 | for (i = 0; i < num_addr; i++) { |
| 1685 | /* Calculate the hash index for the GA registers */ | 1795 | /* Calculate the hash index for the GA registers */ |
| 1686 | 1796 | ||
| 1687 | hash_ix = 0; | 1797 | hash_ix = 0; |
| @@ -1708,8 +1818,7 @@ set_multicast_list(struct net_device *dev) | |||
| 1708 | 1818 | ||
| 1709 | if (hash_ix >= 32) { | 1819 | if (hash_ix >= 32) { |
| 1710 | hi_bits |= (1 << (hash_ix-32)); | 1820 | hi_bits |= (1 << (hash_ix-32)); |
| 1711 | } | 1821 | } else { |
| 1712 | else { | ||
| 1713 | lo_bits |= (1 << hash_ix); | 1822 | lo_bits |= (1 << hash_ix); |
| 1714 | } | 1823 | } |
| 1715 | dmi = dmi->next; | 1824 | dmi = dmi->next; |
| @@ -1724,10 +1833,11 @@ set_multicast_list(struct net_device *dev) | |||
| 1724 | } | 1833 | } |
| 1725 | 1834 | ||
| 1726 | void | 1835 | void |
| 1727 | e100_hardware_send_packet(char *buf, int length) | 1836 | e100_hardware_send_packet(struct net_local *np, char *buf, int length) |
| 1728 | { | 1837 | { |
| 1729 | D(printk("e100 send pack, buf 0x%x len %d\n", buf, length)); | 1838 | D(printk("e100 send pack, buf 0x%x len %d\n", buf, length)); |
| 1730 | 1839 | ||
| 1840 | spin_lock(&np->led_lock); | ||
| 1731 | if (!led_active && time_after(jiffies, led_next_time)) { | 1841 | if (!led_active && time_after(jiffies, led_next_time)) { |
| 1732 | /* light the network leds depending on the current speed. */ | 1842 | /* light the network leds depending on the current speed. */ |
| 1733 | e100_set_network_leds(NETWORK_ACTIVITY); | 1843 | e100_set_network_leds(NETWORK_ACTIVITY); |
| @@ -1737,6 +1847,7 @@ e100_hardware_send_packet(char *buf, int length) | |||
| 1737 | led_active = 1; | 1847 | led_active = 1; |
| 1738 | mod_timer(&clear_led_timer, jiffies + HZ/10); | 1848 | mod_timer(&clear_led_timer, jiffies + HZ/10); |
| 1739 | } | 1849 | } |
| 1850 | spin_unlock(&np->led_lock); | ||
| 1740 | 1851 | ||
| 1741 | /* configure the tx dma descriptor */ | 1852 | /* configure the tx dma descriptor */ |
| 1742 | myNextTxDesc->descr.sw_len = length; | 1853 | myNextTxDesc->descr.sw_len = length; |
| @@ -1754,6 +1865,11 @@ e100_hardware_send_packet(char *buf, int length) | |||
| 1754 | static void | 1865 | static void |
| 1755 | e100_clear_network_leds(unsigned long dummy) | 1866 | e100_clear_network_leds(unsigned long dummy) |
| 1756 | { | 1867 | { |
| 1868 | struct net_device *dev = (struct net_device *)dummy; | ||
| 1869 | struct net_local *np = netdev_priv(dev); | ||
| 1870 | |||
| 1871 | spin_lock(&np->led_lock); | ||
| 1872 | |||
| 1757 | if (led_active && time_after(jiffies, led_next_time)) { | 1873 | if (led_active && time_after(jiffies, led_next_time)) { |
| 1758 | e100_set_network_leds(NO_NETWORK_ACTIVITY); | 1874 | e100_set_network_leds(NO_NETWORK_ACTIVITY); |
| 1759 | 1875 | ||
| @@ -1761,6 +1877,8 @@ e100_clear_network_leds(unsigned long dummy) | |||
| 1761 | led_next_time = jiffies + NET_FLASH_PAUSE; | 1877 | led_next_time = jiffies + NET_FLASH_PAUSE; |
| 1762 | led_active = 0; | 1878 | led_active = 0; |
| 1763 | } | 1879 | } |
| 1880 | |||
| 1881 | spin_unlock(&np->led_lock); | ||
| 1764 | } | 1882 | } |
| 1765 | 1883 | ||
| 1766 | static void | 1884 | static void |
| @@ -1781,19 +1899,25 @@ e100_set_network_leds(int active) | |||
| 1781 | #else | 1899 | #else |
| 1782 | LED_NETWORK_SET(LED_OFF); | 1900 | LED_NETWORK_SET(LED_OFF); |
| 1783 | #endif | 1901 | #endif |
| 1784 | } | 1902 | } else if (light_leds) { |
| 1785 | else if (light_leds) { | ||
| 1786 | if (current_speed == 10) { | 1903 | if (current_speed == 10) { |
| 1787 | LED_NETWORK_SET(LED_ORANGE); | 1904 | LED_NETWORK_SET(LED_ORANGE); |
| 1788 | } else { | 1905 | } else { |
| 1789 | LED_NETWORK_SET(LED_GREEN); | 1906 | LED_NETWORK_SET(LED_GREEN); |
| 1790 | } | 1907 | } |
| 1791 | } | 1908 | } else { |
| 1792 | else { | ||
| 1793 | LED_NETWORK_SET(LED_OFF); | 1909 | LED_NETWORK_SET(LED_OFF); |
| 1794 | } | 1910 | } |
| 1795 | } | 1911 | } |
| 1796 | 1912 | ||
| 1913 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 1914 | static void | ||
| 1915 | e100_netpoll(struct net_device* netdev) | ||
| 1916 | { | ||
| 1917 | e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL); | ||
| 1918 | } | ||
| 1919 | #endif | ||
| 1920 | |||
| 1797 | static int | 1921 | static int |
| 1798 | etrax_init_module(void) | 1922 | etrax_init_module(void) |
| 1799 | { | 1923 | { |
