Merge branch 'upstream-fixes'
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index c53848f..7aa49b9 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -28,8 +28,8 @@
 
 #define DRV_MODULE_NAME		"b44"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.96"
-#define DRV_MODULE_RELDATE	"Nov 8, 2005"
+#define DRV_MODULE_VERSION	"0.97"
+#define DRV_MODULE_RELDATE	"Nov 30, 2005"
 
 #define B44_DEF_MSG_ENABLE	  \
 	(NETIF_MSG_DRV		| \
@@ -1417,6 +1417,7 @@
 	add_timer(&bp->timer);
 
 	b44_enable_ints(bp);
+	netif_start_queue(dev);
 out:
 	return err;
 }
@@ -1837,12 +1838,15 @@
 {
 	struct mii_ioctl_data *data = if_mii(ifr);
 	struct b44 *bp = netdev_priv(dev);
-	int err;
+	int err = -EINVAL;
+
+	if (!netif_running(dev))
+		goto out;
 
 	spin_lock_irq(&bp->lock);
 	err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
 	spin_unlock_irq(&bp->lock);
-
+out:
 	return err;
 }
 
@@ -2113,6 +2117,7 @@
 	add_timer(&bp->timer);
 
 	b44_enable_ints(bp);
+	netif_wake_queue(dev);
 	return 0;
 }
 
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 8b207f0..e0ae248 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2621,19 +2621,7 @@
 			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
 			return 0;
 	}
