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 7f9960f718e..abcc838e18a 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)  	return dm->rx_csum;  } -static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) +static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data)  {  	board_info_t *dm = to_dm9000_board(dev); -	unsigned long flags;  	if (dm->can_csum) {  		dm->rx_csum = data; - -		spin_lock_irqsave(&dm->lock, flags);  		iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0); -		spin_unlock_irqrestore(&dm->lock, flags);  		return 0;  	} @@ -494,6 +490,19 @@ static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data)  	return -EOPNOTSUPP;  } +static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) +{ +	board_info_t *dm = to_dm9000_board(dev); +	unsigned long flags; +	int ret; + +	spin_lock_irqsave(&dm->lock, flags); +	ret = dm9000_set_rx_csum_unlocked(dev, data); +	spin_unlock_irqrestore(&dm->lock, flags); + +	return ret; +} +  static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data)  {  	board_info_t *dm = to_dm9000_board(dev); @@ -722,20 +731,17 @@ static unsigned char dm9000_type_to_char(enum dm9000_type type)   *  Set DM9000 multicast address   */  static void -dm9000_hash_table(struct net_device *dev) +dm9000_hash_table_unlocked(struct net_device *dev)  {  	board_info_t *db = netdev_priv(dev); -	struct dev_mc_list *mcptr; +	struct netdev_hw_addr *ha;  	int i, oft;  	u32 hash_val;  	u16 hash_table[4];  	u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN; -	unsigned long flags;  	dm9000_dbg(db, 1, "entering %s\n", __func__); -	spin_lock_irqsave(&db->lock, flags); -  	for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)  		iow(db, oft, dev->dev_addr[i]); @@ -753,8 +759,8 @@ dm9000_hash_table(struct net_device *dev)  		rcr |= RCR_ALL;  	/* the multicast address in Hash Table : 64 bits */ -	netdev_for_each_mc_addr(mcptr, dev) { -		hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f; +	netdev_for_each_mc_addr(ha, dev) { +		hash_val = ether_crc_le(6, ha->addr) & 0x3f;  		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);  	} @@ -765,11 +771,21 @@ dm9000_hash_table(struct net_device *dev)  	}  	iow(db, DM9000_RCR, rcr); +} + +static void +dm9000_hash_table(struct net_device *dev) +{ +	board_info_t *db = netdev_priv(dev); +	unsigned long flags; + +	spin_lock_irqsave(&db->lock, flags); +	dm9000_hash_table_unlocked(dev);  	spin_unlock_irqrestore(&db->lock, flags);  }  /* - * Initilize dm9000 board + * Initialize dm9000 board   */  static void  dm9000_init_dm9000(struct net_device *dev) @@ -784,7 +800,7 @@ dm9000_init_dm9000(struct net_device *dev)  	db->io_mode = ior(db, DM9000_ISR) >> 6;	/* ISR bit7:6 keeps I/O mode */  	/* Checksum mode */ -	dm9000_set_rx_csum(dev, db->rx_csum); +	dm9000_set_rx_csum_unlocked(dev, db->rx_csum);  	/* GPIO0 on pre-activate PHY */  	iow(db, DM9000_GPR, 0);	/* REG_1F bit0 activate phyxcer */ @@ -811,7 +827,7 @@ dm9000_init_dm9000(struct net_device *dev)  	iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */  	/* Set address filter table */ -	dm9000_hash_table(dev); +	dm9000_hash_table_unlocked(dev);  	imr = IMR_PAR | IMR_PTM | IMR_PRM;  	if (db->type != TYPE_DM9000E) @@ -825,7 +841,7 @@ dm9000_init_dm9000(struct net_device *dev)  	/* Init Driver variable */  	db->tx_pkt_cnt = 0;  	db->queue_pkt_len = 0; -	dev->trans_start = 0; +	dev->trans_start = jiffies;  }  /* Our watchdog timed out. Called by the networking layer */ @@ -843,7 +859,7 @@ static void dm9000_timeout(struct net_device *dev)  	dm9000_reset(db);  	dm9000_init_dm9000(dev);  	/* We can accept TX packets again */ -	dev->trans_start = jiffies; +	dev->trans_start = jiffies; /* prevent tx timeout */  	netif_wake_queue(dev);  	/* Restore previous register address */  |