patch-2.4.19 linux-2.4.19/drivers/net/natsemi.c

Next file: linux-2.4.19/drivers/net/ne.c
Previous file: linux-2.4.19/drivers/net/myri_sbus.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/drivers/net/natsemi.c linux-2.4.19/drivers/net/natsemi.c
@@ -105,6 +105,9 @@
 	version 1.0.14:
 		* Cleanup some messages and autoneg in ethtool (Tim Hockin)
 
+	version 1.0.13:
+		* crc cleanup (Matt Domsch <Matt_Domsch@dell.com>)
+
 	TODO:
 	* big endian support with CFG:BEM instead of cpu_to_le32
 	* support for an external PHY
@@ -1731,36 +1734,15 @@
 	return &np->stats;
 }
 
-/* The little-endian AUTODIN II ethernet CRC calculations.
-   A big-endian version is also available.
-   This is slow but compact code.  Do not use this routine for bulk data,
-   use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c.
-   Chips may use the upper or lower CRC bits, and may reverse and/or invert
-   them.  Select the endian-ness that results in minimal calculations.
-*/
-#if 0
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-	unsigned int crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-#else
+/**
+ * dp83815_crc - computer CRC for hash table entries
+ *
+ * Note - this is, for some reason, *not* the same function
+ * as ether_crc_le() or ether_crc(), though it uses the
+ * same big-endian polynomial.
+ */
 #define DP_POLYNOMIAL			0x04C11DB7
-/* dp83815_crc - computer CRC for hash table entries */
-static unsigned ether_crc_le(int length, unsigned char *data)
+static unsigned dp83815_crc(int length, unsigned char *data)
 {
     u32 crc;
     u8 cur_byte;
@@ -1784,7 +1766,7 @@
 
     return (crc);
 }
-#endif
+
 
 void set_bit_le(int offset, unsigned char * data)
 {
@@ -1814,7 +1796,7 @@
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			set_bit_le(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
+			set_bit_le(dp83815_crc(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
 					mc_filter);
 		}
 		rx_mode = RxFilterEnable | AcceptBroadcast 
@@ -1965,6 +1947,8 @@
 	/* get link status */
 	case ETHTOOL_GLINK: {
 		struct ethtool_value edata = {ETHTOOL_GLINK};
+		/* LSTATUS is latched low until a read - so read twice */
+		mdio_read(dev, 1, MII_BMSR);
 		edata.data = (mdio_read(dev, 1, MII_BMSR)&BMSR_LSTATUS) ? 1:0;
 		if (copy_to_user(useraddr, &edata, sizeof(edata)))
 			return -EFAULT;
@@ -1979,6 +1963,9 @@
 		if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
 			return -EFAULT;
 		
+		if (eeprom.offset > eeprom.offset+eeprom.len)
+			return -EINVAL;
+			
 		if ((eeprom.offset+eeprom.len) > NATSEMI_EEPROM_SIZE) {
 			eeprom.len = NATSEMI_EEPROM_SIZE-eeprom.offset;
 		}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)