summaryrefslogtreecommitdiffstats
path: root/drivers/net/sk98lin
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sk98lin')
-rw-r--r--drivers/net/sk98lin/Makefile6
-rw-r--r--drivers/net/sk98lin/h/skdrv2nd.h13
-rw-r--r--drivers/net/sk98lin/h/skvpd.h8
-rw-r--r--drivers/net/sk98lin/skcsum.c871
-rw-r--r--drivers/net/sk98lin/skdim.c2
-rw-r--r--drivers/net/sk98lin/skethtool.c50
-rw-r--r--drivers/net/sk98lin/skge.c508
-rw-r--r--drivers/net/sk98lin/skgepnmi.c8
-rw-r--r--drivers/net/sk98lin/skproc.c265
9 files changed, 254 insertions, 1477 deletions
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
index 6783039ffb7..afd900d5d73 100644
--- a/drivers/net/sk98lin/Makefile
+++ b/drivers/net/sk98lin/Makefile
@@ -26,9 +26,7 @@ sk98lin-objs := \
skrlmt.o \
sktimer.o \
skvpd.o \
- skxmac2.o \
- skproc.o \
- skcsum.o
+ skxmac2.o
# DBGDEF = \
# -DDEBUG
@@ -77,7 +75,7 @@ endif
# 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 542cec57f86..778d9e618eb 100644
--- a/drivers/net/sk98lin/h/skdrv2nd.h
+++ b/drivers/net/sk98lin/h/skdrv2nd.h
@@ -60,7 +60,6 @@ extern SK_U64 SkOsGetTime(SK_AC*);
extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*);
extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*);
-extern int SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16);
extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8);
extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
@@ -268,8 +267,6 @@ typedef struct s_DevNet DEV_NET;
struct s_DevNet {
int PortNr;
int NetNr;
- int Mtu;
- int Up;
SK_AC *pAC;
};
@@ -298,6 +295,7 @@ struct s_RxPort {
RXD *pRxdRingTail; /* Tail of Rx rings */
RXD *pRxdRingPrev; /* descriptor given to BMU previously */
int RxdRingFree; /* # of free entrys */
+ int RxCsum; /* use receive checksum hardware */
spinlock_t RxDesRingLock; /* serialize descriptor accesses */
int RxFillLimit; /* limit for buffers in ring */
SK_IOC HwAddr; /* bmu registers address */
@@ -390,12 +388,10 @@ struct s_AC {
SK_IOC IoBase; /* register set of adapter */
int BoardLevel; /* level of active hw init (0-2) */
- char DeviceStr[80]; /* adapter string from vpd */
+
SK_U32 AllocFlag; /* flag allocation of resources */
struct pci_dev *PciDev; /* for access to pci config space */
- SK_U32 PciDevId; /* pci device id */
struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */
- char Name[30]; /* driver name */
int RxBufSize; /* length of receive buffers */
struct net_device_stats stats; /* linux 'netstat -i' statistics */
@@ -425,16 +421,11 @@ struct s_AC {
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 */
/* Only for tests */
- int PortUp;
int PortDown;
int ChipsetType; /* Chipset family type
* 0 == Genesis family support
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
index bdc1a5eaaae..daa9a8d154f 100644
--- a/drivers/net/sk98lin/h/skvpd.h
+++ b/drivers/net/sk98lin/h/skvpd.h
@@ -130,14 +130,12 @@ typedef struct s_vpd_key {
#ifndef VPD_DO_IO
#define VPD_OUT8(pAC,IoC,Addr,Val) (void)SkPciWriteCfgByte(pAC,Addr,Val)
#define VPD_OUT16(pAC,IoC,Addr,Val) (void)SkPciWriteCfgWord(pAC,Addr,Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val) (void)SkPciWriteCfgDWord(pAC,Addr,Val)
#define VPD_IN8(pAC,IoC,Addr,pVal) (void)SkPciReadCfgByte(pAC,Addr,pVal)
#define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal)
#define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal)
#else /* VPD_DO_IO */
#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val)
#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val) SK_OUT32(IoC,PCI_C(Addr),Val)
#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal)
#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal)
#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal)
@@ -155,12 +153,6 @@ typedef struct s_vpd_key {
else \
SK_OUT16(pAC,PCI_C(Addr),Val); \
}
-#define VPD_OUT32(pAC,Ioc,Addr,Val) { \
- if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciWriteCfgDWord(pAC,Addr,Val); \
- else \
- SK_OUT32(pAC,PCI_C(Addr),Val); \
- }
#define VPD_IN8(pAC,Ioc,Addr,pVal) { \
if ((pAC)->DgT.DgUseCfgCycle) \
SkPciReadCfgByte(pAC,Addr,pVal); \
diff --git a/drivers/net/sk98lin/skcsum.c b/drivers/net/sk98lin/skcsum.c
deleted file mode 100644
index 38a6e7a631f..00000000000
--- 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/skdim.c b/drivers/net/sk98lin/skdim.c
index 0fddf61047b..07c1b4c8699 100644
--- a/drivers/net/sk98lin/skdim.c
+++ b/drivers/net/sk98lin/skdim.c
@@ -180,7 +180,7 @@ SkDimModerate(SK_AC *pAC) {
/*
** The number of interrupts per sec is the same as expected.
** Evalulate the descriptor-ratio. If it has changed, a resize
- ** in the moderation timer might be usefull
+ ** in the moderation timer might be useful
*/
if (M_DIMINFO.AutoSizing) {
ResizeDimTimerDuration(pAC);
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
index fb639959292..4265ed91a9c 100644
--- a/drivers/net/sk98lin/skethtool.c
+++ b/drivers/net/sk98lin/skethtool.c
@@ -539,6 +539,48 @@ static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *ep
return ret ? -EIO : 0;
}
+/* Only Yukon supports checksum offload. */
+static int setScatterGather(struct net_device *dev, u32 data)
+{
+ DEV_NET *pNet = netdev_priv(dev);
+ SK_AC *pAC = pNet->pAC;
+
+ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+ return -EOPNOTSUPP;
+ return ethtool_op_set_sg(dev, data);
+}
+
+static int setTxCsum(struct net_device *dev, u32 data)
+{
+ DEV_NET *pNet = netdev_priv(dev);
+ SK_AC *pAC = pNet->pAC;
+
+ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+ return -EOPNOTSUPP;
+
+ return ethtool_op_set_tx_csum(dev, data);
+}
+
+static u32 getRxCsum(struct net_device *dev)
+{
+ DEV_NET *pNet = netdev_priv(dev);
+ SK_AC *pAC = pNet->pAC;
+
+ return pAC->RxPort[pNet->PortNr].RxCsum;
+}
+
+static int setRxCsum(struct net_device *dev, u32 data)
+{
+ DEV_NET *pNet = netdev_priv(dev);
+ SK_AC *pAC = pNet->pAC;
+
+ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+ return -EOPNOTSUPP;
+
+ pAC->RxPort[pNet->PortNr].RxCsum = data != 0;
+ return 0;
+}
+
struct ethtool_ops SkGeEthtoolOps = {
.get_settings = getSettings,
.set_settings = setSettings,
@@ -549,4 +591,12 @@ struct ethtool_ops SkGeEthtoolOps = {
.phys_id = locateDevice,
.get_pauseparam = getPauseParams,
.set_pauseparam = setPauseParams,
+ .get_link = ethtool_op_get_link,
+ .get_perm_addr = ethtool_op_get_perm_addr,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = setScatterGather,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = setTxCsum,
+ .get_rx_csum = getRxCsum,
+ .set_rx_csum = setRxCsum,
};
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index b18c92cb629..a5f2b1ee075 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -101,18 +101,18 @@
* "h/skgeinit.h"
* "h/skaddr.h"
* "h/skgesirq.h"
- * "h/skcsum.h"
* "h/skrlmt.h"
*
******************************************************************************/
#include "h/skversion.h"
+#include <linux/in.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#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"
@@ -206,7 +206,6 @@ static void SkGeSetRxMode(struct SK_NET_DEVICE *dev);
static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
static void GetConfiguration(SK_AC*);
-static void ProductStr(SK_AC*);
static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
static void FillRxRing(SK_AC*, RX_PORT*);
@@ -235,28 +234,6 @@ static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
* Extern Function Prototypes
*
******************************************************************************/
-static const char SKRootName[] = "net/sk98lin";
-static struct proc_dir_entry *pSkRootDir;
-extern struct file_operations sk_proc_fops;
-
-static inline void SkGeProcCreate(struct net_device *dev)
-{
- struct proc_dir_entry *pe;
-
- if (pSkRootDir &&
- (pe = create_proc_entry(dev->name, S_IRUGO, pSkRootDir))) {
- pe->proc_fops = &sk_proc_fops;
- pe->data = dev;
- pe->owner = THIS_MODULE;
- }
-}
-
-static inline void SkGeProcRemove(struct net_device *dev)
-{
- if (pSkRootDir)
- remove_proc_entry(dev->name, pSkRootDir);
-}
-
extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
extern void SkDimDisplayModerationSettings(SK_AC *pAC);
extern void SkDimStartModerationTimer(SK_AC *pAC);
@@ -279,31 +256,48 @@ static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
/*****************************************************************************
*
+ * SkPciWriteCfgDWord - write a 32 bit value to pci config space
+ *
+ * Description:
+ * This routine writes a 32 bit value to the pci configuration
+ * space.
+ *
+ * Returns:
+ * 0 - indicate everything worked ok.
+ * != 0 - error indication
+ */
+static inline int SkPciWriteCfgDWord(
+SK_AC *pAC, /* Adapter Control structure pointer */
+int PciAddr, /* PCI register address */
+SK_U32 Val) /* pointer to store the read value */
+{
+ pci_write_config_dword(pAC->PciDev, PciAddr, Val);
+ return(0);
+} /* SkPciWriteCfgDWord */
+
+/*****************************************************************************
+ *
* SkGeInitPCI - Init the PCI resources
*
* Description:
* This function initialize the PCI resources and IO
*
- * Returns: N/A
- *
+ * Returns:
+ * 0 - indicate everything worked ok.
+ * != 0 - error indication
*/
-int SkGeInitPCI(SK_AC *pAC)
+static __devinit int SkGeInitPCI(SK_AC *pAC)
{
struct SK_NET_DEVICE *dev = pAC->dev[0];
struct pci_dev *pdev = pAC->PciDev;
int retval;
- if (pci_enable_device(pdev) != 0) {
- return 1;
- }
-
dev->mem_start = pci_resource_start (pdev, 0);
pci_set_master(pdev);
- if (pci_request_regions(pdev, pAC->Name) != 0) {
- retval = 2;
- goto out_disable;
- }
+ retval = pci_request_regions(pdev, "sk98lin");
+ if (retval)
+ goto out;
#ifdef SK_BIG_ENDIAN
/*
@@ -322,9 +316,8 @@ int SkGeInitPCI(SK_AC *pAC)
* Remap the regs into kernel space.
*/
pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
-
- if (!pAC->IoBase){
- retval = 3;
+ if (!pAC->IoBase) {
+ retval = -EIO;
goto out_release;
}
@@ -332,8 +325,7 @@ int SkGeInitPCI(SK_AC *pAC)
out_release:
pci_release_regions(pdev);
- out_disable:
- pci_disable_device(pdev);
+ out:
return retval;
}
@@ -494,7 +486,7 @@ module_param_array(AutoSizing, charp, NULL, 0);
* 0, if everything is ok
* !=0, on error
*/
-static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
+static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
{
short i;
unsigned long Flags;
@@ -531,7 +523,7 @@ SK_BOOL DualNet;
if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
printk("HWInit (0) failed.\n");
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- return(-EAGAIN);
+ return -EIO;
}
SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA);
SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
@@ -553,7 +545,7 @@ SK_BOOL DualNet;
if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
printk("sk98lin: HWInit (1) failed.\n");
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- return(-EAGAIN);
+ return -EIO;
}
SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
@@ -578,34 +570,29 @@ SK_BOOL DualNet;
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
if (pAC->GIni.GIMacsFound == 2) {
- Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+ Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev);
} else if (pAC->GIni.GIMacsFound == 1) {
Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
- pAC->Name, dev);
+ "sk98lin", dev);
} else {
printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
pAC->GIni.GIMacsFound);
- return -EAGAIN;
+ return -EIO;
}
if (Ret) {
printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
dev->irq);
- return -EAGAIN;
+ return Ret;
}
pAC->AllocFlag |= SK_ALLOC_IRQ;
/* Alloc memory for this board (Mem for RxD/TxD) : */
if(!BoardAllocMem(pAC)) {
printk("No memory for descriptor rings.\n");
- return(-EAGAIN);
+ return -ENOMEM;
}
- 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;
@@ -619,7 +606,7 @@ SK_BOOL DualNet;
DualNet)) {
BoardFreeMem(pAC);
printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
- return(-EAGAIN);
+ return -EIO;
}
return (0);
@@ -640,8 +627,7 @@ SK_BOOL DualNet;
* SK_TRUE, if all memory could be allocated
* SK_FALSE, if not
*/
-static SK_BOOL BoardAllocMem(
-SK_AC *pAC)
+static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC)
{
caddr_t pDescrMem; /* pointer to descriptor memory area */
size_t AllocLength; /* length of complete descriptor area */
@@ -734,8 +720,7 @@ size_t AllocLength; /* length of complete descriptor area */
*
* Returns: N/A
*/
-static void BoardInitMem(
-SK_AC *pAC) /* pointer to adapter context */
+static __devinit void BoardInitMem(SK_AC *pAC)
{
int i; /* loop counter */
int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/
@@ -823,7 +808,7 @@ uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */
/* set the pointers right */
pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
pDescr->pNextRxd = pNextDescr;
- pDescr->TcpSumStarts = pAC->CsOfs;
+ if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN;
/* advance one step */
pPrevDescr = pDescr;
@@ -1270,7 +1255,6 @@ struct SK_NET_DEVICE *dev)
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
pAC->MaxPorts++;
- pNet->Up = 1;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
@@ -1400,7 +1384,6 @@ struct SK_NET_DEVICE *dev)
sizeof(SK_PNMI_STRUCT_DATA));
pAC->MaxPorts--;
- pNet->Up = 0;
return (0);
} /* SkGeClose */
@@ -1505,8 +1488,6 @@ struct sk_buff *pMessage) /* pointer to send-message */
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"));
@@ -1579,8 +1560,10 @@ struct sk_buff *pMessage) /* pointer to send-message */
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;
@@ -1588,14 +1571,9 @@ struct sk_buff *pMessage) /* pointer to send-message */
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 |
@@ -1658,11 +1636,10 @@ struct sk_buff *pMessage) /* pointer to send-message */
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
@@ -1685,7 +1662,6 @@ struct sk_buff *pMessage) /* pointer to send-message */
pTxdFst = pTxd;
pTxdLst = pTxd;
BytesSend = 0;
- Protocol = 0;
/*
** Map the first fragment (header) into the DMA-space
@@ -1703,32 +1679,31 @@ struct sk_buff *pMessage) /* pointer to send-message */
** 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--;
@@ -1752,40 +1727,18 @@ struct sk_buff *pMessage) /* pointer to send-message */
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;
@@ -2032,7 +1985,6 @@ SK_U32 Control; /* control field of descriptor */
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 */
@@ -2045,10 +1997,6 @@ SK_BOOL IsMc;
SK_BOOL IsBadFrame; /* Bad frame */
SK_U32 FrameStat;
-unsigned short Csum1;
-unsigned short Csum2;
-unsigned short Type;
-int Result;
SK_U64 PhysAddr;
rx_start:
@@ -2177,8 +2125,8 @@ rx_start:
(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,
@@ -2206,69 +2154,15 @@ rx_start:
/* 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 & 0xffff;
+ 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
@@ -2643,7 +2537,7 @@ unsigned long Flags;
static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
{
DEV_NET *pNet;
-DEV_NET *pOtherNet;
+struct net_device *pOtherDev;
SK_AC *pAC;
unsigned long Flags;
int i;
@@ -2673,11 +2567,11 @@ SK_EVPARA EvPara;
}
#endif
- pNet->Mtu = NewMtu;
- pOtherNet = netdev_priv(pAC->dev[1 - pNet->NetNr]);
- if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
- return(0);
- }
+ pOtherDev = pAC->dev[1 - pNet->NetNr];
+
+ if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500)
+ && (NewMtu <= 1500))
+ return 0;
pAC->RxBufSize = NewMtu + 32;
dev->mtu = NewMtu;
@@ -2839,7 +2733,8 @@ SK_EVPARA EvPara;
EvPara.Para32[1] = -1;
SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
- if (pOtherNet->Up) {
+ if (netif_running(pOtherDev)) {
+ DEV_NET *pOtherNet = netdev_priv(pOtherDev);
EvPara.Para32[0] = pOtherNet->PortNr;
SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
}
@@ -2913,7 +2808,7 @@ unsigned long Flags; /* for spin lock */
pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
- if (pNet->Mtu <= 1500) {
+ if (dev->mtu <= 1500) {
pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
} else {
pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
@@ -2956,7 +2851,7 @@ unsigned long Flags; /* for spin lock */
* Description:
* This function is called if an ioctl is issued on the device.
* There are three subfunction for reading, writing and test-writing
- * the private MIB data structure (usefull for SysKonnect-internal tools).
+ * the private MIB data structure (useful for SysKonnect-internal tools).
*
* Returns:
* 0, if everything is ok
@@ -3864,25 +3759,21 @@ int Capabilities[3][3] =
*
* Returns: N/A
*/
-static void ProductStr(
-SK_AC *pAC /* pointer to adapter context */
+static inline int ProductStr(
+ SK_AC *pAC, /* pointer to adapter context */
+ char *DeviceStr, /* result string */
+ int StrLen /* length of the string */
)
{
-int StrLen = 80; /* length of the string, defined in SK_AC */
char Keyword[] = VPD_NAME; /* vpd productname identifier */
int ReturnCode; /* return code from vpd_read */
unsigned long Flags;
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
- &StrLen);
+ ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen);
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- if (ReturnCode != 0) {
- /* there was an error reading the vpd data */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
- ("Error reading VPD data: %d\n", ReturnCode));
- pAC->DeviceStr[0] = '\0';
- }
+
+ return ReturnCode;
} /* ProductStr */
/*****************************************************************************
@@ -4085,28 +3976,6 @@ SK_U8 *pVal) /* pointer to store the read value */
/*****************************************************************************
*
- * SkPciWriteCfgDWord - write a 32 bit value to pci config space
- *
- * Description:
- * This routine writes a 32 bit value to the pci configuration
- * space.
- *
- * Returns:
- * 0 - indicate everything worked ok.
- * != 0 - error indication
- */
-int SkPciWriteCfgDWord(
-SK_AC *pAC, /* Adapter Control structure pointer */
-int PciAddr, /* PCI register address */
-SK_U32 Val) /* pointer to store the read value */
-{
- pci_write_config_dword(pAC->PciDev, PciAddr, Val);
- return(0);
-} /* SkPciWriteCfgDWord */
-
-
-/*****************************************************************************
- *
* SkPciWriteCfgWord - write a 16 bit value to pci config space
*
* Description:
@@ -4243,6 +4112,7 @@ SK_BOOL DualNet;
Flags);
break;
case SK_DRV_NET_UP: /* SK_U32 PortIdx */
+ { struct net_device *dev = pAC->dev[Param.Para32[0]];
/* action list 5 */
FromPort = Param.Para32[0];
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4326,22 +4196,12 @@ SK_BOOL DualNet;
printk(" irq moderation: disabled\n");
-#ifdef SK_ZEROCOPY
- if (pAC->ChipsetType)
-#ifdef USE_SK_TX_CHECKSUM
- printk(" scatter-gather: enabled\n");
-#else
- printk(" tx-checksum: disabled\n");
-#endif
- else
- printk(" scatter-gather: disabled\n");
-#else
- printk(" scatter-gather: disabled\n");
-#endif
-
-#ifndef USE_SK_RX_CHECKSUM
- printk(" rx-checksum: disabled\n");
-#endif
+ printk(" scatter-gather: %s\n",
+ (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
+ printk(" tx-checksum: %s\n",
+ (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
+ printk(" rx-checksum: %s\n",
+ pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
} else {
DoPrintInterfaceChange = SK_TRUE;
@@ -4356,9 +4216,9 @@ SK_BOOL DualNet;
}
/* Inform the world that link protocol is up. */
- netif_carrier_on(pAC->dev[Param.Para32[0]]);
-
+ netif_carrier_on(dev);
break;
+ }
case SK_DRV_NET_DOWN: /* SK_U32 Reason */
/* action list 7 */
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4572,7 +4432,7 @@ SK_AC *pAc) /* pointer to adapter context */
pAC->DiagModeActive = DIAG_ACTIVE;
if (pAC->BoardLevel > SK_INIT_DATA) {
- if (pNet->Up) {
+ if (netif_running(pAC->dev[0])) {
pAC->WasIfUp[0] = SK_TRUE;
pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
DoPrintInterfaceChange = SK_FALSE;
@@ -4582,7 +4442,7 @@ SK_AC *pAc) /* pointer to adapter context */
}
if (pNet != netdev_priv(pAC->dev[1])) {
pNet = netdev_priv(pAC->dev[1]);
- if (pNet->Up) {
+ if (netif_running(pAC->dev[1])) {
pAC->WasIfUp[1] = SK_TRUE;
pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
DoPrintInterfaceChange = SK_FALSE;
@@ -4908,45 +4768,59 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
struct net_device *dev = NULL;
static int boards_found = 0;
int error = -ENODEV;
+ int using_dac = 0;
+ char DeviceStr[80];
if (pci_enable_device(pdev))
goto out;
/* Configure DMA attributes. */
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
- pci_set_dma_mask(pdev, DMA_32BIT_MASK))
- goto out_disable_device;
-
+ if (sizeof(dma_addr_t) > sizeof(u32) &&
+ !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+ using_dac = 1;
+ error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (error < 0) {
+ printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA "
+ "for consistent allocations\n", pci_name(pdev));
+ goto out_disable_device;
+ }
+ } else {
+ error = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (error) {
+ printk(KERN_ERR "sk98lin %s no usable DMA configuration\n",
+ pci_name(pdev));
+ goto out_disable_device;
+ }
+ }
- if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) {
- printk(KERN_ERR "Unable to allocate etherdev "
+ error = -ENOMEM;
+ dev = alloc_etherdev(sizeof(DEV_NET));
+ if (!dev) {
+ printk(KERN_ERR "sk98lin: unable to allocate etherdev "
"structure!\n");
goto out_disable_device;
}
pNet = netdev_priv(dev);
- pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
+ pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL);
if (!pNet->pAC) {
- printk(KERN_ERR "Unable to allocate adapter "
+ printk(KERN_ERR "sk98lin: unable to allocate adapter "
"structure!\n");
goto out_free_netdev;
}
- memset(pNet->pAC, 0, sizeof(SK_AC));
pAC = pNet->pAC;
pAC->PciDev = pdev;
- pAC->PciDevId = pdev->device;
+
pAC->dev[0] = dev;
pAC->dev[1] = dev;
- sprintf(pAC->Name, "SysKonnect SK-98xx");
pAC->CheckQueue = SK_FALSE;
- pNet->Mtu = 1500;
- pNet->Up = 0;
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;
}
@@ -4965,30 +4839,44 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev);
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
+ /* Use only if yukon hardware */
if (pAC->ChipsetType) {
- /* Use only if yukon hardware */
- /* SK and ZEROCOPY - fly baby... */
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- }
+#ifdef USE_SK_TX_CHECKSUM
+ dev->features |= NETIF_F_IP_CSUM;
#endif
+#ifdef SK_ZEROCOPY
+ dev->features |= NETIF_F_SG;
+#endif
+#ifdef USE_SK_RX_CHECKSUM
+ pAC->RxPort[0].RxCsum = 1;
#endif
+ }
+
+ if (using_dac)
+ dev->features |= NETIF_F_HIGHDMA;
pAC->Index = boards_found++;
- if (SkGeBoardInit(dev, pAC))
+ error = SkGeBoardInit(dev, pAC);
+ if (error)
goto out_free_netdev;
+ /* Read Adapter name from VPD */
+ if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
+ error = -EIO;
+ printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
+ goto out_free_resources;
+ }
+
/* Register net device */
- if (register_netdev(dev)) {
- printk(KERN_ERR "SKGE: Could not register device.\n");
+ error = register_netdev(dev);
+ if (error) {
+ printk(KERN_ERR "sk98lin: Could not register device.\n");
goto out_free_resources;
}
/* Print adapter specific string from vpd */
- ProductStr(pAC);
- printk("%s: %s\n", dev->name, pAC->DeviceStr);
+ printk("%s: %s\n", dev->name, DeviceStr);
/* Print configuration settings */
printk(" PrefPort:%c RlmtMode:%s\n",
@@ -5001,31 +4889,29 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
SkGeYellowLED(pAC, pAC->IoBase, 1);
-
memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
-
- SkGeProcCreate(dev);
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
pNet->PortNr = 0;
pNet->NetNr = 0;
boards_found++;
+ pci_set_drvdata(pdev, dev);
+
/* More then one port found */
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
- if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) {
- printk(KERN_ERR "Unable to allocate etherdev "
+ dev = alloc_etherdev(sizeof(DEV_NET));
+ if (!dev) {
+ printk(KERN_ERR "sk98lin: unable to allocate etherdev "
"structure!\n");
- goto out;
+ goto single_port;
}
- pAC->dev[1] = dev;
pNet = netdev_priv(dev);
pNet->PortNr = 1;
pNet->NetNr = 1;
pNet->pAC = pAC;
- pNet->Mtu = 1500;
- pNet->Up = 0;
dev->open = &SkGeOpen;
dev->stop = &SkGeClose;
@@ -5038,29 +4924,40 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev);
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
if (pAC->ChipsetType) {
- /* SG and ZEROCOPY - fly baby... */
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- }
+#ifdef USE_SK_TX_CHECKSUM
+ dev->features |= NETIF_F_IP_CSUM;
#endif
+#ifdef SK_ZEROCOPY
+ dev->features |= NETIF_F_SG;
+#endif
+#ifdef USE_SK_RX_CHECKSUM
+ pAC->RxPort[1].RxCsum = 1;
#endif
+ }
+
+ if (using_dac)
+ dev->features |= NETIF_F_HIGHDMA;
- if (register_netdev(dev)) {
- printk(KERN_ERR "SKGE: Could not register device.\n");
+ error = register_netdev(dev);
+ if (error) {
+ printk(KERN_ERR "sk98lin: Could not register device"
+ " for second port. (%d)\n", error);
free_netdev(dev);
- pAC->dev[1] = pAC->dev[0];
- } else {
- SkGeProcCreate(dev);
- memcpy(&dev->dev_addr,
- &pAC->Addr.Net[1].CurrentMacAddress, 6);
-
- printk("%s: %s\n", dev->name, pAC->DeviceStr);
- printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
+ goto single_port;
}
+
+ pAC->dev[1] = 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, DeviceStr);
+ printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
}
+single_port:
+
/* Save the hardware revision */
pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
(pAC->GIni.GIPciHwRev & 0x0F);
@@ -5072,7 +4969,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
- pci_set_drvdata(pdev, dev);
return 0;
out_free_resources:
@@ -5092,10 +4988,7 @@ static void __devexit skge_remove_one(struct pci_dev *pdev)
SK_AC *pAC = pNet->pAC;
struct net_device *otherdev = pAC->dev[1];
- SkGeProcRemove(dev);
unregister_netdev(dev);
- if (otherdev != dev)
- SkGeProcRemove(otherdev);
SkGeYellowLED(pAC, pAC->IoBase, 0);
@@ -5180,9 +5073,9 @@ static int skge_resume(struct pci_dev *pdev)
pci_enable_device(pdev);
pci_set_master(pdev);
if (pAC->GIni.GIMacsFound == 2)
- ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+ ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev);
else
- ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev);
+ ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, "sk98lin", dev);
if (ret) {
printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
pAC->AllocFlag &= ~SK_ALLOC_IRQ;
@@ -5240,23 +5133,12 @@ static struct pci_driver skge_driver = {
static int __init skge_init(void)
{
- int error;
-
- pSkRootDir = proc_mkdir(SKRootName, NULL);
- if (pSkRootDir)
- pSkRootDir->owner = THIS_MODULE;
-
- error = pci_register_driver(&skge_driver);
- if (error)
- remove_proc_entry(SKRootName, NULL);
- return error;
+ return pci_module_init(&skge_driver);
}
static void __exit skge_exit(void)
{
pci_unregister_driver(&skge_driver);
- remove_proc_entry(SKRootName, NULL);
-
}
module_init(skge_init);
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
index 58e1a5be913..a386172107e 100644
--- a/drivers/net/sk98lin/skgepnmi.c
+++ b/drivers/net/sk98lin/skgepnmi.c
@@ -611,7 +611,7 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
* Description:
* Calls a general sub-function for all this stuff. The preset does
* the same as a set, but returns just before finally setting the
- * new value. This is usefull to check if a set might be successfull.
+ * new value. This is useful to check if a set might be successfull.
* If the instance -1 is passed, an array of values is supposed and
* all instances of the OID will be set.
*
@@ -654,7 +654,7 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
* Description:
* Calls a general sub-function for all this stuff. The preset does
* the same as a set, but returns just before finally setting the
- * new value. This is usefull to check if a set might be successfull.
+ * new value. This is useful to check if a set might be successfull.
* If the instance -1 is passed, an array of values is supposed and
* all instances of the OID will be set.
*
@@ -870,7 +870,7 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
* Description:
* Calls a general sub-function for all this set stuff. The preset does
* the same as a set, but returns just before finally setting the
- * new value. This is usefull to check if a set might be successfull.
+ * new value. This is useful to check if a set might be successfull.
* The sub-function runs through the IdTable, checks which OIDs are able
* to set, and calls the handler function of the OID to perform the
* preset. The return value of the function will also be stored in
@@ -6473,7 +6473,7 @@ unsigned int PhysPortIndex) /* Physical port index */
*
* Description:
* The COMMON module only tells us if the mode is half or full duplex.
- * But in the decade of auto sensing it is usefull for the user to
+ * But in the decade of auto sensing it is useful for the user to
* know if the mode was negotiated or forced. Therefore we have a
* look to the mode, which was last used by the negotiation process.
*
diff --git a/drivers/net/sk98lin/skproc.c b/drivers/net/sk98lin/skproc.c
deleted file mode 100644
index 5cece25c034..00000000000
--- a/drivers/net/sk98lin/skproc.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/******************************************************************************
- *
- * Name: skproc.c
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.11 $
- * Date: $Date: 2003/12/11 16:03:57 $
- * Purpose: Funktions to display statictic data
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * 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.
- *
- * Created 22-Nov-2000
- * Author: Mirko Lindner (mlindner@syskonnect.de)
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-#include "h/skversion.h"
-
-static int sk_seq_show(struct seq_file *seq, void *v);
-static int sk_proc_open(struct inode *inode, struct file *file);
-
-struct file_operations sk_proc_fops = {
- .owner = THIS_MODULE,
- .open = sk_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-
-/*****************************************************************************
- *
- * sk_seq_show - show proc information of a particular adapter
- *
- * Description:
- * This function fills the proc entry with statistic data about
- * the ethernet device. It invokes the generic sk_gen_browse() to
- * print out all items one per one.
- *
- * Returns: 0
- *
- */
-static int sk_seq_show(struct seq_file *seq, void *v)
-{
- struct net_device *dev = seq->private;
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
- SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
- unsigned long Flags;
- unsigned int Size;
- char sens_msg[50];
- int t;
- int i;
-
- /* NetIndex in GetStruct is now required, zero is only dummy */
- for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
- if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
- t--;
-
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- Size = SK_PNMI_STRUCT_SIZE;
-#ifdef SK_DIAG_SUPPORT
- if (pAC->BoardLevel == SK_INIT_DATA) {
- SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
- if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
- pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
- }
- } else {
- SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
- }
-#else
- SkPnmiGetStruct(pAC, pAC->IoBase,
- pPnmiStruct, &Size, t-1);
-#endif
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
- if (pAC->dev[t-1] == dev) {
- SK_PNMI_STAT *pPnmiStat = &pPnmiStruct->Stat[0];
-
- seq_printf(seq, "\nDetailed statistic for device %s\n",
- pAC->dev[t-1]->name);
- seq_printf(seq, "=======================================\n");
-
- /* Board statistics */
- seq_printf(seq, "\nBoard statistics\n\n");
- seq_printf(seq, "Active Port %c\n",
- 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
- Net[t-1].PrefPort]->PortNumber);
- seq_printf(seq, "Preferred Port %c\n",
- 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
- Net[t-1].PrefPort]->PortNumber);
-
- seq_printf(seq, "Bus speed (MHz) %d\n",
- pPnmiStruct->BusSpeed);
-
- seq_printf(seq, "Bus width (Bit) %d\n",
- pPnmiStruct->BusWidth);
- seq_printf(seq, "Driver version %s\n",
- VER_STRING);
- seq_printf(seq, "Hardware revision v%d.%d\n",
- (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
- pAC->GIni.GIPciHwRev & 0x0F);
-
- /* Print sensor informations */
- for (i=0; i < pAC->I2c.MaxSens; i ++) {
- /* Check type */
- switch (pAC->I2c.SenTable[i].SenType) {
- case 1:
- strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
- strcat(sens_msg, " (C)");
- seq_printf(seq, "%-25s %d.%02d\n",
- sens_msg,
- pAC->I2c.SenTable[i].SenValue / 10,
- pAC->I2c.SenTable[i].SenValue % 10);
-
- strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
- strcat(sens_msg, " (F)");
- seq_printf(seq, "%-25s %d.%02d\n",
- sens_msg,
- ((((pAC->I2c.SenTable[i].SenValue)
- *10)*9)/5 + 3200)/100,
- ((((pAC->I2c.SenTable[i].SenValue)
- *10)*9)/5 + 3200) % 10);
- break;
- case 2:
- strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
- strcat(sens_msg, " (V)");
- seq_printf(seq, "%-25s %d.%03d\n",
- sens_msg,
- pAC->I2c.SenTable[i].SenValue / 1000,
- pAC->I2c.SenTable[i].SenValue % 1000);
- break;
- case 3:
- strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
- strcat(sens_msg, " (rpm)");
- seq_printf(seq, "%-25s %d\n",
- sens_msg,
- pAC->I2c.SenTable[i].SenValue);
- break;
- default:
- break;
- }
- }
-
- /*Receive statistics */
- seq_printf(seq, "\nReceive statistics\n\n");
-
- seq_printf(seq, "Received bytes %Lu\n",
- (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
- seq_printf(seq, "Received packets %Lu\n",
- (unsigned long long) pPnmiStat->StatRxOkCts);
-#if 0
- if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC &&
- pAC->HWRevision < 12) {
- pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
- pPnmiStat->StatRxShortsCts;
- pPnmiStat->StatRxShortsCts = 0;
- }
-#endif
- if (dev->mtu > 1500)
- pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
- pPnmiStat->StatRxTooLongCts;
-
- seq_printf(seq, "Receive errors %Lu\n",
- (unsigned long long) pPnmiStruct->InErrorsCts);
- seq_printf(seq, "Receive dropped %Lu\n",
- (unsigned long long) pPnmiStruct->RxNoBufCts);
- seq_printf(seq, "Received multicast %Lu\n",
- (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
- seq_printf(seq, "Receive error types\n");
- seq_printf(seq, " length %Lu\n",
- (unsigned long long) pPnmiStat->StatRxRuntCts);
- seq_printf(seq, " buffer overflow %Lu\n",
- (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
- seq_printf(seq, " bad crc %Lu\n",
- (unsigned long long) pPnmiStat->StatRxFcsCts);
- seq_printf(seq, " framing %Lu\n",
- (unsigned long long) pPnmiStat->StatRxFramingCts);
- seq_printf(seq, " missed frames %Lu\n",
- (unsigned long long) pPnmiStat->StatRxMissedCts);
-
- if (dev->mtu > 1500)
- pPnmiStat->StatRxTooLongCts = 0;
-
- seq_printf(seq, " too long %Lu\n",
- (unsigned long long) pPnmiStat->StatRxTooLongCts);
- seq_printf(seq, " carrier extension %Lu\n",
- (unsigned long long) pPnmiStat->StatRxCextCts);
- seq_printf(seq, " too short %Lu\n",
- (unsigned long long) pPnmiStat->StatRxShortsCts);
- seq_printf(seq, " symbol %Lu\n",
- (unsigned long long) pPnmiStat->StatRxSymbolCts);
- seq_printf(seq, " LLC MAC size %Lu\n",
- (unsigned long long) pPnmiStat->StatRxIRLengthCts);
- seq_printf(seq, " carrier event %Lu\n",
- (unsigned long long) pPnmiStat->StatRxCarrierCts);
- seq_printf(seq, " jabber %Lu\n",
- (unsigned long long) pPnmiStat->StatRxJabberCts);
-
-
- /*Transmit statistics */
- seq_printf(seq, "\nTransmit statistics\n\n");
-
- seq_printf(seq, "Transmited bytes %Lu\n",
- (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
- seq_printf(seq, "Transmited packets %Lu\n",
- (unsigned long long) pPnmiStat->StatTxOkCts);
- seq_printf(seq, "Transmit errors %Lu\n",
- (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
- seq_printf(seq, "Transmit dropped %Lu\n",
- (unsigned long long) pPnmiStruct->TxNoBufCts);
- seq_printf(seq, "Transmit collisions %Lu\n",
- (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
- seq_printf(seq, "Transmit error types\n");
- seq_printf(seq, " excessive collision %ld\n",
- pAC->stats.tx_aborted_errors);
- seq_printf(seq, " carrier %Lu\n",
- (unsigned long long) pPnmiStat->StatTxCarrierCts);
- seq_printf(seq, " fifo underrun %Lu\n",
- (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
- seq_printf(seq, " heartbeat %Lu\n",
- (unsigned long long) pPnmiStat->StatTxCarrierCts);
- seq_printf(seq, " window %ld\n",
- pAC->stats.tx_window_errors);
-
- }
- }
- return 0;
-}
-
-/*****************************************************************************
- *
- * sk_proc_open - register the show function when proc is open'ed
- *
- * Description:
- * This function is called whenever a sk98lin proc file is queried.
- *
- * Returns: the return value of single_open()
- *
- */
-static int sk_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, sk_seq_show, PDE(inode)->data);
-}
-
-/*******************************************************************************
- *
- * End of file
- *
- ******************************************************************************/