aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mv643xx_eth.c
diff options
context:
space:
mode:
authorDale Farnsworth <dale@farnsworth.org>2006-03-03 12:04:39 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-03 12:12:37 -0500
commit468d09f8946d40228c56de26fe4874b2f98067ed (patch)
tree4f5641ffdf6782f71fbd1645908e3ba4e50aff33 /drivers/net/mv643xx_eth.c
parent7303fde88a149c4cee54dae7e46d1895fa7214b4 (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/mv643xx_eth.c')
-rw-r--r--drivers/net/mv643xx_eth.c75
1 files changed, 25 insertions, 50 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
392static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) 391static int mv643xx_eth_receive_queue(struct net_device *dev, int budget)
393#else
394static 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.