diff options
Diffstat (limited to 'drivers/net/dm9000.c')
-rw-r--r-- | drivers/net/dm9000.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 7f9960f718e3..abcc838e18af 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -476,17 +476,13 @@ static uint32_t dm9000_get_rx_csum(struct net_device *dev) | |||
476 | return dm->rx_csum; | 476 | return dm->rx_csum; |
477 | } | 477 | } |
478 | 478 | ||
479 | static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) | 479 | static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data) |
480 | { | 480 | { |
481 | board_info_t *dm = to_dm9000_board(dev); | 481 | board_info_t *dm = to_dm9000_board(dev); |
482 | unsigned long flags; | ||
483 | 482 | ||
484 | if (dm->can_csum) { | 483 | if (dm->can_csum) { |
485 | dm->rx_csum = data; | 484 | dm->rx_csum = data; |
486 | |||
487 | spin_lock_irqsave(&dm->lock, flags); | ||
488 | iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0); | 485 | iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0); |
489 | spin_unlock_irqrestore(&dm->lock, flags); | ||
490 | 486 | ||
491 | return 0; | 487 | return 0; |
492 | } | 488 | } |
@@ -494,6 +490,19 @@ static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) | |||
494 | return -EOPNOTSUPP; | 490 | return -EOPNOTSUPP; |
495 | } | 491 | } |
496 | 492 | ||
493 | static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) | ||
494 | { | ||
495 | board_info_t *dm = to_dm9000_board(dev); | ||
496 | unsigned long flags; | ||
497 | int ret; | ||
498 | |||
499 | spin_lock_irqsave(&dm->lock, flags); | ||
500 | ret = dm9000_set_rx_csum_unlocked(dev, data); | ||
501 | spin_unlock_irqrestore(&dm->lock, flags); | ||
502 | |||
503 | return ret; | ||
504 | } | ||
505 | |||
497 | static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data) | 506 | static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data) |
498 | { | 507 | { |
499 | board_info_t *dm = to_dm9000_board(dev); | 508 | board_info_t *dm = to_dm9000_board(dev); |
@@ -722,20 +731,17 @@ static unsigned char dm9000_type_to_char(enum dm9000_type type) | |||
722 | * Set DM9000 multicast address | 731 | * Set DM9000 multicast address |
723 | */ | 732 | */ |
724 | static void | 733 | static void |
725 | dm9000_hash_table(struct net_device *dev) | 734 | dm9000_hash_table_unlocked(struct net_device *dev) |
726 | { | 735 | { |
727 | board_info_t *db = netdev_priv(dev); | 736 | board_info_t *db = netdev_priv(dev); |
728 | struct dev_mc_list *mcptr; | 737 | struct netdev_hw_addr *ha; |
729 | int i, oft; | 738 | int i, oft; |
730 | u32 hash_val; | 739 | u32 hash_val; |
731 | u16 hash_table[4]; | 740 | u16 hash_table[4]; |
732 | u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN; | 741 | u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN; |
733 | unsigned long flags; | ||
734 | 742 | ||
735 | dm9000_dbg(db, 1, "entering %s\n", __func__); | 743 | dm9000_dbg(db, 1, "entering %s\n", __func__); |
736 | 744 | ||
737 | spin_lock_irqsave(&db->lock, flags); | ||
738 | |||
739 | for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) | 745 | for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) |
740 | iow(db, oft, dev->dev_addr[i]); | 746 | iow(db, oft, dev->dev_addr[i]); |
741 | 747 | ||
@@ -753,8 +759,8 @@ dm9000_hash_table(struct net_device *dev) | |||
753 | rcr |= RCR_ALL; | 759 | rcr |= RCR_ALL; |
754 | 760 | ||
755 | /* the multicast address in Hash Table : 64 bits */ | 761 | /* the multicast address in Hash Table : 64 bits */ |
756 | netdev_for_each_mc_addr(mcptr, dev) { | 762 | netdev_for_each_mc_addr(ha, dev) { |
757 | hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f; | 763 | hash_val = ether_crc_le(6, ha->addr) & 0x3f; |
758 | hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); | 764 | hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); |
759 | } | 765 | } |
760 | 766 | ||
@@ -765,11 +771,21 @@ dm9000_hash_table(struct net_device *dev) | |||
765 | } | 771 | } |
766 | 772 | ||
767 | iow(db, DM9000_RCR, rcr); | 773 | iow(db, DM9000_RCR, rcr); |
774 | } | ||
775 | |||
776 | static void | ||
777 | dm9000_hash_table(struct net_device *dev) | ||
778 | { | ||
779 | board_info_t *db = netdev_priv(dev); | ||
780 | unsigned long flags; | ||
781 | |||
782 | spin_lock_irqsave(&db->lock, flags); | ||
783 | dm9000_hash_table_unlocked(dev); | ||
768 | spin_unlock_irqrestore(&db->lock, flags); | 784 | spin_unlock_irqrestore(&db->lock, flags); |
769 | } | 785 | } |
770 | 786 | ||
771 | /* | 787 | /* |
772 | * Initilize dm9000 board | 788 | * Initialize dm9000 board |
773 | */ | 789 | */ |
774 | static void | 790 | static void |
775 | dm9000_init_dm9000(struct net_device *dev) | 791 | dm9000_init_dm9000(struct net_device *dev) |
@@ -784,7 +800,7 @@ dm9000_init_dm9000(struct net_device *dev) | |||
784 | db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ | 800 | db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ |
785 | 801 | ||
786 | /* Checksum mode */ | 802 | /* Checksum mode */ |
787 | dm9000_set_rx_csum(dev, db->rx_csum); | 803 | dm9000_set_rx_csum_unlocked(dev, db->rx_csum); |
788 | 804 | ||
789 | /* GPIO0 on pre-activate PHY */ | 805 | /* GPIO0 on pre-activate PHY */ |
790 | iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ | 806 | iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ |
@@ -811,7 +827,7 @@ dm9000_init_dm9000(struct net_device *dev) | |||
811 | iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */ | 827 | iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */ |
812 | 828 | ||
813 | /* Set address filter table */ | 829 | /* Set address filter table */ |
814 | dm9000_hash_table(dev); | 830 | dm9000_hash_table_unlocked(dev); |
815 | 831 | ||
816 | imr = IMR_PAR | IMR_PTM | IMR_PRM; | 832 | imr = IMR_PAR | IMR_PTM | IMR_PRM; |
817 | if (db->type != TYPE_DM9000E) | 833 | if (db->type != TYPE_DM9000E) |
@@ -825,7 +841,7 @@ dm9000_init_dm9000(struct net_device *dev) | |||
825 | /* Init Driver variable */ | 841 | /* Init Driver variable */ |
826 | db->tx_pkt_cnt = 0; | 842 | db->tx_pkt_cnt = 0; |
827 | db->queue_pkt_len = 0; | 843 | db->queue_pkt_len = 0; |
828 | dev->trans_start = 0; | 844 | dev->trans_start = jiffies; |
829 | } | 845 | } |
830 | 846 | ||
831 | /* Our watchdog timed out. Called by the networking layer */ | 847 | /* Our watchdog timed out. Called by the networking layer */ |
@@ -843,7 +859,7 @@ static void dm9000_timeout(struct net_device *dev) | |||
843 | dm9000_reset(db); | 859 | dm9000_reset(db); |
844 | dm9000_init_dm9000(dev); | 860 | dm9000_init_dm9000(dev); |
845 | /* We can accept TX packets again */ | 861 | /* We can accept TX packets again */ |
846 | dev->trans_start = jiffies; | 862 | dev->trans_start = jiffies; /* prevent tx timeout */ |
847 | netif_wake_queue(dev); | 863 | netif_wake_queue(dev); |
848 | 864 | ||
849 | /* Restore previous register address */ | 865 | /* Restore previous register address */ |