diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-12-01 15:49:37 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-12-01 15:49:37 -0800 |
commit | f327220b1494aa23fd4206ac4778b8aa449a3351 (patch) | |
tree | b463d2541db1638c7cb8b9ff10a9238fc8a47000 | |
parent | 31b3c31bca3b4df975631323d6ee6f49f43f4956 (diff) | |
parent | ea182d4aefa3a27847d890b1592a608d1180aa45 (diff) |
Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
-rw-r--r-- | drivers/net/b44.c | 13 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 14 | ||||
-rw-r--r-- | drivers/net/ibm_emac/ibm_emac_core.c | 38 | ||||
-rw-r--r-- | drivers/net/ibm_emac/ibm_emac_core.h | 2 | ||||
-rw-r--r-- | drivers/net/jazzsonic.c | 4 | ||||
-rw-r--r-- | drivers/net/mipsnet.h | 30 | ||||
-rw-r--r-- | drivers/net/pcmcia/fmvj18x_cs.c | 32 | ||||
-rw-r--r-- | drivers/net/sk98lin/Makefile | 5 | ||||
-rw-r--r-- | drivers/net/sk98lin/h/skdrv2nd.h | 4 | ||||
-rw-r--r-- | drivers/net/sk98lin/skcsum.c | 871 | ||||
-rw-r--r-- | drivers/net/sk98lin/skethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/sk98lin/skge.c | 174 | ||||
-rw-r--r-- | drivers/net/skge.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/airo.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco.c | 3 |
15 files changed, 108 insertions, 1092 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index c53848f787e..7aa49b974dc 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 @@ static int b44_open(struct net_device *dev) add_timer(&bp->timer); b44_enable_ints(bp); + netif_start_queue(dev); out: return err; } @@ -1837,12 +1838,15 @@ static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { 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 @@ static int b44_resume(struct pci_dev *pdev) 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 8b207f0e139..e0ae248b431 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2621,19 +2621,7 @@ e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb) 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/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index eb7d6947871..1da8a66f91e 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -65,7 +65,7 @@ */ #define DRV_NAME "emac" -#define DRV_VERSION "3.53" +#define DRV_VERSION "3.54" #define DRV_DESC "PPC 4xx OCP EMAC driver" MODULE_DESCRIPTION(DRV_DESC); @@ -158,6 +158,14 @@ static inline void emac_report_timeout_error(struct ocp_enet_private *dev, #define PHY_POLL_LINK_ON HZ #define PHY_POLL_LINK_OFF (HZ / 5) +/* Graceful stop timeouts in us. + * We should allow up to 1 frame time (full-duplex, ignoring collisions) + */ +#define STOP_TIMEOUT_10 1230 +#define STOP_TIMEOUT_100 124 +#define STOP_TIMEOUT_1000 13 +#define STOP_TIMEOUT_1000_JUMBO 73 + /* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */ static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = { "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum", @@ -222,10 +230,12 @@ static void emac_tx_disable(struct ocp_enet_private *dev) r = in_be32(&p->mr0); if (r & EMAC_MR0_TXE) { - int n = 300; + int n = dev->stop_timeout; out_be32(&p->mr0, r & ~EMAC_MR0_TXE); - while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) + while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) { + udelay(1); --n; + } if (unlikely(!n)) emac_report_timeout_error(dev, "TX disable timeout"); } @@ -248,9 +258,11 @@ static void emac_rx_enable(struct ocp_enet_private *dev) if (!(r & EMAC_MR0_RXE)) { if (unlikely(!(r & EMAC_MR0_RXI))) { /* Wait if previous async disable is still in progress */ - int n = 100; - while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) + int n = dev->stop_timeout; + while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) { + udelay(1); --n; + } if (unlikely(!n)) emac_report_timeout_error(dev, "RX disable timeout"); @@ -273,10 +285,12 @@ static void emac_rx_disable(struct ocp_enet_private *dev) r = in_be32(&p->mr0); if (r & EMAC_MR0_RXE) { - int n = 300; + int n = dev->stop_timeout; out_be32(&p->mr0, r & ~EMAC_MR0_RXE); - while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) + while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) { + udelay(1); --n; + } if (unlikely(!n)) emac_report_timeout_error(dev, "RX disable timeout"); } @@ -395,6 +409,7 @@ static int emac_configure(struct ocp_enet_private *dev) r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST; if (dev->phy.duplex == DUPLEX_FULL) r |= EMAC_MR1_FDE; + dev->stop_timeout = STOP_TIMEOUT_10; switch (dev->phy.speed) { case SPEED_1000: if (emac_phy_gpcs(dev->phy.mode)) { @@ -409,12 +424,16 @@ static int emac_configure(struct ocp_enet_private *dev) r |= EMAC_MR1_MF_1000; r |= EMAC_MR1_RFS_16K; gige = 1; - - if (dev->ndev->mtu > ETH_DATA_LEN) + + if (dev->ndev->mtu > ETH_DATA_LEN) { r |= EMAC_MR1_JPSM; + dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO; + } else + dev->stop_timeout = STOP_TIMEOUT_1000; break; case SPEED_100: r |= EMAC_MR1_MF_100; + dev->stop_timeout = STOP_TIMEOUT_100; /* Fall through */ default: r |= EMAC_MR1_RFS_4K; @@ -2048,6 +2067,7 @@ static int __init emac_probe(struct ocp_device *ocpdev) dev->phy.duplex = DUPLEX_FULL; dev->phy.autoneg = AUTONEG_DISABLE; dev->phy.pause = dev->phy.asym_pause = 0; + dev->stop_timeout = STOP_TIMEOUT_100; init_timer(&dev->link_timer); dev->link_timer.function = emac_link_timer; dev->link_timer.data = (unsigned long)dev; diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h index e9b44d030ac..911abbaf471 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.h +++ b/drivers/net/ibm_emac/ibm_emac_core.h @@ -189,6 +189,8 @@ struct ocp_enet_private { struct timer_list link_timer; int reset_failed; + int stop_timeout; /* in us */ + struct ibm_emac_error_stats estats; struct net_device_stats nstats; diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index b039bd89ceb..272d331d29c 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -296,7 +296,7 @@ static int __init jazz_sonic_init_module(void) } jazz_sonic_device = platform_device_alloc(jazz_sonic_string, 0); - if (!jazz_sonnic_device) + if (!jazz_sonic_device) goto out_unregister; if (platform_device_add(jazz_sonic_device)) { @@ -307,7 +307,7 @@ static int __init jazz_sonic_init_module(void) return 0; out_unregister: - driver_unregister(&jazz_sonic_driver); + platform_driver_unregister(&jazz_sonic_driver); return -ENOMEM; } diff --git a/drivers/net/mipsnet.h b/drivers/net/mipsnet.h index 878535953cb..026c732024c 100644 --- a/drivers/net/mipsnet.h +++ b/drivers/net/mipsnet.h @@ -1,28 +1,8 @@ -// -// <COPYRIGHT CLASS="1B" YEAR="2005"> -// Unpublished work (c) MIPS Technologies, Inc. All rights reserved. -// Unpublished rights reserved under the copyright laws of the U.S.A. and -// other countries. -// -// PROPRIETARY / SECRET CONFIDENTIAL INFORMATION OF MIPS TECHNOLOGIES, INC. -// FOR INTERNAL USE ONLY. -// -// Under no circumstances (contract or otherwise) may this information be -// disclosed to, or copied, modified or used by anyone other than employees -// or contractors of MIPS Technologies having a need to know. -// </COPYRIGHT> -// -//++ -// File: MIPS_Net.h -// -// Description: -// The definition of the emulated MIPSNET device's interface. -// -// Notes: This include file needs to work from a Linux device drivers. -// -//-- -// - +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ #ifndef __MIPSNET_H #define __MIPSNET_H diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 384a736a0d2..356f5090922 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -131,10 +131,9 @@ typedef struct local_info_t { u_short tx_queue_len; cardtype_t cardtype; u_short sent; - u_char mc_filter[8]; } local_info_t; -#define MC_FILTERBREAK 8 +#define MC_FILTERBREAK 64 /*====================================================================*/ /* @@ -1005,15 +1004,8 @@ static void fjn_reset(struct net_device *dev) for (i = 0; i < 6; i++) outb(dev->dev_addr[i], ioaddr + NODE_ID + i); - /* Switch to bank 1 */ - if (lp->cardtype == MBH10302) - outb(BANK_1, ioaddr + CONFIG_1); - else - outb(BANK_1U, ioaddr + CONFIG_1); - - /* set the multicast table to accept none. */ - for (i = 0; i < 8; i++) - outb(0x00, ioaddr + MAR_ADR + i); + /* (re)initialize the multicast table */ + set_rx_mode(dev); /* Switch to bank 2 (runtime mode) */ if (lp->cardtype == MBH10302) @@ -1264,11 +1256,11 @@ static struct net_device_stats *fjn_get_stats(struct net_device *dev) static void set_rx_mode(struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; - struct local_info_t *lp = netdev_priv(dev); u_char mc_filter[8]; /* Multicast hash filter */ u_long flags; int i; + int saved_bank; int saved_config_0 = inb(ioaddr + CONFIG_0); local_irq_save(flags); @@ -1306,15 +1298,13 @@ static void set_rx_mode(struct net_device *dev) outb(2, ioaddr + RX_MODE); /* Use normal mode. */ } - if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) { - int saved_bank = inb(ioaddr + CONFIG_1); - /* Switch to bank 1 and set the multicast table. */ - outb(0xe4, ioaddr + CONFIG_1); - for (i = 0; i < 8; i++) - outb(mc_filter[i], ioaddr + MAR_ADR + i); - memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter)); - outb(saved_bank, ioaddr + CONFIG_1); - } + /* Switch to bank 1 and set the multicast table. */ + saved_bank = inb(ioaddr + CONFIG_1); + outb(0xe4, ioaddr + CONFIG_1); + + for (i = 0; i < 8; i++) + outb(mc_filter[i], ioaddr + MAR_ADR + i); + outb(saved_bank, ioaddr + CONFIG_1); outb(saved_config_0, ioaddr + CONFIG_0); diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile index 6783039ffb7..7653d6e33aa 100644 --- a/drivers/net/sk98lin/Makefile +++ b/drivers/net/sk98lin/Makefile @@ -27,8 +27,7 @@ sk98lin-objs := \ sktimer.o \ skvpd.o \ skxmac2.o \ - skproc.o \ - skcsum.o + skproc.o # DBGDEF = \ # -DDEBUG @@ -77,7 +76,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..2dc5728e3ef 100644 --- a/drivers/net/sk98lin/h/skdrv2nd.h +++ b/drivers/net/sk98lin/h/skdrv2nd.h @@ -425,10 +425,6 @@ 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 */ 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/skethtool.c b/drivers/net/sk98lin/skethtool.c index fb639959292..b71769ae460 100644 --- a/drivers/net/sk98lin/skethtool.c +++ b/drivers/net/sk98lin/skethtool.c @@ -549,4 +549,6 @@ 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, }; diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c index b18c92cb629..00c5d7f04c6 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" @@ -601,11 +601,6 @@ SK_BOOL DualNet; 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; @@ -823,7 +818,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; + pDescr->TcpSumStarts = 0; /* advance one step */ pPrevDescr = pDescr; @@ -1505,8 +1500,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 +1572,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 +1583,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 +1648,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 +1674,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 +1691,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 +1739,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 +1997,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 +2009,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 +2137,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 +2166,16 @@ 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; + 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 @@ -4946,7 +4853,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, 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; } @@ -4982,7 +4889,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, /* 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; } @@ -5001,8 +4908,8 @@ 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); + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); SkGeProcCreate(dev); @@ -5048,13 +4955,14 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, #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"); diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 596c93b12da..716467879b9 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -2300,14 +2300,12 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) td->dma_hi = map >> 32; if (skb->ip_summed == CHECKSUM_HW) { - const struct iphdr *ip - = (const struct iphdr *) (skb->data + ETH_HLEN); int offset = skb->h.raw - skb->data; /* This seems backwards, but it is what the sk98lin * does. Looks like hardware is wrong? */ - if (ip->protocol == IPPROTO_UDP + if (skb->h.ipiph->protocol == IPPROTO_UDP && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON) control = BMU_TCP_CHECK; else diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 340ab4ee4b6..7a92b1cbd6a 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2755,8 +2755,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, SET_NETDEV_DEV(dev, dmdev); - if (test_bit(FLAG_MPI,&ai->flags)) - reset_card (dev, 1); + reset_card (dev, 1); + msleep(400); rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev ); if (rc) { diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 488ab06fb79..6fd0bf73683 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -3512,9 +3512,8 @@ static int orinoco_ioctl_setpower(struct net_device *dev, break; default: err = -EINVAL; - } - if (err) goto out; + } if (prq->flags & IW_POWER_TIMEOUT) { priv->pm_on = 1; |