···6565 */66666767#define DRV_NAME "emac"6868-#define DRV_VERSION "3.53"6868+#define DRV_VERSION "3.54"6969#define DRV_DESC "PPC 4xx OCP EMAC driver"70707171MODULE_DESCRIPTION(DRV_DESC);···158158#define PHY_POLL_LINK_ON HZ159159#define PHY_POLL_LINK_OFF (HZ / 5)160160161161+/* Graceful stop timeouts in us. 162162+ * We should allow up to 1 frame time (full-duplex, ignoring collisions) 163163+ */164164+#define STOP_TIMEOUT_10 1230 165165+#define STOP_TIMEOUT_100 124166166+#define STOP_TIMEOUT_1000 13167167+#define STOP_TIMEOUT_1000_JUMBO 73168168+161169/* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */162170static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {163171 "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum",···230222231223 r = in_be32(&p->mr0);232224 if (r & EMAC_MR0_TXE) {233233- int n = 300;225225+ int n = dev->stop_timeout;234226 out_be32(&p->mr0, r & ~EMAC_MR0_TXE);235235- while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n)227227+ while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) {228228+ udelay(1);236229 --n;230230+ } 237231 if (unlikely(!n))238232 emac_report_timeout_error(dev, "TX disable timeout");239233 }···258248 if (!(r & EMAC_MR0_RXE)) {259249 if (unlikely(!(r & EMAC_MR0_RXI))) {260250 /* Wait if previous async disable is still in progress */261261- int n = 100;262262- while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n)251251+ int n = dev->stop_timeout;252252+ while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {253253+ udelay(1);263254 --n;255255+ } 264256 if (unlikely(!n))265257 emac_report_timeout_error(dev,266258 "RX disable timeout");···285273286274 r = in_be32(&p->mr0);287275 if (r & EMAC_MR0_RXE) {288288- int n = 300;276276+ int n = dev->stop_timeout;289277 out_be32(&p->mr0, r & ~EMAC_MR0_RXE);290290- while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n)278278+ while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {279279+ udelay(1);291280 --n;281281+ } 292282 if (unlikely(!n))293283 emac_report_timeout_error(dev, "RX disable timeout");294284 }···409395 r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;410396 if (dev->phy.duplex == DUPLEX_FULL)411397 r |= EMAC_MR1_FDE;398398+ dev->stop_timeout = STOP_TIMEOUT_10;412399 switch (dev->phy.speed) {413400 case SPEED_1000:414401 if (emac_phy_gpcs(dev->phy.mode)) {···424409 r |= EMAC_MR1_MF_1000;425410 r |= EMAC_MR1_RFS_16K;426411 gige = 1;427427-428428- if (dev->ndev->mtu > ETH_DATA_LEN)412412+413413+ if (dev->ndev->mtu > ETH_DATA_LEN) {429414 r |= EMAC_MR1_JPSM;415415+ dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO;416416+ } else417417+ dev->stop_timeout = STOP_TIMEOUT_1000;430418 break;431419 case SPEED_100:432420 r |= EMAC_MR1_MF_100;421421+ dev->stop_timeout = STOP_TIMEOUT_100;433422 /* Fall through */434423 default:435424 r |= EMAC_MR1_RFS_4K;···20672048 dev->phy.duplex = DUPLEX_FULL;20682049 dev->phy.autoneg = AUTONEG_DISABLE;20692050 dev->phy.pause = dev->phy.asym_pause = 0;20512051+ dev->stop_timeout = STOP_TIMEOUT_100;20702052 init_timer(&dev->link_timer);20712053 dev->link_timer.function = emac_link_timer;20722054 dev->link_timer.data = (unsigned long)dev;
+2
drivers/net/ibm_emac/ibm_emac_core.h
···189189 struct timer_list link_timer;190190 int reset_failed;191191192192+ int stop_timeout; /* in us */193193+192194 struct ibm_emac_error_stats estats;193195 struct net_device_stats nstats;194196
+2-2
drivers/net/jazzsonic.c
···296296 }297297298298 jazz_sonic_device = platform_device_alloc(jazz_sonic_string, 0);299299- if (!jazz_sonnic_device)299299+ if (!jazz_sonic_device)300300 goto out_unregister;301301302302 if (platform_device_add(jazz_sonic_device)) {···307307 return 0;308308309309out_unregister:310310- driver_unregister(&jazz_sonic_driver);310310+ platform_driver_unregister(&jazz_sonic_driver);311311312312 return -ENOMEM;313313}
+5-25
drivers/net/mipsnet.h
···11-//22-// <COPYRIGHT CLASS="1B" YEAR="2005">33-// Unpublished work (c) MIPS Technologies, Inc. All rights reserved.44-// Unpublished rights reserved under the copyright laws of the U.S.A. and55-// other countries.66-//77-// PROPRIETARY / SECRET CONFIDENTIAL INFORMATION OF MIPS TECHNOLOGIES, INC.88-// FOR INTERNAL USE ONLY.99-//1010-// Under no circumstances (contract or otherwise) may this information be1111-// disclosed to, or copied, modified or used by anyone other than employees1212-// or contractors of MIPS Technologies having a need to know.1313-// </COPYRIGHT>1414-//1515-//++1616-// File: MIPS_Net.h1717-//1818-// Description:1919-// The definition of the emulated MIPSNET device's interface.2020-//2121-// Notes: This include file needs to work from a Linux device drivers.2222-//2323-//--2424-//2525-11+/*22+ * This file is subject to the terms and conditions of the GNU General Public33+ * License. See the file "COPYING" in the main directory of this archive44+ * for more details.55+ */266#ifndef __MIPSNET_H277#define __MIPSNET_H288
+11-21
drivers/net/pcmcia/fmvj18x_cs.c
···131131 u_short tx_queue_len;132132 cardtype_t cardtype;133133 u_short sent;134134- u_char mc_filter[8];135134} local_info_t;136135137137-#define MC_FILTERBREAK 8136136+#define MC_FILTERBREAK 64138137139138/*====================================================================*/140139/* ···10041005 for (i = 0; i < 6; i++) 10051006 outb(dev->dev_addr[i], ioaddr + NODE_ID + i);1006100710071007- /* Switch to bank 1 */10081008- if (lp->cardtype == MBH10302)10091009- outb(BANK_1, ioaddr + CONFIG_1);10101010- else10111011- outb(BANK_1U, ioaddr + CONFIG_1);10121012-10131013- /* set the multicast table to accept none. */10141014- for (i = 0; i < 8; i++) 10151015- outb(0x00, ioaddr + MAR_ADR + i);10081008+ /* (re)initialize the multicast table */10091009+ set_rx_mode(dev);1016101010171011 /* Switch to bank 2 (runtime mode) */10181012 if (lp->cardtype == MBH10302)···12561264static void set_rx_mode(struct net_device *dev)12571265{12581266 kio_addr_t ioaddr = dev->base_addr;12591259- struct local_info_t *lp = netdev_priv(dev);12601267 u_char mc_filter[8]; /* Multicast hash filter */12611268 u_long flags;12621269 int i;1263127012711271+ int saved_bank;12641272 int saved_config_0 = inb(ioaddr + CONFIG_0);1265127312661274 local_irq_save(flags); ···12981306 outb(2, ioaddr + RX_MODE); /* Use normal mode. */12991307 }1300130813011301- if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {13021302- int saved_bank = inb(ioaddr + CONFIG_1);13031303- /* Switch to bank 1 and set the multicast table. */13041304- outb(0xe4, ioaddr + CONFIG_1);13051305- for (i = 0; i < 8; i++)13061306- outb(mc_filter[i], ioaddr + MAR_ADR + i);13071307- memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));13081308- outb(saved_bank, ioaddr + CONFIG_1);13091309- }13091309+ /* Switch to bank 1 and set the multicast table. */13101310+ saved_bank = inb(ioaddr + CONFIG_1);13111311+ outb(0xe4, ioaddr + CONFIG_1);13121312+13131313+ for (i = 0; i < 8; i++)13141314+ outb(mc_filter[i], ioaddr + MAR_ADR + i);13151315+ outb(saved_bank, ioaddr + CONFIG_1);1310131613111317 outb(saved_config_0, ioaddr + CONFIG_0);13121318
···425425 TX_PORT TxPort[SK_MAX_MACS][2];426426 RX_PORT RxPort[SK_MAX_MACS];427427428428- unsigned int CsOfs1; /* for checksum calculation */429429- unsigned int CsOfs2; /* for checksum calculation */430430- SK_U32 CsOfs; /* for checksum calculation */431431-432428 SK_BOOL CheckQueue; /* check event queue soon */433429 SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */434430 DIM_INFO DynIrqModInfo; /* all data related to DIM */
-871
drivers/net/sk98lin/skcsum.c
···11-/******************************************************************************22- *33- * Name: skcsum.c44- * Project: GEnesis, PCI Gigabit Ethernet Adapter55- * Version: $Revision: 1.12 $66- * Date: $Date: 2003/08/20 13:55:53 $77- * Purpose: Store/verify Internet checksum in send/receive packets.88- *99- ******************************************************************************/1010-1111-/******************************************************************************1212- *1313- * (C)Copyright 1998-2003 SysKonnect GmbH.1414- *1515- * This program is free software; you can redistribute it and/or modify1616- * it under the terms of the GNU General Public License as published by1717- * the Free Software Foundation; either version 2 of the License, or1818- * (at your option) any later version.1919- *2020- * The information in this file is provided "AS IS" without warranty.2121- *2222- ******************************************************************************/2323-2424-#ifdef SK_USE_CSUM /* Check if CSUM is to be used. */2525-2626-#ifndef lint2727-static const char SysKonnectFileId[] =2828- "@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect.";2929-#endif /* !lint */3030-3131-/******************************************************************************3232- *3333- * Description:3434- *3535- * This is the "GEnesis" common module "CSUM".3636- *3737- * This module contains the code necessary to calculate, store, and verify the3838- * Internet Checksum of IP, TCP, and UDP frames.3939- *4040- * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"4141- * and is the code name of this SysKonnect project.4242- *4343- * Compilation Options:4444- *4545- * SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an4646- * empty module.4747- *4848- * SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id4949- * definitions. In this case, all SKCS_PROTO_xxx definitions must be made5050- * external.5151- *5252- * SKCS_OVERWRITE_STATUS - Define to overwrite the default return status5353- * definitions. In this case, all SKCS_STATUS_xxx definitions must be made5454- * external.5555- *5656- * Include File Hierarchy:5757- *5858- * "h/skdrv1st.h"5959- * "h/skcsum.h"6060- * "h/sktypes.h"6161- * "h/skqueue.h"6262- * "h/skdrv2nd.h"6363- *6464- ******************************************************************************/6565-6666-#include "h/skdrv1st.h"6767-#include "h/skcsum.h"6868-#include "h/skdrv2nd.h"6969-7070-/* defines ********************************************************************/7171-7272-/* The size of an Ethernet MAC header. */7373-#define SKCS_ETHERNET_MAC_HEADER_SIZE (6+6+2)7474-7575-/* The size of the used topology's MAC header. */7676-#define SKCS_MAC_HEADER_SIZE SKCS_ETHERNET_MAC_HEADER_SIZE7777-7878-/* The size of the IP header without any option fields. */7979-#define SKCS_IP_HEADER_SIZE 208080-8181-/*8282- * Field offsets within the IP header.8383- */8484-8585-/* "Internet Header Version" and "Length". */8686-#define SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH 08787-8888-/* "Total Length". */8989-#define SKCS_OFS_IP_TOTAL_LENGTH 29090-9191-/* "Flags" "Fragment Offset". */9292-#define SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET 69393-9494-/* "Next Level Protocol" identifier. */9595-#define SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL 99696-9797-/* Source IP address. */9898-#define SKCS_OFS_IP_SOURCE_ADDRESS 129999-100100-/* Destination IP address. */101101-#define SKCS_OFS_IP_DESTINATION_ADDRESS 16102102-103103-104104-/*105105- * Field offsets within the UDP header.106106- */107107-108108-/* UDP checksum. */109109-#define SKCS_OFS_UDP_CHECKSUM 6110110-111111-/* IP "Next Level Protocol" identifiers (see RFC 790). */112112-#define SKCS_PROTO_ID_TCP 6 /* Transport Control Protocol */113113-#define SKCS_PROTO_ID_UDP 17 /* User Datagram Protocol */114114-115115-/* IP "Don't Fragment" bit. */116116-#define SKCS_IP_DONT_FRAGMENT SKCS_HTON16(0x4000)117117-118118-/* Add a byte offset to a pointer. */119119-#define SKCS_IDX(pPtr, Ofs) ((void *) ((char *) (pPtr) + (Ofs)))120120-121121-/*122122- * Macros that convert host to network representation and vice versa, i.e.123123- * little/big endian conversion on little endian machines only.124124- */125125-#ifdef SK_LITTLE_ENDIAN126126-#define SKCS_HTON16(Val16) (((unsigned) (Val16) >> 8) | (((Val16) & 0xff) << 8))127127-#endif /* SK_LITTLE_ENDIAN */128128-#ifdef SK_BIG_ENDIAN129129-#define SKCS_HTON16(Val16) (Val16)130130-#endif /* SK_BIG_ENDIAN */131131-#define SKCS_NTOH16(Val16) SKCS_HTON16(Val16)132132-133133-/* typedefs *******************************************************************/134134-135135-/* function prototypes ********************************************************/136136-137137-/******************************************************************************138138- *139139- * SkCsGetSendInfo - get checksum information for a send packet140140- *141141- * Description:142142- * Get all checksum information necessary to send a TCP or UDP packet. The143143- * function checks the IP header passed to it. If the high-level protocol144144- * is either TCP or UDP the pseudo header checksum is calculated and145145- * returned.146146- *147147- * The function returns the total length of the IP header (including any148148- * IP option fields), which is the same as the start offset of the IP data149149- * which in turn is the start offset of the TCP or UDP header.150150- *151151- * The function also returns the TCP or UDP pseudo header checksum, which152152- * should be used as the start value for the hardware checksum calculation.153153- * (Note that any actual pseudo header checksum can never calculate to154154- * zero.)155155- *156156- * Note:157157- * There is a bug in the GENESIS ASIC which may lead to wrong checksums.158158- *159159- * Arguments:160160- * pAc - A pointer to the adapter context struct.161161- *162162- * pIpHeader - Pointer to IP header. Must be at least the IP header *not*163163- * including any option fields, i.e. at least 20 bytes.164164- *165165- * Note: This pointer will be used to address 8-, 16-, and 32-bit166166- * variables with the respective alignment offsets relative to the pointer.167167- * Thus, the pointer should point to a 32-bit aligned address. If the168168- * target system cannot address 32-bit variables on non 32-bit aligned169169- * addresses, then the pointer *must* point to a 32-bit aligned address.170170- *171171- * pPacketInfo - A pointer to the packet information structure for this172172- * packet. Before calling this SkCsGetSendInfo(), the following field must173173- * be initialized:174174- *175175- * ProtocolFlags - Initialize with any combination of176176- * SKCS_PROTO_XXX bit flags. SkCsGetSendInfo() will only work on177177- * the protocols specified here. Any protocol(s) not specified178178- * here will be ignored.179179- *180180- * Note: Only one checksum can be calculated in hardware. Thus, if181181- * SKCS_PROTO_IP is specified in the 'ProtocolFlags',182182- * SkCsGetSendInfo() must calculate the IP header checksum in183183- * software. It might be a better idea to have the calling184184- * protocol stack calculate the IP header checksum.185185- *186186- * Returns: N/A187187- * On return, the following fields in 'pPacketInfo' may or may not have188188- * been filled with information, depending on the protocol(s) found in the189189- * packet:190190- *191191- * ProtocolFlags - Returns the SKCS_PROTO_XXX bit flags of the protocol(s)192192- * that were both requested by the caller and actually found in the packet.193193- * Protocol(s) not specified by the caller and/or not found in the packet194194- * will have their respective SKCS_PROTO_XXX bit flags reset.195195- *196196- * Note: For IP fragments, TCP and UDP packet information is ignored.197197- *198198- * IpHeaderLength - The total length in bytes of the complete IP header199199- * including any option fields is returned here. This is the start offset200200- * of the IP data, i.e. the TCP or UDP header if present.201201- *202202- * IpHeaderChecksum - If IP has been specified in the 'ProtocolFlags', the203203- * 16-bit Internet Checksum of the IP header is returned here. This value204204- * is to be stored into the packet's 'IP Header Checksum' field.205205- *206206- * PseudoHeaderChecksum - If this is a TCP or UDP packet and if TCP or UDP207207- * has been specified in the 'ProtocolFlags', the 16-bit Internet Checksum208208- * of the TCP or UDP pseudo header is returned here.209209- */210210-void SkCsGetSendInfo(211211-SK_AC *pAc, /* Adapter context struct. */212212-void *pIpHeader, /* IP header. */213213-SKCS_PACKET_INFO *pPacketInfo, /* Packet information struct. */214214-int NetNumber) /* Net number */215215-{216216- /* Internet Header Version found in IP header. */217217- unsigned InternetHeaderVersion;218218-219219- /* Length of the IP header as found in IP header. */220220- unsigned IpHeaderLength;221221-222222- /* Bit field specifiying the desired/found protocols. */223223- unsigned ProtocolFlags;224224-225225- /* Next level protocol identifier found in IP header. */226226- unsigned NextLevelProtocol;227227-228228- /* Length of IP data portion. */229229- unsigned IpDataLength;230230-231231- /* TCP/UDP pseudo header checksum. */232232- unsigned long PseudoHeaderChecksum;233233-234234- /* Pointer to next level protocol statistics structure. */235235- SKCS_PROTO_STATS *NextLevelProtoStats;236236-237237- /* Temporary variable. */238238- unsigned Tmp;239239-240240- Tmp = *(SK_U8 *)241241- SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);242242-243243- /* Get the Internet Header Version (IHV). */244244- /* Note: The IHV is stored in the upper four bits. */245245-246246- InternetHeaderVersion = Tmp >> 4;247247-248248- /* Check the Internet Header Version. */249249- /* Note: We currently only support IP version 4. */250250-251251- if (InternetHeaderVersion != 4) { /* IPv4? */252252- SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,253253- ("Tx: Unknown Internet Header Version %u.\n",254254- InternetHeaderVersion));255255- pPacketInfo->ProtocolFlags = 0;256256- pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;257257- return;258258- }259259-260260- /* Get the IP header length (IHL). */261261- /*262262- * Note: The IHL is stored in the lower four bits as the number of263263- * 4-byte words.264264- */265265-266266- IpHeaderLength = (Tmp & 0xf) * 4;267267- pPacketInfo->IpHeaderLength = IpHeaderLength;268268-269269- /* Check the IP header length. */270270-271271- /* 04-Aug-1998 sw - Really check the IHL? Necessary? */272272-273273- if (IpHeaderLength < 5*4) {274274- SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,275275- ("Tx: Invalid IP Header Length %u.\n", IpHeaderLength));276276- pPacketInfo->ProtocolFlags = 0;277277- pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;278278- return;279279- }280280-281281- /* This is an IPv4 frame with a header of valid length. */282282-283283- pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxOkCts++;284284-285285- /* Check if we should calculate the IP header checksum. */286286-287287- ProtocolFlags = pPacketInfo->ProtocolFlags;288288-289289- if (ProtocolFlags & SKCS_PROTO_IP) {290290- pPacketInfo->IpHeaderChecksum =291291- SkCsCalculateChecksum(pIpHeader, IpHeaderLength);292292- }293293-294294- /* Get the next level protocol identifier. */295295-296296- NextLevelProtocol =297297- *(SK_U8 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);298298-299299- /*300300- * Check if this is a TCP or UDP frame and if we should calculate the301301- * TCP/UDP pseudo header checksum.302302- *303303- * Also clear all protocol bit flags of protocols not present in the304304- * frame.305305- */306306-307307- if ((ProtocolFlags & SKCS_PROTO_TCP) != 0 &&308308- NextLevelProtocol == SKCS_PROTO_ID_TCP) {309309- /* TCP/IP frame. */310310- ProtocolFlags &= SKCS_PROTO_TCP | SKCS_PROTO_IP;311311- NextLevelProtoStats =312312- &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];313313- }314314- else if ((ProtocolFlags & SKCS_PROTO_UDP) != 0 &&315315- NextLevelProtocol == SKCS_PROTO_ID_UDP) {316316- /* UDP/IP frame. */317317- ProtocolFlags &= SKCS_PROTO_UDP | SKCS_PROTO_IP;318318- NextLevelProtoStats =319319- &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];320320- }321321- else {322322- /*323323- * Either not a TCP or UDP frame and/or TCP/UDP processing not324324- * specified.325325- */326326- pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;327327- return;328328- }329329-330330- /* Check if this is an IP fragment. */331331-332332- /*333333- * Note: An IP fragment has a non-zero "Fragment Offset" field and/or334334- * the "More Fragments" bit set. Thus, if both the "Fragment Offset"335335- * and the "More Fragments" are zero, it is *not* a fragment. We can336336- * easily check both at the same time since they are in the same 16-bit337337- * word.338338- */339339-340340- if ((*(SK_U16 *)341341- SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &342342- ~SKCS_IP_DONT_FRAGMENT) != 0) {343343- /* IP fragment; ignore all other protocols. */344344- pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;345345- NextLevelProtoStats->TxUnableCts++;346346- return;347347- }348348-349349- /*350350- * Calculate the TCP/UDP pseudo header checksum.351351- */352352-353353- /* Get total length of IP header and data. */354354-355355- IpDataLength =356356- *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);357357-358358- /* Get length of IP data portion. */359359-360360- IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;361361-362362- /* Calculate the sum of all pseudo header fields (16-bit). */363363-364364- PseudoHeaderChecksum =365365- (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,366366- SKCS_OFS_IP_SOURCE_ADDRESS + 0) +367367- (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,368368- SKCS_OFS_IP_SOURCE_ADDRESS + 2) +369369- (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,370370- SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +371371- (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,372372- SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +373373- (unsigned long) SKCS_HTON16(NextLevelProtocol) +374374- (unsigned long) SKCS_HTON16(IpDataLength);375375-376376- /* Add-in any carries. */377377-378378- SKCS_OC_ADD(PseudoHeaderChecksum, PseudoHeaderChecksum, 0);379379-380380- /* Add-in any new carry. */381381-382382- SKCS_OC_ADD(pPacketInfo->PseudoHeaderChecksum, PseudoHeaderChecksum, 0);383383-384384- pPacketInfo->ProtocolFlags = ProtocolFlags;385385- NextLevelProtoStats->TxOkCts++; /* Success. */386386-} /* SkCsGetSendInfo */387387-388388-389389-/******************************************************************************390390- *391391- * SkCsGetReceiveInfo - verify checksum information for a received packet392392- *393393- * Description:394394- * Verify a received frame's checksum. The function returns a status code395395- * reflecting the result of the verification.396396- *397397- * Note:398398- * Before calling this function you have to verify that the frame is399399- * not padded and Checksum1 and Checksum2 are bigger than 1.400400- *401401- * Arguments:402402- * pAc - Pointer to adapter context struct.403403- *404404- * pIpHeader - Pointer to IP header. Must be at least the length in bytes405405- * of the received IP header including any option fields. For UDP packets,406406- * 8 additional bytes are needed to access the UDP checksum.407407- *408408- * Note: The actual length of the IP header is stored in the lower four409409- * bits of the first octet of the IP header as the number of 4-byte words,410410- * so it must be multiplied by four to get the length in bytes. Thus, the411411- * maximum IP header length is 15 * 4 = 60 bytes.412412- *413413- * Checksum1 - The first 16-bit Internet Checksum calculated by the414414- * hardware starting at the offset returned by SkCsSetReceiveFlags().415415- *416416- * Checksum2 - The second 16-bit Internet Checksum calculated by the417417- * hardware starting at the offset returned by SkCsSetReceiveFlags().418418- *419419- * Returns:420420- * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.421421- * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.422422- * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.423423- * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame424424- * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).425425- * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).426426- * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).427427- * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).428428- * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.429429- * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.430430- * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.431431- *432432- * Note: If SKCS_OVERWRITE_STATUS is defined, the SKCS_STATUS_XXX values433433- * returned here can be defined in some header file by the module using CSUM.434434- * In this way, the calling module can assign return values for its own needs,435435- * e.g. by assigning bit flags to the individual protocols.436436- */437437-SKCS_STATUS SkCsGetReceiveInfo(438438-SK_AC *pAc, /* Adapter context struct. */439439-void *pIpHeader, /* IP header. */440440-unsigned Checksum1, /* Hardware checksum 1. */441441-unsigned Checksum2, /* Hardware checksum 2. */442442-int NetNumber) /* Net number */443443-{444444- /* Internet Header Version found in IP header. */445445- unsigned InternetHeaderVersion;446446-447447- /* Length of the IP header as found in IP header. */448448- unsigned IpHeaderLength;449449-450450- /* Length of IP data portion. */451451- unsigned IpDataLength;452452-453453- /* IP header checksum. */454454- unsigned IpHeaderChecksum;455455-456456- /* IP header options checksum, if any. */457457- unsigned IpOptionsChecksum;458458-459459- /* IP data checksum, i.e. TCP/UDP checksum. */460460- unsigned IpDataChecksum;461461-462462- /* Next level protocol identifier found in IP header. */463463- unsigned NextLevelProtocol;464464-465465- /* The checksum of the "next level protocol", i.e. TCP or UDP. */466466- unsigned long NextLevelProtocolChecksum;467467-468468- /* Pointer to next level protocol statistics structure. */469469- SKCS_PROTO_STATS *NextLevelProtoStats;470470-471471- /* Temporary variable. */472472- unsigned Tmp;473473-474474- Tmp = *(SK_U8 *)475475- SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);476476-477477- /* Get the Internet Header Version (IHV). */478478- /* Note: The IHV is stored in the upper four bits. */479479-480480- InternetHeaderVersion = Tmp >> 4;481481-482482- /* Check the Internet Header Version. */483483- /* Note: We currently only support IP version 4. */484484-485485- if (InternetHeaderVersion != 4) { /* IPv4? */486486- SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,487487- ("Rx: Unknown Internet Header Version %u.\n",488488- InternetHeaderVersion));489489- pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxUnableCts++;490490- return (SKCS_STATUS_UNKNOWN_IP_VERSION);491491- }492492-493493- /* Get the IP header length (IHL). */494494- /*495495- * Note: The IHL is stored in the lower four bits as the number of496496- * 4-byte words.497497- */498498-499499- IpHeaderLength = (Tmp & 0xf) * 4;500500-501501- /* Check the IP header length. */502502-503503- /* 04-Aug-1998 sw - Really check the IHL? Necessary? */504504-505505- if (IpHeaderLength < 5*4) {506506- SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,507507- ("Rx: Invalid IP Header Length %u.\n", IpHeaderLength));508508- pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;509509- return (SKCS_STATUS_IP_CSUM_ERROR);510510- }511511-512512- /* This is an IPv4 frame with a header of valid length. */513513-514514- /* Get the IP header and data checksum. */515515-516516- IpDataChecksum = Checksum2;517517-518518- /*519519- * The IP header checksum is calculated as follows:520520- *521521- * IpHeaderChecksum = Checksum1 - Checksum2522522- */523523-524524- SKCS_OC_SUB(IpHeaderChecksum, Checksum1, Checksum2);525525-526526- /* Check if any IP header options. */527527-528528- if (IpHeaderLength > SKCS_IP_HEADER_SIZE) {529529-530530- /* Get the IP options checksum. */531531-532532- IpOptionsChecksum = SkCsCalculateChecksum(533533- SKCS_IDX(pIpHeader, SKCS_IP_HEADER_SIZE),534534- IpHeaderLength - SKCS_IP_HEADER_SIZE);535535-536536- /* Adjust the IP header and IP data checksums. */537537-538538- SKCS_OC_ADD(IpHeaderChecksum, IpHeaderChecksum, IpOptionsChecksum);539539-540540- SKCS_OC_SUB(IpDataChecksum, IpDataChecksum, IpOptionsChecksum);541541- }542542-543543- /*544544- * Check if the IP header checksum is ok.545545- *546546- * NOTE: We must check the IP header checksum even if the caller just wants547547- * us to check upper-layer checksums, because we cannot do any further548548- * processing of the packet without a valid IP checksum.549549- */550550-551551- /* Get the next level protocol identifier. */552552-553553- NextLevelProtocol = *(SK_U8 *)554554- SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);555555-556556- if (IpHeaderChecksum != 0xffff) {557557- pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;558558- /* the NDIS tester wants to know the upper level protocol too */559559- if (NextLevelProtocol == SKCS_PROTO_ID_TCP) {560560- return(SKCS_STATUS_IP_CSUM_ERROR_TCP);561561- }562562- else if (NextLevelProtocol == SKCS_PROTO_ID_UDP) {563563- return(SKCS_STATUS_IP_CSUM_ERROR_UDP);564564- }565565- return (SKCS_STATUS_IP_CSUM_ERROR);566566- }567567-568568- /*569569- * Check if this is a TCP or UDP frame and if we should calculate the570570- * TCP/UDP pseudo header checksum.571571- *572572- * Also clear all protocol bit flags of protocols not present in the573573- * frame.574574- */575575-576576- if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_TCP) != 0 &&577577- NextLevelProtocol == SKCS_PROTO_ID_TCP) {578578- /* TCP/IP frame. */579579- NextLevelProtoStats =580580- &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];581581- }582582- else if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_UDP) != 0 &&583583- NextLevelProtocol == SKCS_PROTO_ID_UDP) {584584- /* UDP/IP frame. */585585- NextLevelProtoStats =586586- &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];587587- }588588- else {589589- /*590590- * Either not a TCP or UDP frame and/or TCP/UDP processing not591591- * specified.592592- */593593- return (SKCS_STATUS_IP_CSUM_OK);594594- }595595-596596- /* Check if this is an IP fragment. */597597-598598- /*599599- * Note: An IP fragment has a non-zero "Fragment Offset" field and/or600600- * the "More Fragments" bit set. Thus, if both the "Fragment Offset"601601- * and the "More Fragments" are zero, it is *not* a fragment. We can602602- * easily check both at the same time since they are in the same 16-bit603603- * word.604604- */605605-606606- if ((*(SK_U16 *)607607- SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &608608- ~SKCS_IP_DONT_FRAGMENT) != 0) {609609- /* IP fragment; ignore all other protocols. */610610- NextLevelProtoStats->RxUnableCts++;611611- return (SKCS_STATUS_IP_FRAGMENT);612612- }613613-614614- /*615615- * 08-May-2000 ra616616- *617617- * From RFC 768 (UDP)618618- * If the computed checksum is zero, it is transmitted as all ones (the619619- * equivalent in one's complement arithmetic). An all zero transmitted620620- * checksum value means that the transmitter generated no checksum (for621621- * debugging or for higher level protocols that don't care).622622- */623623-624624- if (NextLevelProtocol == SKCS_PROTO_ID_UDP &&625625- *(SK_U16*)SKCS_IDX(pIpHeader, IpHeaderLength + 6) == 0x0000) {626626-627627- NextLevelProtoStats->RxOkCts++;628628-629629- return (SKCS_STATUS_IP_CSUM_OK_NO_UDP);630630- }631631-632632- /*633633- * Calculate the TCP/UDP checksum.634634- */635635-636636- /* Get total length of IP header and data. */637637-638638- IpDataLength =639639- *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);640640-641641- /* Get length of IP data portion. */642642-643643- IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;644644-645645- NextLevelProtocolChecksum =646646-647647- /* Calculate the pseudo header checksum. */648648-649649- (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,650650- SKCS_OFS_IP_SOURCE_ADDRESS + 0) +651651- (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,652652- SKCS_OFS_IP_SOURCE_ADDRESS + 2) +653653- (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,654654- SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +655655- (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,656656- SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +657657- (unsigned long) SKCS_HTON16(NextLevelProtocol) +658658- (unsigned long) SKCS_HTON16(IpDataLength) +659659-660660- /* Add the TCP/UDP header checksum. */661661-662662- (unsigned long) IpDataChecksum;663663-664664- /* Add-in any carries. */665665-666666- SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);667667-668668- /* Add-in any new carry. */669669-670670- SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);671671-672672- /* Check if the TCP/UDP checksum is ok. */673673-674674- if ((unsigned) NextLevelProtocolChecksum == 0xffff) {675675-676676- /* TCP/UDP checksum ok. */677677-678678- NextLevelProtoStats->RxOkCts++;679679-680680- return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?681681- SKCS_STATUS_TCP_CSUM_OK : SKCS_STATUS_UDP_CSUM_OK);682682- }683683-684684- /* TCP/UDP checksum error. */685685-686686- NextLevelProtoStats->RxErrCts++;687687-688688- return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?689689- SKCS_STATUS_TCP_CSUM_ERROR : SKCS_STATUS_UDP_CSUM_ERROR);690690-} /* SkCsGetReceiveInfo */691691-692692-693693-/******************************************************************************694694- *695695- * SkCsSetReceiveFlags - set checksum receive flags696696- *697697- * Description:698698- * Use this function to set the various receive flags. According to the699699- * protocol flags set by the caller, the start offsets within received700700- * packets of the two hardware checksums are returned. These offsets must701701- * be stored in all receive descriptors.702702- *703703- * Arguments:704704- * pAc - Pointer to adapter context struct.705705- *706706- * ReceiveFlags - Any combination of SK_PROTO_XXX flags of the protocols707707- * for which the caller wants checksum information on received frames.708708- *709709- * pChecksum1Offset - The start offset of the first receive descriptor710710- * hardware checksum to be calculated for received frames is returned711711- * here.712712- *713713- * pChecksum2Offset - The start offset of the second receive descriptor714714- * hardware checksum to be calculated for received frames is returned715715- * here.716716- *717717- * Returns: N/A718718- * Returns the two hardware checksum start offsets.719719- */720720-void SkCsSetReceiveFlags(721721-SK_AC *pAc, /* Adapter context struct. */722722-unsigned ReceiveFlags, /* New receive flags. */723723-unsigned *pChecksum1Offset, /* Offset for hardware checksum 1. */724724-unsigned *pChecksum2Offset, /* Offset for hardware checksum 2. */725725-int NetNumber)726726-{727727- /* Save the receive flags. */728728-729729- pAc->Csum.ReceiveFlags[NetNumber] = ReceiveFlags;730730-731731- /* First checksum start offset is the IP header. */732732- *pChecksum1Offset = SKCS_MAC_HEADER_SIZE;733733-734734- /*735735- * Second checksum start offset is the IP data. Note that this may vary736736- * if there are any IP header options in the actual packet.737737- */738738- *pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;739739-} /* SkCsSetReceiveFlags */740740-741741-#ifndef SK_CS_CALCULATE_CHECKSUM742742-743743-/******************************************************************************744744- *745745- * SkCsCalculateChecksum - calculate checksum for specified data746746- *747747- * Description:748748- * Calculate and return the 16-bit Internet Checksum for the specified749749- * data.750750- *751751- * Arguments:752752- * pData - Pointer to data for which the checksum shall be calculated.753753- * Note: The pointer should be aligned on a 16-bit boundary.754754- *755755- * Length - Length in bytes of data to checksum.756756- *757757- * Returns:758758- * The 16-bit Internet Checksum for the specified data.759759- *760760- * Note: The checksum is calculated in the machine's natural byte order,761761- * i.e. little vs. big endian. Thus, the resulting checksum is different762762- * for the same input data on little and big endian machines.763763- *764764- * However, when written back to the network packet, the byte order is765765- * always in correct network order.766766- */767767-unsigned SkCsCalculateChecksum(768768-void *pData, /* Data to checksum. */769769-unsigned Length) /* Length of data. */770770-{771771- SK_U16 *pU16; /* Pointer to the data as 16-bit words. */772772- unsigned long Checksum; /* Checksum; must be at least 32 bits. */773773-774774- /* Sum up all 16-bit words. */775775-776776- pU16 = (SK_U16 *) pData;777777- for (Checksum = 0; Length > 1; Length -= 2) {778778- Checksum += *pU16++;779779- }780780-781781- /* If this is an odd number of bytes, add-in the last byte. */782782-783783- if (Length > 0) {784784-#ifdef SK_BIG_ENDIAN785785- /* Add the last byte as the high byte. */786786- Checksum += ((unsigned) *(SK_U8 *) pU16) << 8;787787-#else /* !SK_BIG_ENDIAN */788788- /* Add the last byte as the low byte. */789789- Checksum += *(SK_U8 *) pU16;790790-#endif /* !SK_BIG_ENDIAN */791791- }792792-793793- /* Add-in any carries. */794794-795795- SKCS_OC_ADD(Checksum, Checksum, 0);796796-797797- /* Add-in any new carry. */798798-799799- SKCS_OC_ADD(Checksum, Checksum, 0);800800-801801- /* Note: All bits beyond the 16-bit limit are now zero. */802802-803803- return ((unsigned) Checksum);804804-} /* SkCsCalculateChecksum */805805-806806-#endif /* SK_CS_CALCULATE_CHECKSUM */807807-808808-/******************************************************************************809809- *810810- * SkCsEvent - the CSUM event dispatcher811811- *812812- * Description:813813- * This is the event handler for the CSUM module.814814- *815815- * Arguments:816816- * pAc - Pointer to adapter context.817817- *818818- * Ioc - I/O context.819819- *820820- * Event - Event id.821821- *822822- * Param - Event dependent parameter.823823- *824824- * Returns:825825- * The 16-bit Internet Checksum for the specified data.826826- *827827- * Note: The checksum is calculated in the machine's natural byte order,828828- * i.e. little vs. big endian. Thus, the resulting checksum is different829829- * for the same input data on little and big endian machines.830830- *831831- * However, when written back to the network packet, the byte order is832832- * always in correct network order.833833- */834834-int SkCsEvent(835835-SK_AC *pAc, /* Pointer to adapter context. */836836-SK_IOC Ioc, /* I/O context. */837837-SK_U32 Event, /* Event id. */838838-SK_EVPARA Param) /* Event dependent parameter. */839839-{840840- int ProtoIndex;841841- int NetNumber;842842-843843- switch (Event) {844844- /*845845- * Clear protocol statistics.846846- *847847- * Param - Protocol index, or -1 for all protocols.848848- * - Net number.849849- */850850- case SK_CSUM_EVENT_CLEAR_PROTO_STATS:851851-852852- ProtoIndex = (int)Param.Para32[1];853853- NetNumber = (int)Param.Para32[0];854854- if (ProtoIndex < 0) { /* Clear for all protocols. */855855- if (NetNumber >= 0) {856856- SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][0], 0,857857- sizeof(pAc->Csum.ProtoStats[NetNumber]));858858- }859859- }860860- else { /* Clear for individual protocol. */861861- SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0,862862- sizeof(pAc->Csum.ProtoStats[NetNumber][ProtoIndex]));863863- }864864- break;865865- default:866866- break;867867- }868868- return (0); /* Success. */869869-} /* SkCsEvent */870870-871871-#endif /* SK_USE_CSUM */