diff options
author | Dale Farnsworth <dale@farnsworth.org> | 2006-03-03 12:04:39 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-03 12:12:37 -0500 |
commit | 468d09f8946d40228c56de26fe4874b2f98067ed (patch) | |
tree | 4f5641ffdf6782f71fbd1645908e3ba4e50aff33 /drivers/net | |
parent | 7303fde88a149c4cee54dae7e46d1895fa7214b4 (diff) |
[PATCH] mv643xx_eth: Clean up interrupt handling
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 75 | ||||
-rw-r--r-- | drivers/net/mv643xx_eth.h | 5 |
2 files changed, 25 insertions, 55 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 50ee08518c6b..30b0d5b1b155 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -388,11 +388,7 @@ static void mv643xx_eth_free_all_tx_descs(struct net_device *dev) | |||
388 | * | 388 | * |
389 | * Output : number of served packets | 389 | * Output : number of served packets |
390 | */ | 390 | */ |
391 | #ifdef MV643XX_NAPI | ||
392 | static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) | 391 | static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) |
393 | #else | ||
394 | static int mv643xx_eth_receive_queue(struct net_device *dev) | ||
395 | #endif | ||
396 | { | 392 | { |
397 | struct mv643xx_private *mp = netdev_priv(dev); | 393 | struct mv643xx_private *mp = netdev_priv(dev); |
398 | struct net_device_stats *stats = &mp->stats; | 394 | struct net_device_stats *stats = &mp->stats; |
@@ -400,15 +396,14 @@ static int mv643xx_eth_receive_queue(struct net_device *dev) | |||
400 | struct sk_buff *skb; | 396 | struct sk_buff *skb; |
401 | struct pkt_info pkt_info; | 397 | struct pkt_info pkt_info; |
402 | 398 | ||
403 | #ifdef MV643XX_NAPI | ||
404 | while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) { | 399 | while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) { |
405 | #else | ||
406 | while (eth_port_receive(mp, &pkt_info) == ETH_OK) { | ||
407 | #endif | ||
408 | mp->rx_desc_count--; | 400 | mp->rx_desc_count--; |
409 | received_packets++; | 401 | received_packets++; |
410 | 402 | ||
411 | /* Update statistics. Note byte count includes 4 byte CRC count */ | 403 | /* |
404 | * Update statistics. | ||
405 | * Note byte count includes 4 byte CRC count | ||
406 | */ | ||
412 | stats->rx_packets++; | 407 | stats->rx_packets++; |
413 | stats->rx_bytes += pkt_info.byte_cnt; | 408 | stats->rx_bytes += pkt_info.byte_cnt; |
414 | skb = pkt_info.return_info; | 409 | skb = pkt_info.return_info; |
@@ -532,48 +527,10 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, | |||
532 | /* Read interrupt cause registers */ | 527 | /* Read interrupt cause registers */ |
533 | eth_int_cause = mv_read(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num)) & | 528 | eth_int_cause = mv_read(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num)) & |
534 | ETH_INT_UNMASK_ALL; | 529 | ETH_INT_UNMASK_ALL; |
535 | 530 | if (eth_int_cause & ETH_INT_CAUSE_EXT) { | |
536 | if (eth_int_cause & BIT1) | ||
537 | eth_int_cause_ext = mv_read( | 531 | eth_int_cause_ext = mv_read( |
538 | MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) & | 532 | MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) & |
539 | ETH_INT_UNMASK_ALL_EXT; | 533 | ETH_INT_UNMASK_ALL_EXT; |
540 | |||
541 | #ifdef MV643XX_NAPI | ||
542 | if (!(eth_int_cause & 0x0007fffd)) { | ||
543 | /* Dont ack the Rx interrupt */ | ||
544 | #endif | ||
545 | /* | ||
546 | * Clear specific ethernet port intrerrupt registers by | ||
547 | * acknowleding relevant bits. | ||
548 | */ | ||
549 | mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), | ||
550 | ~eth_int_cause); | ||
551 | if (eth_int_cause_ext != 0x0) { | ||
552 | mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG | ||
553 | (port_num), ~eth_int_cause_ext); | ||
554 | /* UDP change : We may need this */ | ||
555 | if (eth_int_cause_ext & (BIT0 | BIT8)) | ||
556 | mv643xx_eth_free_completed_tx_descs(dev); | ||
557 | } | ||
558 | #ifdef MV643XX_NAPI | ||
559 | } else { | ||
560 | if (netif_rx_schedule_prep(dev)) { | ||
561 | /* Mask all the interrupts */ | ||
562 | mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), | ||
563 | ETH_INT_MASK_ALL); | ||
564 | /* wait for previous write to complete */ | ||
565 | mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); | ||
566 | __netif_rx_schedule(dev); | ||
567 | } | ||
568 | #else | ||
569 | if (eth_int_cause & (BIT2 | BIT11)) | ||
570 | mv643xx_eth_receive_queue(dev, 0); | ||
571 | |||
572 | /* | ||
573 | * After forwarded received packets to upper layer, add a task | ||
574 | * in an interrupts enabled context that refills the RX ring | ||
575 | * with skb's. | ||
576 | */ | ||
577 | #ifdef MV643XX_RX_QUEUE_FILL_ON_TASK | 534 | #ifdef MV643XX_RX_QUEUE_FILL_ON_TASK |
578 | /* Mask all interrupts on ethernet port */ | 535 | /* Mask all interrupts on ethernet port */ |
579 | mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), | 536 | mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), |
@@ -586,11 +543,12 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, | |||
586 | #else | 543 | #else |
587 | mp->rx_task.func(dev); | 544 | mp->rx_task.func(dev); |
588 | #endif | 545 | #endif |
589 | #endif | 546 | mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), |
547 | ~eth_int_cause_ext); | ||
590 | } | 548 | } |
591 | 549 | ||
592 | /* PHY status changed */ | 550 | /* PHY status changed */ |
593 | if (eth_int_cause_ext & (BIT16 | BIT20)) { | 551 | if (eth_int_cause_ext & ETH_INT_CAUSE_PHY) { |
594 | struct ethtool_cmd cmd; | 552 | struct ethtool_cmd cmd; |
595 | 553 | ||
596 | if (mii_link_ok(&mp->mii)) { | 554 | if (mii_link_ok(&mp->mii)) { |
@@ -610,6 +568,23 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, | |||
610 | } | 568 | } |
611 | } | 569 | } |
612 | 570 | ||
571 | #ifdef MV643XX_NAPI | ||
572 | if (eth_int_cause & ETH_INT_CAUSE_RX) { | ||
573 | /* schedule the NAPI poll routine to maintain port */ | ||
574 | mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), | ||
575 | ETH_INT_MASK_ALL); | ||
576 | /* wait for previous write to complete */ | ||
577 | mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); | ||
578 | |||
579 | netif_rx_schedule(dev); | ||
580 | } | ||
581 | #else | ||
582 | if (eth_int_cause & ETH_INT_CAUSE_RX) | ||
583 | mv643xx_eth_receive_queue(dev, INT_MAX); | ||
584 | if (eth_int_cause_ext & ETH_INT_CAUSE_TX) | ||
585 | mv643xx_eth_free_completed_tx_descs(dev); | ||
586 | #endif | ||
587 | |||
613 | /* | 588 | /* |
614 | * If no real interrupt occured, exit. | 589 | * If no real interrupt occured, exit. |
615 | * This can happen when using gigE interrupt coalescing mechanism. | 590 | * This can happen when using gigE interrupt coalescing mechanism. |
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h index 2e59f193e267..df2c76154205 100644 --- a/drivers/net/mv643xx_eth.h +++ b/drivers/net/mv643xx_eth.h | |||
@@ -372,9 +372,6 @@ struct mv643xx_private { | |||
372 | 372 | ||
373 | struct work_struct tx_timeout_task; | 373 | struct work_struct tx_timeout_task; |
374 | 374 | ||
375 | /* | ||
376 | * Former struct mv643xx_eth_priv members start here | ||
377 | */ | ||
378 | struct net_device_stats stats; | 375 | struct net_device_stats stats; |
379 | struct mv643xx_mib_counters mib_counters; | 376 | struct mv643xx_mib_counters mib_counters; |
380 | spinlock_t lock; | 377 | spinlock_t lock; |
@@ -405,8 +402,6 @@ struct mv643xx_private { | |||
405 | struct mii_if_info mii; | 402 | struct mii_if_info mii; |
406 | }; | 403 | }; |
407 | 404 | ||
408 | /* ethernet.h API list */ | ||
409 | |||
410 | /* Port operation control routines */ | 405 | /* Port operation control routines */ |
411 | static void eth_port_init(struct mv643xx_private *mp); | 406 | static void eth_port_init(struct mv643xx_private *mp); |
412 | static void eth_port_reset(unsigned int eth_port_num); | 407 | static void eth_port_reset(unsigned int eth_port_num); |