-	if(htons(ETH_P_IP) == skb->protocol) {
-		const struct iphdr *ip = skb->nh.iph;
-		if(IPPROTO_UDP == ip->protocol) {
-			struct udphdr *udp = (struct udphdr *)(skb->h.uh);
-			if(ntohs(udp->dest) == 67) {
-				offset = (uint8_t *)udp + 8 - skb->data;
-				length = skb->len - offset;
-
-				return e1000_mng_write_dhcp_info(hw,
-						(uint8_t *)udp + 8, length);
-			}
-		}
-	} else if((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
+ 	if ((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
 		struct ethhdr *eth = (struct ethhdr *) skb->data;
 		if((htons(ETH_P_IP) == eth->h_proto)) {
 			const struct iphdr *ip = 
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
index 6783039..7653d6e 100644
--- a/drivers/net/sk98lin/Makefile
+++ b/drivers/net/sk98lin/Makefile
@@ -27,8 +27,7 @@
 		sktimer.o	\
 		skvpd.o		\
 		skxmac2.o	\
-		skproc.o	\
-		skcsum.o
+		skproc.o
 
 # DBGDEF =  \
 # -DDEBUG
@@ -77,7 +76,7 @@
 # SK_DBGCAT_DRV_INT_SRC         0x04000000      interrupts sources
 # SK_DBGCAT_DRV_EVENT           0x08000000      driver events
 
-EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
+EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
 
 clean:
 	rm -f core *.o *.a *.s
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
index c0bfce5..9bdfde8 100644
--- a/drivers/net/sk98lin/h/skdrv2nd.h
+++ b/drivers/net/sk98lin/h/skdrv2nd.h
@@ -424,10 +424,6 @@
 	TX_PORT		TxPort[SK_MAX_MACS][2];
 	RX_PORT		RxPort[SK_MAX_MACS];
 
-	unsigned int	CsOfs1;		/* for checksum calculation */
-	unsigned int	CsOfs2;		/* for checksum calculation */
-	SK_U32		CsOfs;		/* for checksum calculation */
-
 	SK_BOOL		CheckQueue;	/* check event queue soon */
 	SK_TIMER        DrvCleanupTimer;/* to check for pending descriptors */
 	DIM_INFO        DynIrqModInfo;  /* all data related to DIM */
diff --git a/drivers/net/sk98lin/skcsum.c b/drivers/net/sk98lin/skcsum.c
deleted file mode 100644
index 38a6e7a..0000000
--- a/drivers/net/sk98lin/skcsum.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/******************************************************************************
- *
- * Name:	skcsum.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.12 $
- * Date:	$Date: 2003/08/20 13:55:53 $
- * Purpose:	Store/verify Internet checksum in send/receive packets.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
- *	The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifdef SK_USE_CSUM	/* Check if CSUM is to be used. */
-
-#ifndef lint
-static const char SysKonnectFileId[] =
-	"@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect.";
-#endif	/* !lint */
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the "GEnesis" common module "CSUM".
- *
- * This module contains the code necessary to calculate, store, and verify the
- * Internet Checksum of IP, TCP, and UDP frames.
- *
- * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
- * and is the code name of this SysKonnect project.
- *
- * Compilation Options:
- *
- *	SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
- *	empty module.
- *
- *	SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
- *	definitions. In this case, all SKCS_PROTO_xxx definitions must be made
- *	external.
- *
- *	SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
- *	definitions. In this case, all SKCS_STATUS_xxx definitions must be made
- *	external.
- *
- * Include File Hierarchy:
- *
- *	"h/skdrv1st.h"
- *	"h/skcsum.h"
- *	"h/sktypes.h"
- *	"h/skqueue.h"
- *	"h/skdrv2nd.h"
- *
- ******************************************************************************/
-
-#include "h/skdrv1st.h"
-#include "h/skcsum.h"
-#include "h/skdrv2nd.h"
-
-/* defines ********************************************************************/
-
-/* The size of an Ethernet MAC header. */
-#define SKCS_ETHERNET_MAC_HEADER_SIZE			(6+6+2)
-
-/* The size of the used topology's MAC header. */
-#define	SKCS_MAC_HEADER_SIZE	SKCS_ETHERNET_MAC_HEADER_SIZE
-
-/* The size of the IP header without any option fields. */
-#define SKCS_IP_HEADER_SIZE						20
-
-/*
- * Field offsets within the IP header.
- */
-
-/* "Internet Header Version" and "Length". */
-#define SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH	0
-
-/* "Total Length". */
-#define SKCS_OFS_IP_TOTAL_LENGTH				2
-
-/* "Flags" "Fragment Offset". */
-#define SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET	6
-
-/* "Next Level Protocol" identifier. */
-#define SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL			9
-
-/* Source IP address. */
-#define SKCS_OFS_IP_SOURCE_ADDRESS				12
-
-/* Destination IP address. */
-#define SKCS_OFS_IP_DESTINATION_ADDRESS			16
-
-
-/*
- * Field offsets within the UDP header.
- */
-
-/* UDP checksum. */
-#define SKCS_OFS_UDP_CHECKSUM					6
-
-/* IP "Next Level Protocol" identifiers (see RFC 790). */
-#define SKCS_PROTO_ID_TCP		6	/* Transport Control Protocol */
-#define SKCS_PROTO_ID_UDP		17	/* User Datagram Protocol */
-
-/* IP "Don't Fragment" bit. */
-#define SKCS_IP_DONT_FRAGMENT	SKCS_HTON16(0x4000)
-
-/* Add a byte offset to a pointer. */
-#define SKCS_IDX(pPtr, Ofs)	((void *) ((char *) (pPtr) + (Ofs)))
-
-/*
- * Macros that convert host to network representation and vice versa, i.e.
- * little/big endian conversion on little endian machines only.
- */
-#ifdef SK_LITTLE_ENDIAN
-#define SKCS_HTON16(Val16)	(((unsigned) (Val16) >> 8) | (((Val16) & 0xff) << 8))
-#endif	/* SK_LITTLE_ENDIAN */
-#ifdef SK_BIG_ENDIAN
-#define SKCS_HTON16(Val16)	(Val16)
-#endif	/* SK_BIG_ENDIAN */
-#define SKCS_NTOH16(Val16)	SKCS_HTON16(Val16)
-
-/* typedefs *******************************************************************/
-
-/* function prototypes ********************************************************/
-
-/******************************************************************************
- *
- *	SkCsGetSendInfo - get checksum information for a send packet
- *
- * Description:
- *	Get all checksum information necessary to send a TCP or UDP packet. The
- *	function checks the IP header passed to it. If the high-level protocol
- *	is either TCP or UDP the pseudo header checksum is calculated and
- *	returned.
- *
- *	The function returns the total length of the IP header (including any
- *	IP option fields), which is the same as the start offset of the IP data
- *	which in turn is the start offset of the TCP or UDP header.
- *
- *	The function also returns the TCP or UDP pseudo header checksum, which
- *	should be used as the start value for the hardware checksum calculation.
- *	(Note that any actual pseudo header checksum can never calculate to
- *	zero.)
- *
- * Note:
- *	There is a bug in the GENESIS ASIC which may lead to wrong checksums.
- *
- * Arguments:
- *	pAc - A pointer to the adapter context struct.
- *
- *	pIpHeader - Pointer to IP header. Must be at least the IP header *not*
- *	including any option fields, i.e. at least 20 bytes.
- *
- *	Note: This pointer will be used to address 8-, 16-, and 32-bit
- *	variables with the respective alignment offsets relative to the pointer.
- *	Thus, the pointer should point to a 32-bit aligned address. If the
- *	target system cannot address 32-bit variables on non 32-bit aligned
- *	addresses, then the pointer *must* point to a 32-bit aligned address.
- *
- *	pPacketInfo - A pointer to the packet information structure for this
- *	packet. Before calling this SkCsGetSendInfo(), the following field must
- *	be initialized:
- *
- *		ProtocolFlags - Initialize with any combination of
- *		SKCS_PROTO_XXX bit flags. SkCsGetSendInfo() will only work on
- *		the protocols specified here. Any protocol(s) not specified
- *		here will be ignored.
- *
- *		Note: Only one checksum can be calculated in hardware. Thus, if
- *		SKCS_PROTO_IP is specified in the 'ProtocolFlags',
- *		SkCsGetSendInfo() must calculate the IP header checksum in
- *		software. It might be a better idea to have the calling
- *		protocol stack calculate the IP header checksum.
- *
- * Returns: N/A
- *	On return, the following fields in 'pPacketInfo' may or may not have
- *	been filled with information, depending on the protocol(s) found in the
- *	packet:
- *
- *	ProtocolFlags - Returns the SKCS_PROTO_XXX bit flags of the protocol(s)
- *	that were both requested by the caller and actually found in the packet.
- *	Protocol(s) not specified by the caller and/or not found in the packet
- *	will have their respective SKCS_PROTO_XXX bit flags reset.
- *
- *	Note: For IP fragments, TCP and UDP packet information is ignored.
- *
- *	IpHeaderLength - The total length in bytes of the complete IP header
- *	including any option fields is returned here. This is the start offset
- *	of the IP data, i.e. the TCP or UDP header if present.
- *
- *	IpHeaderChecksum - If IP has been specified in the 'ProtocolFlags', the
- *	16-bit Internet Checksum of the IP header is returned here. This value
- *	is to be stored into the packet's 'IP Header Checksum' field.
- *
- *	PseudoHeaderChecksum - If this is a TCP or UDP packet and if TCP or UDP
- *	has been specified in the 'ProtocolFlags', the 16-bit Internet Checksum
- *	of the TCP or UDP pseudo header is returned here.
- */
-void SkCsGetSendInfo(
-SK_AC				*pAc,			/* Adapter context struct. */
-void				*pIpHeader,		/* IP header. */
-SKCS_PACKET_INFO	*pPacketInfo,	/* Packet information struct. */
-int					NetNumber)		/* Net number */
-{
-	/* Internet Header Version found in IP header. */
-	unsigned InternetHeaderVersion;
-
-	/* Length of the IP header as found in IP header. */
-	unsigned IpHeaderLength;
-
-	/* Bit field specifiying the desired/found protocols. */
-	unsigned ProtocolFlags;
-
-	/* Next level protocol identifier found in IP header. */
-	unsigned NextLevelProtocol;
-
-	/* Length of IP data portion. */
-	unsigned IpDataLength;
-
-	/* TCP/UDP pseudo header checksum. */
-	unsigned long PseudoHeaderChecksum;
-
-	/* Pointer to next level protocol statistics structure. */
-	SKCS_PROTO_STATS *NextLevelProtoStats;
-
-	/* Temporary variable. */
-	unsigned Tmp;
-
-	Tmp = *(SK_U8 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
-
-	/* Get the Internet Header Version (IHV). */
-	/* Note: The IHV is stored in the upper four bits. */
-
-	InternetHeaderVersion = Tmp >> 4;
-
-	/* Check the Internet Header Version. */
-	/* Note: We currently only support IP version 4. */
-
-	if (InternetHeaderVersion != 4) {	/* IPv4? */
-		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
-			("Tx: Unknown Internet Header Version %u.\n",
-			InternetHeaderVersion));
-		pPacketInfo->ProtocolFlags = 0;
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
-		return;
-	}
-
-	/* Get the IP header length (IHL). */
-	/*
-	 * Note: The IHL is stored in the lower four bits as the number of
-	 * 4-byte words.
-	 */
-
-	IpHeaderLength = (Tmp & 0xf) * 4;
-	pPacketInfo->IpHeaderLength = IpHeaderLength;
-
-	/* Check the IP header length. */
-
-	/* 04-Aug-1998 sw - Really check the IHL? Necessary? */
-
-	if (IpHeaderLength < 5*4) {
-		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
-			("Tx: Invalid IP Header Length %u.\n", IpHeaderLength));
-		pPacketInfo->ProtocolFlags = 0;
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
-		return;
-	}
-
-	/* This is an IPv4 frame with a header of valid length. */
-
-	pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxOkCts++;
-
-	/* Check if we should calculate the IP header checksum. */
-
-	ProtocolFlags = pPacketInfo->ProtocolFlags;
-
-	if (ProtocolFlags & SKCS_PROTO_IP) {
-		pPacketInfo->IpHeaderChecksum =
-			SkCsCalculateChecksum(pIpHeader, IpHeaderLength);
-	}
-
-	/* Get the next level protocol identifier. */
-
-	NextLevelProtocol =
-		*(SK_U8 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
-
-	/*
-	 * Check if this is a TCP or UDP frame and if we should calculate the
-	 * TCP/UDP pseudo header checksum.
-	 *
-	 * Also clear all protocol bit flags of protocols not present in the
-	 * frame.
-	 */
-
-	if ((ProtocolFlags & SKCS_PROTO_TCP) != 0 &&
-		NextLevelProtocol == SKCS_PROTO_ID_TCP) {
-		/* TCP/IP frame. */
-		ProtocolFlags &= SKCS_PROTO_TCP | SKCS_PROTO_IP;
-		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
-	}
-	else if ((ProtocolFlags & SKCS_PROTO_UDP) != 0 &&
-		NextLevelProtocol == SKCS_PROTO_ID_UDP) {
-		/* UDP/IP frame. */
-		ProtocolFlags &= SKCS_PROTO_UDP | SKCS_PROTO_IP;
-		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
-	}
-	else {
-		/*
-		 * Either not a TCP or UDP frame and/or TCP/UDP processing not
-		 * specified.
-		 */
-		pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
-		return;
-	}
-
-	/* Check if this is an IP fragment. */
-
-	/*
-	 * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
-	 * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
-	 * and the "More Fragments" are zero, it is *not* a fragment. We can
-	 * easily check both at the same time since they are in the same 16-bit
-	 * word.
-	 */
-
-	if ((*(SK_U16 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
-		~SKCS_IP_DONT_FRAGMENT) != 0) {
-		/* IP fragment; ignore all other protocols. */
-		pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
-		NextLevelProtoStats->TxUnableCts++;
-		return;
-	}
-
-	/*
-	 * Calculate the TCP/UDP pseudo header checksum.
-	 */
-
-	/* Get total length of IP header and data. */
-
-	IpDataLength =
-		*(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
-
-	/* Get length of IP data portion. */
-
-	IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
-
-	/* Calculate the sum of all pseudo header fields (16-bit). */
-
-	PseudoHeaderChecksum =
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
-		(unsigned long) SKCS_HTON16(NextLevelProtocol) +
-		(unsigned long) SKCS_HTON16(IpDataLength);
-	
-	/* Add-in any carries. */
-
-	SKCS_OC_ADD(PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
-
-	/* Add-in any new carry. */
-
-	SKCS_OC_ADD(pPacketInfo->PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
-
-	pPacketInfo->ProtocolFlags = ProtocolFlags;
-	NextLevelProtoStats->TxOkCts++;	/* Success. */
-}	/* SkCsGetSendInfo */
-
-
-/******************************************************************************
- *
- *	SkCsGetReceiveInfo - verify checksum information for a received packet
- *
- * Description:
- *	Verify a received frame's checksum. The function returns a status code
- *	reflecting the result of the verification.
- *
- * Note:
- *	Before calling this function you have to verify that the frame is
- *	not padded and Checksum1 and Checksum2 are bigger than 1.
- *
- * Arguments:
- *	pAc - Pointer to adapter context struct.
- *
- *	pIpHeader - Pointer to IP header. Must be at least the length in bytes
- *	of the received IP header including any option fields. For UDP packets,
- *	8 additional bytes are needed to access the UDP checksum.
- *
- *	Note: The actual length of the IP header is stored in the lower four
- *	bits of the first octet of the IP header as the number of 4-byte words,
- *	so it must be multiplied by four to get the length in bytes. Thus, the
- *	maximum IP header length is 15 * 4 = 60 bytes.
- *
- *	Checksum1 - The first 16-bit Internet Checksum calculated by the
- *	hardware starting at the offset returned by SkCsSetReceiveFlags().
- *
- *	Checksum2 - The second 16-bit Internet Checksum calculated by the
- *	hardware starting at the offset returned by SkCsSetReceiveFlags().
- *
- * Returns:
- *	SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
- *	SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
- *	SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
- *	SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
- *	SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
- *	SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
- *	SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
- *	SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
- *	SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
- *	SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
- *	SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
- *
- *	Note: If SKCS_OVERWRITE_STATUS is defined, the SKCS_STATUS_XXX values
- *	returned here can be defined in some header file by the module using CSUM.
- *	In this way, the calling module can assign return values for its own needs,
- *	e.g. by assigning bit flags to the individual protocols.
- */
-SKCS_STATUS SkCsGetReceiveInfo(
-SK_AC		*pAc,		/* Adapter context struct. */
-void		*pIpHeader,	/* IP header. */
-unsigned	Checksum1,	/* Hardware checksum 1. */
-unsigned	Checksum2,	/* Hardware checksum 2. */
-int			NetNumber)	/* Net number */
-{
-	/* Internet Header Version found in IP header. */
-	unsigned InternetHeaderVersion;
-
-	/* Length of the IP header as found in IP header. */
-	unsigned IpHeaderLength;
-
-	/* Length of IP data portion. */
-	unsigned IpDataLength;
-
-	/* IP header checksum. */
-	unsigned IpHeaderChecksum;
-
-	/* IP header options checksum, if any. */
-	unsigned IpOptionsChecksum;
-
-	/* IP data checksum, i.e. TCP/UDP checksum. */
-	unsigned IpDataChecksum;
-
-	/* Next level protocol identifier found in IP header. */
-	unsigned NextLevelProtocol;
-
-	/* The checksum of the "next level protocol", i.e. TCP or UDP. */
-	unsigned long NextLevelProtocolChecksum;
-
-	/* Pointer to next level protocol statistics structure. */
-	SKCS_PROTO_STATS *NextLevelProtoStats;
-
-	/* Temporary variable. */
-	unsigned Tmp;
-
-	Tmp = *(SK_U8 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
-
-	/* Get the Internet Header Version (IHV). */
-	/* Note: The IHV is stored in the upper four bits. */
-
-	InternetHeaderVersion = Tmp >> 4;
-
-	/* Check the Internet Header Version. */
-	/* Note: We currently only support IP version 4. */
-
-	if (InternetHeaderVersion != 4) {	/* IPv4? */
-		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
-			("Rx: Unknown Internet Header Version %u.\n",
-			InternetHeaderVersion));
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxUnableCts++;
-		return (SKCS_STATUS_UNKNOWN_IP_VERSION);
-	}
-
-	/* Get the IP header length (IHL). */
-	/*
-	 * Note: The IHL is stored in the lower four bits as the number of
-	 * 4-byte words.
-	 */
-
-	IpHeaderLength = (Tmp & 0xf) * 4;
-
-	/* Check the IP header length. */
-
-	/* 04-Aug-1998 sw - Really check the IHL? Necessary? */
-
-	if (IpHeaderLength < 5*4) {
-		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
-			("Rx: Invalid IP Header Length %u.\n", IpHeaderLength));
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
-		return (SKCS_STATUS_IP_CSUM_ERROR);
-	}
-
-	/* This is an IPv4 frame with a header of valid length. */
-
-	/* Get the IP header and data checksum. */
-
-	IpDataChecksum = Checksum2;
-
-	/*
-	 * The IP header checksum is calculated as follows:
-	 *
-	 *	IpHeaderChecksum = Checksum1 - Checksum2
-	 */
-
-	SKCS_OC_SUB(IpHeaderChecksum, Checksum1, Checksum2);
-
-	/* Check if any IP header options. */
-
-	if (IpHeaderLength > SKCS_IP_HEADER_SIZE) {
-
-		/* Get the IP options checksum. */
-
-		IpOptionsChecksum = SkCsCalculateChecksum(
-			SKCS_IDX(pIpHeader, SKCS_IP_HEADER_SIZE),
-			IpHeaderLength - SKCS_IP_HEADER_SIZE);
-
-		/* Adjust the IP header and IP data checksums. */
-
-		SKCS_OC_ADD(IpHeaderChecksum, IpHeaderChecksum, IpOptionsChecksum);
-
-		SKCS_OC_SUB(IpDataChecksum, IpDataChecksum, IpOptionsChecksum);
-	}
-
-	/*
-	 * Check if the IP header checksum is ok.
-	 *
-	 * NOTE: We must check the IP header checksum even if the caller just wants
-	 * us to check upper-layer checksums, because we cannot do any further
-	 * processing of the packet without a valid IP checksum.
-	 */
-	
-	/* Get the next level protocol identifier. */
-	
-	NextLevelProtocol = *(SK_U8 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
-
-	if (IpHeaderChecksum != 0xffff) {
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
-		/* the NDIS tester wants to know the upper level protocol too */
-		if (NextLevelProtocol == SKCS_PROTO_ID_TCP) {
-			return(SKCS_STATUS_IP_CSUM_ERROR_TCP);
-		}
-		else if (NextLevelProtocol == SKCS_PROTO_ID_UDP) {
-			return(SKCS_STATUS_IP_CSUM_ERROR_UDP);
-		}
-		return (SKCS_STATUS_IP_CSUM_ERROR);
-	}
-
-	/*
-	 * Check if this is a TCP or UDP frame and if we should calculate the
-	 * TCP/UDP pseudo header checksum.
-	 *
-	 * Also clear all protocol bit flags of protocols not present in the
-	 * frame.
-	 */
-
-	if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_TCP) != 0 &&
-		NextLevelProtocol == SKCS_PROTO_ID_TCP) {
-		/* TCP/IP frame. */
-		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
-	}
-	else if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_UDP) != 0 &&
-		NextLevelProtocol == SKCS_PROTO_ID_UDP) {
-		/* UDP/IP frame. */
-		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
-	}
-	else {
-		/*
-		 * Either not a TCP or UDP frame and/or TCP/UDP processing not
-		 * specified.
-		 */
-		return (SKCS_STATUS_IP_CSUM_OK);
-	}
-
-	/* Check if this is an IP fragment. */
-
-	/*
-	 * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
-	 * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
-	 * and the "More Fragments" are zero, it is *not* a fragment. We can
-	 * easily check both at the same time since they are in the same 16-bit
-	 * word.
-	 */
-
-	if ((*(SK_U16 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
-		~SKCS_IP_DONT_FRAGMENT) != 0) {
-		/* IP fragment; ignore all other protocols. */
-		NextLevelProtoStats->RxUnableCts++;
-		return (SKCS_STATUS_IP_FRAGMENT);
-	}
-
-	/*
-	 * 08-May-2000 ra
-	 *
-	 * From RFC 768 (UDP)
-	 * If the computed checksum is zero, it is transmitted as all ones (the
-	 * equivalent in one's complement arithmetic).  An all zero transmitted
-	 * checksum value means that the transmitter generated no checksum (for
-	 * debugging or for higher level protocols that don't care).
-	 */
-
-	if (NextLevelProtocol == SKCS_PROTO_ID_UDP &&
-		*(SK_U16*)SKCS_IDX(pIpHeader, IpHeaderLength + 6) == 0x0000) {
-
-		NextLevelProtoStats->RxOkCts++;
-		
-		return (SKCS_STATUS_IP_CSUM_OK_NO_UDP);
-	}
-
-	/*
-	 * Calculate the TCP/UDP checksum.
-	 */
-
-	/* Get total length of IP header and data. */
-
-	IpDataLength =
-		*(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
-
-	/* Get length of IP data portion. */
-
-	IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
-
-	NextLevelProtocolChecksum =
-
-		/* Calculate the pseudo header checksum. */
-
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
-		(unsigned long) SKCS_HTON16(NextLevelProtocol) +
-		(unsigned long) SKCS_HTON16(IpDataLength) +
-
-		/* Add the TCP/UDP header checksum. */
-
-		(unsigned long) IpDataChecksum;
-
-	/* Add-in any carries. */
-
-	SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
-
-	/* Add-in any new carry. */
-
-	SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
-
-	/* Check if the TCP/UDP checksum is ok. */
-
-	if ((unsigned) NextLevelProtocolChecksum == 0xffff) {
-
-		/* TCP/UDP checksum ok. */
-
-		NextLevelProtoStats->RxOkCts++;
-
-		return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
-			SKCS_STATUS_TCP_CSUM_OK : SKCS_STATUS_UDP_CSUM_OK);
-	}
-	
-	/* TCP/UDP checksum error. */
-
-	NextLevelProtoStats->RxErrCts++;
-
-	return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
-		SKCS_STATUS_TCP_CSUM_ERROR : SKCS_STATUS_UDP_CSUM_ERROR);
-}	/* SkCsGetReceiveInfo */
-
-
-/******************************************************************************
- *
- *	SkCsSetReceiveFlags - set checksum receive flags
- *
- * Description:
- *	Use this function to set the various receive flags. According to the
- *	protocol flags set by the caller, the start offsets within received
- *	packets of the two hardware checksums are returned. These offsets must
- *	be stored in all receive descriptors.
- *
- * Arguments:
- *	pAc - Pointer to adapter context struct.
- *
- *	ReceiveFlags - Any combination of SK_PROTO_XXX flags of the protocols
- *	for which the caller wants checksum information on received frames.
- *
- *	pChecksum1Offset - The start offset of the first receive descriptor
- *	hardware checksum to be calculated for received frames is returned
- *	here.
- *
- *	pChecksum2Offset - The start offset of the second receive descriptor
- *	hardware checksum to be calculated for received frames is returned
- *	here.
- *
- * Returns: N/A
- *	Returns the two hardware checksum start offsets.
- */
-void SkCsSetReceiveFlags(
-SK_AC		*pAc,				/* Adapter context struct. */
-unsigned	ReceiveFlags,		/* New receive flags. */
-unsigned	*pChecksum1Offset,	/* Offset for hardware checksum 1. */
-unsigned	*pChecksum2Offset,	/* Offset for hardware checksum 2. */
-int			NetNumber)
-{
-	/* Save the receive flags. */
-
-	pAc->Csum.ReceiveFlags[NetNumber] = ReceiveFlags;
-
-	/* First checksum start offset is the IP header. */
-	*pChecksum1Offset = SKCS_MAC_HEADER_SIZE;
-
-	/*
-	 * Second checksum start offset is the IP data. Note that this may vary
-	 * if there are any IP header options in the actual packet.
-	 */
-	*pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;
-}	/* SkCsSetReceiveFlags */
-
-#ifndef SK_CS_CALCULATE_CHECKSUM
-
-/******************************************************************************
- *
- *	SkCsCalculateChecksum - calculate checksum for specified data
- *
- * Description:
- *	Calculate and return the 16-bit Internet Checksum for the specified
- *	data.
- *
- * Arguments:
- *	pData - Pointer to data for which the checksum shall be calculated.
- *	Note: The pointer should be aligned on a 16-bit boundary.
- *
- *	Length - Length in bytes of data to checksum.
- *
- * Returns:
- *	The 16-bit Internet Checksum for the specified data.
- *
- *	Note: The checksum is calculated in the machine's natural byte order,
- *	i.e. little vs. big endian. Thus, the resulting checksum is different
- *	for the same input data on little and big endian machines.
- *
- *	However, when written back to the network packet, the byte order is
- *	always in correct network order.
- */
-unsigned SkCsCalculateChecksum(
-void		*pData,		/* Data to checksum. */
-unsigned	Length)		/* Length of data. */
-{
-	SK_U16 *pU16;		/* Pointer to the data as 16-bit words. */
-	unsigned long Checksum;	/* Checksum; must be at least 32 bits. */
-
-	/* Sum up all 16-bit words. */
-
-	pU16 = (SK_U16 *) pData;
-	for (Checksum = 0; Length > 1; Length -= 2) {
-		Checksum += *pU16++;
-	}
-
-	/* If this is an odd number of bytes, add-in the last byte. */
-
-	if (Length > 0) {
-#ifdef SK_BIG_ENDIAN
-		/* Add the last byte as the high byte. */
-		Checksum += ((unsigned) *(SK_U8 *) pU16) << 8;
-#else	/* !SK_BIG_ENDIAN */
-		/* Add the last byte as the low byte. */
-		Checksum += *(SK_U8 *) pU16;
-#endif	/* !SK_BIG_ENDIAN */
-	}
-
-	/* Add-in any carries. */
-
-	SKCS_OC_ADD(Checksum, Checksum, 0);
-
-	/* Add-in any new carry. */
-
-	SKCS_OC_ADD(Checksum, Checksum, 0);
-
-	/* Note: All bits beyond the 16-bit limit are now zero. */
-
-	return ((unsigned) Checksum);
-}	/* SkCsCalculateChecksum */
-
-#endif /* SK_CS_CALCULATE_CHECKSUM */
-
-/******************************************************************************
- *
- *	SkCsEvent - the CSUM event dispatcher
- *
- * Description:
- *	This is the event handler for the CSUM module.
- *
- * Arguments:
- *	pAc - Pointer to adapter context.
- *
- *	Ioc - I/O context.
- *
- *	Event -	 Event id.
- *
- *	Param - Event dependent parameter.
- *
- * Returns:
- *	The 16-bit Internet Checksum for the specified data.
- *
- *	Note: The checksum is calculated in the machine's natural byte order,
- *	i.e. little vs. big endian. Thus, the resulting checksum is different
- *	for the same input data on little and big endian machines.
- *
- *	However, when written back to the network packet, the byte order is
- *	always in correct network order.
- */
-int SkCsEvent(
-SK_AC		*pAc,	/* Pointer to adapter context. */
-SK_IOC		Ioc,	/* I/O context. */
-SK_U32		Event,	/* Event id. */
-SK_EVPARA	Param)	/* Event dependent parameter. */
-{
-	int ProtoIndex;
-	int	NetNumber;
-
-	switch (Event) {
-	/*
-	 * Clear protocol statistics.
-	 *
-	 * Param - Protocol index, or -1 for all protocols.
-	 *		 - Net number.
-	 */
-	case SK_CSUM_EVENT_CLEAR_PROTO_STATS:
-
-		ProtoIndex = (int)Param.Para32[1];
-		NetNumber = (int)Param.Para32[0];
-		if (ProtoIndex < 0) {	/* Clear for all protocols. */
-			if (NetNumber >= 0) {
-				SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][0], 0,
-					sizeof(pAc->Csum.ProtoStats[NetNumber]));
-			}
-		}
-		else {					/* Clear for individual protocol. */
-			SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0,
-				sizeof(pAc->Csum.ProtoStats[NetNumber][ProtoIndex]));
-		}
-		break;
-	default:
-		break;
-	}
-	return (0);	/* Success. */
-}	/* SkCsEvent */
-
-#endif	/* SK_USE_CSUM */
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
index fb63995..b71769a 100644
--- a/drivers/net/sk98lin/skethtool.c
+++ b/drivers/net/sk98lin/skethtool.c
@@ -549,4 +549,6 @@
 	.phys_id		= locateDevice,
 	.get_pauseparam		= getPauseParams,
 	.set_pauseparam		= setPauseParams,
+	.get_link		= ethtool_op_get_link,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 08906ef..107c5d9 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -101,7 +101,6 @@
  *		"h/skgeinit.h"
  *		"h/skaddr.h"
  *		"h/skgesirq.h"
- *		"h/skcsum.h"
  *		"h/skrlmt.h"
  *
  ******************************************************************************/
@@ -113,6 +112,7 @@
 #include	<linux/init.h>
 #include 	<linux/proc_fs.h>
 #include	<linux/dma-mapping.h>
+#include	<linux/ip.h>
 
 #include	"h/skdrv1st.h"
 #include	"h/skdrv2nd.h"
@@ -622,11 +622,6 @@
        		return(-EAGAIN);
 	}
 
-	SkCsSetReceiveFlags(pAC,
-		SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
-		&pAC->CsOfs1, &pAC->CsOfs2, 0);
-	pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
-
 	BoardInitMem(pAC);
 	/* tschilling: New common function with minimum size check. */
 	DualNet = SK_FALSE;
@@ -844,7 +839,7 @@
 		/* set the pointers right */
 		pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
 		pDescr->pNextRxd = pNextDescr;
-		pDescr->TcpSumStarts = pAC->CsOfs;
+		pDescr->TcpSumStarts = 0;
 
 		/* advance one step */
 		pPrevDescr = pDescr;
@@ -1526,8 +1521,6 @@
 	TXD		*pOldTxd;
 	unsigned long	 Flags;
 	SK_U64		 PhysAddr;
-	int	 	 Protocol;
-	int		 IpHeaderLength;
 	int		 BytesSend = pMessage->len;
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X"));
@@ -1600,8 +1593,10 @@
 	pTxd->pMBuf     = pMessage;
 
 	if (pMessage->ip_summed == CHECKSUM_HW) {
-		Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
-		if ((Protocol == C_PROTO_ID_UDP) && 
+		u16 hdrlen = pMessage->h.raw - pMessage->data;
+		u16 offset = hdrlen + pMessage->csum;
+
+		if ((pMessage->h.ipiph->protocol == IPPROTO_UDP ) &&
 			(pAC->GIni.GIChipRev == 0) &&
 			(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
 			pTxd->TBControl = BMU_TCP_CHECK;
@@ -1609,14 +1604,9 @@
 			pTxd->TBControl = BMU_UDP_CHECK;
 		}
 
-		IpHeaderLength  = (SK_U8)pMessage->data[C_OFFSET_IPHEADER];
-		IpHeaderLength  = (IpHeaderLength & 0xf) * 4;
-		pTxd->TcpSumOfs = 0; /* PH-Checksum already calculated */
-		pTxd->TcpSumSt  = C_LEN_ETHERMAC_HEADER + IpHeaderLength + 
-							(Protocol == C_PROTO_ID_UDP ?
-							C_OFFSET_UDPHEADER_UDPCS : 
-							C_OFFSET_TCPHEADER_TCPCS);
-		pTxd->TcpSumWr  = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
+		pTxd->TcpSumOfs = 0;
+		pTxd->TcpSumSt  = hdrlen;
+		pTxd->TcpSumWr  = offset;
 
 		pTxd->TBControl |= BMU_OWN | BMU_STF | 
 				   BMU_SW  | BMU_EOF |
@@ -1679,11 +1669,10 @@
 	TXD		*pTxdLst;
 	int 	 	 CurrFrag;
 	int		 BytesSend;
-	int		 IpHeaderLength; 
-	int		 Protocol;
 	skb_frag_t	*sk_frag;
 	SK_U64		 PhysAddr;
 	unsigned long	 Flags;
+	SK_U32		 Control;
 
 	spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
 #ifndef USE_TX_COMPLETE
@@ -1706,7 +1695,6 @@
 	pTxdFst   = pTxd;
 	pTxdLst   = pTxd;
 	BytesSend = 0;
-	Protocol  = 0;
 
 	/* 
 	** Map the first fragment (header) into the DMA-space
@@ -1724,32 +1712,31 @@
 	** Does the HW need to evaluate checksum for TCP or UDP packets? 
 	*/
 	if (pMessage->ip_summed == CHECKSUM_HW) {
-		pTxd->TBControl = BMU_STF | BMU_STFWD | skb_headlen(pMessage);
+		u16 hdrlen = pMessage->h.raw - pMessage->data;
+		u16 offset = hdrlen + pMessage->csum;
+
+		Control = BMU_STFWD;
+
 		/* 
 		** We have to use the opcode for tcp here,  because the
 		** opcode for udp is not working in the hardware yet 
 		** (Revision 2.0)
 		*/
-		Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
-		if ((Protocol == C_PROTO_ID_UDP) && 
+		if ((pMessage->h.ipiph->protocol == IPPROTO_UDP ) &&
 			(pAC->GIni.GIChipRev == 0) &&
 			(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
-			pTxd->TBControl |= BMU_TCP_CHECK;
+			Control |= BMU_TCP_CHECK;
 		} else {
-			pTxd->TBControl |= BMU_UDP_CHECK;
+			Control |= BMU_UDP_CHECK;
 		}
 
-		IpHeaderLength  = ((SK_U8)pMessage->data[C_OFFSET_IPHEADER] & 0xf)*4;
-		pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */
-		pTxd->TcpSumSt  = C_LEN_ETHERMAC_HEADER + IpHeaderLength +
-						(Protocol == C_PROTO_ID_UDP ?
-						C_OFFSET_UDPHEADER_UDPCS :
-						C_OFFSET_TCPHEADER_TCPCS);
-		pTxd->TcpSumWr  = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
-	} else {
-		pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_STF |
-					skb_headlen(pMessage);
-	}
+		pTxd->TcpSumOfs = 0;
+		pTxd->TcpSumSt  = hdrlen;
+		pTxd->TcpSumWr  = offset;
+	} else
+		Control = BMU_CHECK | BMU_SW;
+
+	pTxd->TBControl = BMU_STF | Control | skb_headlen(pMessage);
 
 	pTxd = pTxd->pNextTxd;
 	pTxPort->TxdRingFree--;
@@ -1773,40 +1760,18 @@
 		pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
 		pTxd->pMBuf     = pMessage;
 		
-		/* 
-		** Does the HW need to evaluate checksum for TCP or UDP packets? 
-		*/
-		if (pMessage->ip_summed == CHECKSUM_HW) {
-			pTxd->TBControl = BMU_OWN | BMU_SW | BMU_STFWD;
-			/* 
-			** We have to use the opcode for tcp here because the 
-			** opcode for udp is not working in the hardware yet 
-			** (revision 2.0)
-			*/
-			if ((Protocol == C_PROTO_ID_UDP) && 
-				(pAC->GIni.GIChipRev == 0) &&
-				(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
-				pTxd->TBControl |= BMU_TCP_CHECK;
-			} else {
-				pTxd->TBControl |= BMU_UDP_CHECK;
-			}
-		} else {
-			pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_OWN;
-		}
+		pTxd->TBControl = Control | BMU_OWN | sk_frag->size;;
 
 		/* 
 		** Do we have the last fragment? 
 		*/
 		if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags )  {
 #ifdef USE_TX_COMPLETE
-			pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF | sk_frag->size;
+			pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF;
 #else
-			pTxd->TBControl |= BMU_EOF | sk_frag->size;
+			pTxd->TBControl |= BMU_EOF;
 #endif
 			pTxdFst->TBControl |= BMU_OWN | BMU_SW;
-
-		} else {
-			pTxd->TBControl |= sk_frag->size;
 		}
 		pTxdLst = pTxd;
 		pTxd    = pTxd->pNextTxd;
@@ -2053,7 +2018,6 @@
 struct sk_buff	*pMsg;			/* pointer to message holding frame */
 struct sk_buff	*pNewMsg;		/* pointer to a new message for copying frame */
 int				FrameLength;	/* total length of received frame */
-int				IpFrameLength;
 SK_MBUF			*pRlmtMbuf;		/* ptr to a buffer for giving a frame to rlmt */
 SK_EVPARA		EvPara;			/* an event parameter union */	
 unsigned long	Flags;			/* for spin lock */
@@ -2066,10 +2030,6 @@
 SK_BOOL  IsBadFrame; 			/* Bad frame */
 
 SK_U32			FrameStat;
-unsigned short	Csum1;
-unsigned short	Csum2;
-unsigned short	Type;
-int				Result;
 SK_U64			PhysAddr;
 
 rx_start:	
@@ -2198,8 +2158,8 @@
 						    (dma_addr_t) PhysAddr,
 						    FrameLength,
 						    PCI_DMA_FROMDEVICE);
-			eth_copy_and_sum(pNewMsg, pMsg->data,
-				FrameLength, 0);
+			memcpy(pNewMsg->data, pMsg, FrameLength);
+
 			pci_dma_sync_single_for_device(pAC->PciDev,
 						       (dma_addr_t) PhysAddr,
 						       FrameLength,
@@ -2227,69 +2187,16 @@
 
 			/* set length in message */
 			skb_put(pMsg, FrameLength);
-			/* hardware checksum */
-			Type = ntohs(*((short*)&pMsg->data[12]));
+		} /* frame > SK_COPY_TRESHOLD */
 
 #ifdef USE_SK_RX_CHECKSUM
-			if (Type == 0x800) {
-				Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
-				Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
-				IpFrameLength = (int) ntohs((unsigned short)
-								((unsigned short *) pMsg->data)[8]);
-
-				/*
-				 * Test: If frame is padded, a check is not possible!
-				 * Frame not padded? Length difference must be 14 (0xe)!
-				 */
-				if ((FrameLength - IpFrameLength) != 0xe) {
-				/* Frame padded => TCP offload not possible! */
-					pMsg->ip_summed = CHECKSUM_NONE;
-				} else {
-				/* Frame not padded => TCP offload! */
-					if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
-						(pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
-						(pAC->ChipsetType)) {
-						Result = SkCsGetReceiveInfo(pAC,
-							&pMsg->data[14],
-							Csum1, Csum2, pRxPort->PortIndex);
-						if (Result ==
-							SKCS_STATUS_IP_FRAGMENT ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_OK ||
-							Result ==
-							SKCS_STATUS_TCP_CSUM_OK ||
-							Result ==
-							SKCS_STATUS_UDP_CSUM_OK) {
-								pMsg->ip_summed =
-								CHECKSUM_UNNECESSARY;
-						}
-						else if (Result ==
-							SKCS_STATUS_TCP_CSUM_ERROR ||
-							Result ==
-							SKCS_STATUS_UDP_CSUM_ERROR ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_ERROR_UDP ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_ERROR_TCP ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_ERROR ) {
-							/* HW Checksum error */
-							SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-							SK_DBGCAT_DRV_RX_PROGRESS,
-							("skge: CRC error. Frame dropped!\n"));
-							goto rx_failed;
-						} else {
-								pMsg->ip_summed =
-								CHECKSUM_NONE;
-						}
-					}/* checksumControl calculation valid */
-				} /* Frame length check */
-			} /* IP frame */
+		pMsg->csum = pRxd->TcpSums;
+		pMsg->ip_summed = CHECKSUM_HW;
 #else
-			pMsg->ip_summed = CHECKSUM_NONE;	
+		pMsg->ip_summed = CHECKSUM_NONE;
 #endif
-		} /* frame > SK_COPY_TRESHOLD */
-		
+
+
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("V"));
 		ForRlmt = SK_RLMT_RX_PROTOCOL;
 #if 0
@@ -4945,7 +4852,7 @@
 	dev->irq = pdev->irq;
 	error = SkGeInitPCI(pAC);
 	if (error) {
-		printk("SKGE: PCI setup failed: %i\n", error);
+		printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error);
 		goto out_free_netdev;
 	}
 
@@ -4981,7 +4888,7 @@
 
 	/* Register net device */
 	if (register_netdev(dev)) {
-		printk(KERN_ERR "SKGE: Could not register device.\n");
+		printk(KERN_ERR "sk98lin: Could not register device.\n");
 		goto out_free_resources;
 	}
 
@@ -5000,8 +4907,8 @@
 
 	SkGeYellowLED(pAC, pAC->IoBase, 1);
 
-
 	memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	SkGeProcCreate(dev);
 
@@ -5047,13 +4954,14 @@
 #endif
 
 		if (register_netdev(dev)) {
-			printk(KERN_ERR "SKGE: Could not register device.\n");
+			printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n");
 			free_netdev(dev);
 			pAC->dev[1] = pAC->dev[0];
 		} else {
 			SkGeProcCreate(dev);
 			memcpy(&dev->dev_addr,
 					&pAC->Addr.Net[1].CurrentMacAddress, 6);
+			memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	
 			printk("%s: %s\n", dev->name, pAC->DeviceStr);
 			printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");