/*++ Copyright (c) 1998-1999 Microsoft Corporation Module Name: priv.h Abstract: Private structure definitions and function templates for the 1394 ARP module. Author: Revision History: Who When What -------- -------- ---- josephj 11-17-98 created --*/ #define ARP1394_SYMBOLIC_NAME L"\\DosDevices\\ARP1394" #define ARP1394_DEVICE_NAME L"\\Device\\ARP1394" #define ARP1394_UL_NAME L"ARP1394" #define ARP1394_LL_NAME L"TCPIP_ARP1394" #define ARP1394_NDIS_MAJOR_VERSION 5 #define ARP1394_NDIS_MINOR_VERSION 0 // The physical address length, as reported to IP in the following places: // // IFEntry.if_physaddr (on WIN98, IFEntry.if_physaddr is truncated to 6 bytes) // LLIPBindInfo.lip_addr // IPNetToMediaEntry.inme_physaddr // // Note that may be (and in fact currently is) less then the actual length of // the actual IEEE1394 FIFO physical-address length. // #define ARP1394_IP_PHYSADDR_LEN 6 // TODO: make 8 // The levels of the various types of locks // enum { LOCKLEVEL_GLOBAL=1, // Must start > 0. LOCKLEVEL_ADAPTER, LOCKLEVEL_IF_SEND }; #define ARP1394_GLOBALS_SIG 'G31A' // TODO: read this from configuration. Set default based on the ip/1394 standard. // #define ARP1394_ADAPTER_MTU 1520 #define ARP1394_MAX_PROTOCOL_PKTS 1000 #define ARP1394_MAX_PROTOCOL_PACKET_SIZE 1600 // We need to forward between ICS. #define ARP1394_ADDRESS_RESOLUTION_TIMEOUT 1000 // Ms #define ARP1394_MAX_ETHERNET_PKTS 4 // Delay between polling for connect status. // #define ARP1394_WAIT_FOR_CONNECT_STATUS_TIMEOUT 5000 // // Packet flags for packets allocated by us. // Go into protocol-context (pc_common.pc_flags) of the packet. // #define ARP1394_PACKET_FLAGS_ARP 0 #define ARP1394_PACKET_FLAGS_ICS 1 #define ARP1394_PACKET_FLAGS_MCAP 2 #define ARP1394_PACKET_FLAGS_DBGCOPY 3 #define ARP1394_PACKET_FLAGS_IOCTL 4 // // Pre allocation constants to avoid low memory condition // #define ARP1394_BACKUP_TASKS 4 // Forward references // typedef struct _ARP1394_INTERFACE ARP1394_INTERFACE; typedef struct _ARPCB_LOCAL_IP ARPCB_LOCAL_IP; typedef struct _ARPCB_REMOTE_IP ARPCB_REMOTE_IP; typedef struct _ARPCB_REMOTE_ETH ARPCB_REMOTE_ETH; typedef struct _ARPCB_DEST ARPCB_DEST, *PARPCB_DEST; typedef IPAddr IP_ADDRESS, *PIP_ADDRESS; typedef IPMask IP_MASK, *PIP_MASK; typedef int MYBOOL; // Like BOOL typedef struct _ARP1394_GLOBALS { RM_OBJECT_HEADER Hdr; RM_LOCK Lock; // Driver global state // struct { // Handle to Driver Object for ARP1394 // PVOID pDriverObject; // Handle to the single device object representing this driver. // PVOID pDeviceObject; } driver; // Global NDIS State // struct { // NDIS' protocol handle, returned in NdisRegisterProtocol // NDIS_HANDLE ProtocolHandle; // NDIS Protocol characteristics // NDIS_PROTOCOL_CHARACTERISTICS PC; // NDIS Client characteristics NDIS_CLIENT_CHARACTERISTICS CC; } ndis; // Global IP State // struct { // Handle returned by IPRegisterARP // HANDLE ARPRegisterHandle; // Following are callback's into IP, set in IPRegisterARP // IP_ADD_INTERFACE pAddInterfaceRtn; // add an interface IP_DEL_INTERFACE pDelInterfaceRtn; // delete an interface IP_BIND_COMPLETE pBindCompleteRtn; // inform of bind cmpl IP_ADD_LINK pAddLinkRtn; IP_DELETE_LINK pDeleteLinkRtn; } ip; // Global adapter list // struct { RM_GROUP Group; } adapters; // Global List of backup tasks SLIST_HEADER BackupTasks; NDIS_SPIN_LOCK BackupTaskLock; UINT NumTasks; } ARP1394_GLOBALS; extern ARP1394_GLOBALS ArpGlobals; typedef struct // ARP1394_ADAPTER { RM_OBJECT_HEADER Hdr; RM_LOCK Lock; // // PRIMARY_STATE flags (in Hdr.State) // // PRIMARY_STATE is the primary state of the adapter. // #define ARPAD_PS_MASK 0x00f #define ARPAD_PS_DEINITED 0x000 #define ARPAD_PS_INITED 0x001 #define ARPAD_PS_FAILEDINIT 0x002 #define ARPAD_PS_INITING 0x003 #define ARPAD_PS_REINITING 0x004 #define ARPAD_PS_DEINITING 0x005 #define SET_AD_PRIMARY_STATE(_pAD, _IfState) \ RM_SET_STATE(_pAD, ARPAD_PS_MASK, _IfState) #define CHECK_AD_PRIMARY_STATE(_pAD, _IfState) \ RM_CHECK_STATE(_pAD, ARPAD_PS_MASK, _IfState) #define GET_AD_PRIMARY_STATE(_pAD) \ RM_GET_STATE(_pAD, ARPAD_PS_MASK) // // ACTIVE_STATE flags (in Hdr.State) // // ACTIVE_STATE is a secondary state of the adapter. // Primary state takes precedence over secondary sate. For example, // the interface is REINITING and ACTIVE, one should not actively use the // interface. // // NOTE: When the primary state is INITED, the secondary state WILL be // ACTIVATED. It is thus usually only necessary to look at the primary state. // #define ARPAD_AS_MASK 0x0f0 #define ARPAD_AS_DEACTIVATED 0x000 #define ARPAD_AS_ACTIVATED 0x010 #define ARPAD_AS_FAILEDACTIVATE 0x020 #define ARPAD_AS_DEACTIVATING 0x030 #define ARPAD_AS_ACTIVATING 0x040 #define SET_AD_ACTIVE_STATE(_pAD, _IfState) \ RM_SET_STATE(_pAD, ARPAD_AS_MASK, _IfState) #define CHECK_AD_ACTIVE_STATE(_pAD, _IfState) \ RM_CHECK_STATE(_pAD, ARPAD_AS_MASK, _IfState) #define GET_AD_ACTIVE_STATE(_pAD) \ RM_GET_STATE(_pAD, ARPAD_AS_MASK) // BRIDGE (Ethernet Emulation) state (in Hdr.State) // #define ARPAD_BS_MASK 0x100 #define ARPAD_BS_ENABLED 0x100 #define ARP_ENABLE_BRIDGE(_pAD) \ RM_SET_STATE(_pAD, ARPAD_BS_MASK, ARPAD_BS_ENABLED) #define ARP_BRIDGE_ENABLED(_pAD) \ RM_CHECK_STATE(_pAD, ARPAD_BS_MASK, ARPAD_BS_ENABLED) #define SET_BS_FLAG(_pAD, _IfState) \ RM_SET_STATE(_pAD, ARPAD_BS_MASK, _IfState) #define CHECK_BS_FLAG(_pAD, _IfState) \ RM_CHECK_STATE(_pAD, ARPAD_BS_MASK, _IfState) #define GET_BS_ACTIVE_STATE(_pAD) \ RM_GET_STATE(_pAD, ARPAD_BS_MASK) #define ARPAD_POWER_MASK 0xf000 #define ARPAD_POWER_LOW_POWER 0x1000 #define ARPAD_POWER_NORMAL 0x0000 #define SET_POWER_STATE(_pAD, _PoState) \ RM_SET_STATE(_pAD, ARPAD_POWER_MASK , _PoState) #define CHECK_POWER_STATE(_pAD, _PoState) \ RM_CHECK_STATE(_pAD, ARPAD_POWER_MASK, _PoState) #define GET_POWER_ACTIVE_STATE(_pAD) \ RM_GET_STATE(_pAD, ARPAD_POWER_MASK) // NDIS bind info. // struct { NDIS_STRING ConfigName; NDIS_STRING DeviceName; PVOID IpConfigHandle; NDIS_HANDLE BindContext; // Init/Deinit/Reinit task // PRM_TASK pPrimaryTask; // Activate/Deactivate task // PRM_TASK pSecondaryTask; NDIS_HANDLE AdapterHandle; // This is read from the configuration information in the registry. // It is a multisz string, in theory it could contain the config-strings // of multiple interfaces, although IP/1394 only provides one. // NDIS_STRING IpConfigString; } bind; // Information about the adapter, obtained by querying it. // Note: MTU is the MTU reported by the adapter, and is not the same // as the MTU reported up to ip (the latter MTU is in the ARP1394_INTERFACE // structure). // struct { ULONG MTU; // Maximum speed, in bytes per second, that the local host controller // is capable of. // ULONG Speed; #if OBSOLETE // Minimum size (in bytes) of: // -- Max individual async write to any remote node // -- Max individual async write to any channel // -- Max block we can receive on our recv FIFO // -- Max block we can receive on any channel // ULONG MaxBlockSize; #endif // 0 // max_rec (Maximum bus data record size) // size == 2^(max_rec+1). // (Macro IP1394_MAXREC_TO_SIZE in rfc.h) // // ULONG MaxRec; ULONG MaxSpeedCode; //NIC1394_FIFO_ADDRESS LocalHwAddress; UINT64 LocalUniqueID; UCHAR * szDescription; UINT DescriptionLength; // including null termination. // This address is synthesized using the adapter's EU64 unique ID. // ENetAddr EthernetMacAddress; } info; struct { // // Current Power State // NET_DEVICE_POWER_STATE State; NDIS_EVENT Complete; // // Boolean variable to track the state on resume // BOOLEAN bReceivedSetPowerD0; BOOLEAN bReceivedAf; BOOLEAN bReceivedUnbind; BOOLEAN bResuming; BOOLEAN bFailedResume; }PoMgmt; // The IP interface control block (only one per adapter). // ARP1394_INTERFACE *pIF; // Bus Topology of the 1394 card below this adapter // EUID_TOPOLOGY EuidMap; // // Set when a Workitem is queued to query Node Addresses // MYBOOL fQueryAddress; // // Power State of the Adapter // NET_DEVICE_POWER_STATE PowerState; } ARP1394_ADAPTER, *PARP1394_ADAPTER; // This structure maintains a pool of buffers, all pointing to // the same area of memory (whose contents are expected to be CONSTANT). // The primary use of this structure is to maintain a pool of encapsulation headers // buffers. // typedef struct _ARP_CONST_BUFFER_POOL { NDIS_HANDLE NdisHandle; // Buffer pool handle PRM_OBJECT_HEADER pOwningObject; // ptr to object that owns this list // Following stuff just for statistics gathering. // TODO: consider conditionally-compiling this. // struct { UINT TotBufAllocs; // # allocs from buffer pool UINT TotCacheAllocs; // # allocs from cache list UINT TotAllocFails; // # failed allocs } stats; UINT NumBuffersToCache; // Number to keep inited and cached UINT MaxBuffers; // Max number to allocate UINT cbMem; // Size in bytes of mem below... const VOID* pvMem; // Ptr to memory containg encap data UINT NumAllocd; // # outstanding allocs from pool UINT NumInCache; // # items sitting in cache. NDIS_SPIN_LOCK NdisLock; // Spinlock protecting the list below SLIST_HEADER BufferList; // List of available, inited bufs } ARP_CONST_BUFFER_POOL; // This structure is used when calling NdisRequest. // typedef struct _ARP_NDIS_REQUEST { NDIS_REQUEST Request; // The NDIS request structure. NDIS_EVENT Event; // Event to signal when done. PRM_TASK pTask; // Task to resume when done. NDIS_STATUS Status; // Status of completed request. } ARP_NDIS_REQUEST, *PARP_NDIS_REQUEST; // Static set of information associated with a VC, mainly co-ndis call handlers. // typedef struct { PCHAR Description; CO_SEND_COMPLETE_HANDLER CoSendCompleteHandler; // CO_STATUS_HANDLER CoStatusHandler; CO_RECEIVE_PACKET_HANDLER CoReceivePacketHandler; // CO_AF_REGISTER_NOTIFY_HANDLER CoAfRegisterNotifyHandler; // CL_MAKE_CALL_COMPLETE_HANDLER ClMakeCallCompleteHandler; // CL_CLOSE_CALL_COMPLETE_HANDLER ClCloseCallCompleteHandler; CL_INCOMING_CLOSE_CALL_HANDLER ClIncomingCloseCallHandler; // Vc type is currently used just for stats. We may get rid of some of the // handlers above and use the vctype instead. // enum { ARPVCTYPE_SEND_FIFO, ARPVCTYPE_RECV_FIFO, ARPVCTYPE_BROADCAST_CHANNEL, ARPVCTYPE_MULTI_CHANNEL, ARPVCTYPE_ETHERNET, ARPVCTYPE_SEND_CHANNEL, ARPVCTYPE_RECV_CHANNEL, } VcType; BOOLEAN IsDestVc; } ARP_STATIC_VC_INFO, *PARP_STATIC_VC_INFO; // ARP's protocol vc context has this common header. // typedef struct { PARP_STATIC_VC_INFO pStaticInfo; // Ndis VC handle associated with the VC. // NDIS_HANDLE NdisVcHandle; // These two tasks are for making and tearingdown the VC, // respectively. // PRM_TASK pMakeCallTask; PRM_TASK pCleanupCallTask; } ARP_VC_HEADER, *PARP_VC_HEADER; typedef struct { // Channel number. // UINT Channel; // IP multicast group address bound to this channel. // IP_ADDRESS GroupAddress; // Absolute time at which this information was updated, // in seconds. // UINT UpdateTime; // Absolute time at which this mapping will expire. // In seconds. // UINT ExpieryTime; UINT SpeedCode; // TBD // UINT Flags; // One of the MCAP_CHANNEL_FLAGS_* #define MCAP_CHANNEL_FLAGS_LOCALLY_ALLOCATED 0x1 // NodeID of owner of this channel. // UINT NodeId; } MCAP_CHANNEL_INFO, *PMCAP_CHANNEL_INFO; // The IP interface control block. // typedef struct _ARP1394_INTERFACE { RM_OBJECT_HEADER Hdr; // // PRIMARY_STATE flags (in Hdr.State) // // PRIMARY_STATE is the primary state of the interface. // #define ARPIF_PS_MASK 0x00f #define ARPIF_PS_DEINITED 0x000 #define ARPIF_PS_INITED 0x001 #define ARPIF_PS_FAILEDINIT 0x002 #define ARPIF_PS_INITING 0x003 #define ARPIF_PS_REINITING 0x004 #define ARPIF_PS_DEINITING 0x005 #define ARPIF_PS_LOW_POWER 0x006 #define SET_IF_PRIMARY_STATE(_pIF, _IfState) \ RM_SET_STATE(_pIF, ARPIF_PS_MASK, _IfState) #define CHECK_IF_PRIMARY_STATE(_pIF, _IfState) \ RM_CHECK_STATE(_pIF, ARPIF_PS_MASK, _IfState) #define GET_IF_PRIMARY_STATE(_pIF) \ RM_GET_STATE(_pIF, ARPIF_PS_MASK) // // ACTIVE_STATE flags (in Hdr.State) // // ACTIVE_STATE is a secondary state of the interface. // Primary state takes precedence over secondary sate. For example, // the interface is REINITING and ACTIVE, one should not actively use the // interface. // // NOTE: When the primary state is INITED, the secondary state WILL be // ACTIVATED. It is thus usually only necessary to look at the primary state. // #define ARPIF_AS_MASK 0x0f0 #define ARPIF_AS_DEACTIVATED 0x000 #define ARPIF_AS_ACTIVATED 0x010 #define ARPIF_AS_FAILEDACTIVATE 0x020 #define ARPIF_AS_DEACTIVATING 0x030 #define ARPIF_AS_ACTIVATING 0x040 #define SET_IF_ACTIVE_STATE(_pIF, _IfState) \ RM_SET_STATE(_pIF, ARPIF_AS_MASK, _IfState) #define CHECK_IF_ACTIVE_STATE(_pIF, _IfState) \ RM_CHECK_STATE(_pIF, ARPIF_AS_MASK, _IfState) #define GET_IF_ACTIVE_STATE(_pIF) \ RM_GET_STATE(_pIF, ARPIF_AS_MASK) // // IP_STATE flags (in Hdr.State) // // This state is set to OPEN when our open handler (ArpIpOpen) is called, and // to CLOSED when our close handler (ArpIpClose) is called // #define ARPIF_IPS_MASK 0xf00 #define ARPIF_IPS_CLOSED 0x000 #define ARPIF_IPS_OPEN 0x100 #define SET_IF_IP_STATE(_pIF, _IfState) \ RM_SET_STATE(_pIF, ARPIF_IPS_MASK, _IfState) #define CHECK_IF_IP_STATE(_pIF, _IfState) \ RM_CHECK_STATE(_pIF, ARPIF_IPS_MASK, _IfState) #define GET_IF_IP_STATE(_pIF) \ RM_GET_STATE(_pIF, ARPIF_IPS_MASK) // Init/Deinit/Reinit task // PRM_TASK pPrimaryTask; // Activate/Deactivate task // PRM_TASK pActDeactTask; // Maintenance task // PRM_TASK pMaintenanceTask; // Ndis-provided handlers and handles. // struct { // Cashed value of the adapter handle. // NDIS_HANDLE AdapterHandle; // The address family handle. // NDIS_HANDLE AfHandle; } ndis; // Stuff directly relating to interaction with IP. // struct { // // Following passed in from IP. // PVOID Context; // Use in calls to IP ULONG IFIndex; // Interface number IPRcvRtn RcvHandler; // Indicate Receive IPTxCmpltRtn TxCmpltHandler; // Transmit Complete IPStatusRtn StatusHandler; IPTDCmpltRtn TDCmpltHandler; // Transfer Data Complete IPRcvCmpltRtn RcvCmpltHandler; // Receive Complete IPRcvPktRtn RcvPktHandler; // Indicate Receive Packet IP_PNP PnPEventHandler; // // Following passed up to IP. // ULONG MTU; // Max Transmision Unit (bytes) NDIS_STRING ConfigString; // Following are for IP's query/set info functionality. // UINT ATInstance; // Instance # for this AT Entity UINT IFInstance; // Instance # for this IF Entity // // Other stuff ... // // Defaults to all-1's, but may be set by ip to be something different // (actually the only other possibility is all-0's, when the stack is // running in "BSD compatibility mode". // This field is used to decide where a given destination address is // unicast or not. // // IP_ADDRESS BroadcastAddress; // This address is used in filling out ARP requests. // IP_ADDRESS DefaultLocalAddress; #if TODO #ifdef PROMIS NDIS_OID EnabledIpFilters; // Set of enabled oids -- // set/cleared using // arpIfSetNdisRequest. #endif // PROMIS #endif // TODO } ip; // Statistics // // WARNING: arpResetIfStats() zeros this entire structure, then // selectively re-inits some fields, such as StatsResetTime. // struct { // Following for MIB stats // ULONG LastChangeTime; // Time of last state change ULONG InOctets; // Input octets ULONG InUnicastPkts; // Input Unicast packets ULONG InNonUnicastPkts; // Input Non-unicast packets ULONG OutOctets; // Output octets ULONG OutUnicastPkts; // Output Unicast packets ULONG OutNonUnicastPkts; // Output Non-unicast packets ULONG InDiscards; ULONG InErrors; ULONG UnknownProtos; ULONG OutDiscards; ULONG OutErrors; ULONG OutQlen; // // Following for our private statistics gathering. // // Timestamp since the last reset of statistics collection. // Set by a call to NdisGetCurrentSystemTime. // LARGE_INTEGER StatsResetTime; // In 100-nanoseconds. LARGE_INTEGER PerformanceFrequency; // In Hz. // // Some send pkt stats // struct { UINT TotSends; UINT FastSends; UINT MediumSends; UINT SlowSends; UINT BackFills; // UINT HeaderBufUses; // UINT HeaderBufCacheHits; ARP1394_PACKET_COUNTS SendFifoCounts; ARP1394_PACKET_COUNTS SendChannelCounts; } sendpkts; // // Some recv pkt stats // struct { UINT TotRecvs; UINT NoCopyRecvs; UINT CopyRecvs; UINT ResourceRecvs; ARP1394_PACKET_COUNTS RecvFifoCounts; ARP1394_PACKET_COUNTS RecvChannelCounts; } recvpkts; // // Task statistics // struct { UINT TotalTasks; UINT CurrentTasks; UINT TimeCounts[ARP1394_NUM_TASKTIME_SLOTS]; } tasks; // // Arp cache stats // struct { UINT TotalQueries; UINT SuccessfulQueries; UINT FailedQueries; UINT TotalResponses; UINT TotalLookups; // UINT TraverseRatio; << this is picked up by looking into the // << hash table data structure. } arpcache; // // Call stats // struct { // // FIFO-related call stats. // UINT TotalSendFifoMakeCalls; UINT SuccessfulSendFifoMakeCalls; UINT FailedSendFifoMakeCalls; UINT IncomingClosesOnSendFifos; // // Channel-related call stats. // UINT TotalChannelMakeCalls; UINT SuccessfulChannelMakeCalls; UINT FailedChannelMakeCalls; UINT IncomingClosesOnChannels; } calls; } stats; // Group containing local ip addresses, of type ARPCB_LOCAL_IP // RM_GROUP LocalIpGroup; // Group containing remote ip addresses, of type ARPCB_REMOTE_IP // (this is the arp cache) // RM_GROUP RemoteIpGroup; // Group containing remote ethernet destinations. This group is only used // if the adapter is operating in bridge mode. // This is the Ethernet address cache. // RM_GROUP RemoteEthGroup; // Group containing remote h/w distinations, of type ARPCB_DEST // (each ARPCB_DEST has a group of VCs) // RM_GROUP DestinationGroup; // Group containing the table (bridge only) of dhcp session, and their // associated physical addresses // RM_GROUP EthDhcpGroup; // Stuff relating to the receive FIFO, which is owned by the interface. // // struct { ARP_VC_HEADER VcHdr; // Address offset of the receive VC // struct { ULONG Off_Low; USHORT Off_High; } offset; } recvinfo; // This maintains interface-wide information relevant to the send path. // struct { // Lock used exclusively for sending. // Protects the following: // ??? this->sendinfo.listPktsWaitingForHeaders // ??? this->sendinfo.NumSendPacketsWaiting // pLocalIp->sendinfo // pDest->sendinfo // // RM_LOCK Lock; // List of send packets waiting for header buffers to become available. // LIST_ENTRY listPktsWaitingForHeaders; // Length of the above list // UINT NumSendPacketsWaiting; // Pool of header buffer pool. This is seralized by its OWN lock, // not by sendinfo.Lock. // ARP_CONST_BUFFER_POOL HeaderPool; // Pool of Channel header buffers. This is serialized by its OWN lock, // not by sendinfo.Lock // ARP_CONST_BUFFER_POOL ChannelHeaderPool; } sendinfo; // // Following 3 are "special" destinations .... // // Pointer to the broadcast-channel destination object. // PARPCB_DEST pBroadcastDest; // Pointer to the multi-channel destination object. // PARPCB_DEST pMultiChannelDest; // Pointer to the ethernet destination object. // PARPCB_DEST pEthernetDest; // Stuff relating to running the ARP protocol // (All serialized by the IF lock (not the IF SEND lock). // struct { // The NDIS packet pool for ARP pkts. // NDIS_HANDLE PacketPool; // The NDIS buffer pool for ARP pkts. // NDIS_HANDLE BufferPool; // Number of currently allocated packets. // LONG NumOutstandingPackets; // Maximum size of the packet that can be allocated from this pool. // UINT MaxBufferSize; } arp; // Stuff relating to the Ethernet VC, which is owned by the interface. // struct { // The NDIS packet pool for Ethernet pkts. // NDIS_HANDLE PacketPool; // The NDIS buffer pool for Ethernet packet headers. // NDIS_HANDLE BufferPool; #if TEST_ICS_HACK PRM_TASK pTestIcsTask; #endif // TEST_ICS_HACK; } ethernet; #define ARP_NUM_CHANNELS 64 struct { // Information about each channel. Information includes: // IP multicast group address and expiry time. // MCAP_CHANNEL_INFO rgChannelInfo[ARP_NUM_CHANNELS]; } mcapinfo; struct { PRM_TASK pAfPendingTask; } PoMgmt; } ARP1394_INTERFACE, *PARP1394_INTERFACE; #define ARP_OBJECT_IS_INTERFACE(_pHdr) ((_pHdr)->Sig == MTAG_INTERFACE) #define ASSERT_VALID_INTERFACE(_pIF) ASSERT((_pIF)->Hdr.Sig == MTAG_INTERFACE) #define ARP_WRITELOCK_IF_SEND_LOCK(_pIF, _psr) \ RmDoWriteLock(&(_pIF)->sendinfo.Lock, (_psr)) #define ARP_READLOCK_IF_SEND_LOCK(_pIF, _psr) \ RmDoReadLock(&(_pIF)->sendinfo.Lock, (_psr)) #define ARP_UNLOCK_IF_SEND_LOCK(_pIF, _psr) \ RmDoUnlock(&(_pIF)->sendinfo.Lock, (_psr)) #define ARP_FASTREADLOCK_IF_SEND_LOCK(_pIF) \ NdisAcquireSpinLock(&(_pIF)->sendinfo.Lock.OsLock) #define ARP_FASTUNLOCK_IF_SEND_LOCK(_pIF) \ NdisReleaseSpinLock(&(_pIF)->sendinfo.Lock.OsLock) /*++ VOID ARP_IF_STAT_INCR( IN ARP1394_INTERFACE * _pIF IN OPAQUE StatsCounter ) Increment the specified StatsCounter on an Interface by 1. --*/ #define ARP_IF_STAT_INCR(_pIF, StatsCounter) \ NdisInterlockedIncrement(&(_pIF)->stats.StatsCounter) /*++ VOID ARP_IF_STAT_ADD( IN ARP1394_INTERFACE * _pIF IN OPAQUE StatsCounter, IN ULONG IncrValue ) Increment the specified StatsCounter on an Interface by the specified IncrValue. Take a lock on the interface to do so. --*/ #if BINARY_COMPATIBLE #define ARP_IF_STAT_ADD(_pIF, StatsCounter, IncrValue) \ ((_pIF)->stats.StatsCounter += (IncrValue)) #else // !BINARY_COMPATIBLE #define ARP_IF_STAT_ADD(_pIF, StatsCounter, IncrValue) \ InterlockedExchangeAdd(&(_pIF)->stats.StatsCounter, IncrValue) #endif // !BINARY_COMPATIBLE // // This is the table used to store the DHCP entries used in the bridge mode // typedef struct _ARP1394_ETH_DHCP_ENTRY { RM_OBJECT_HEADER Hdr; // // xid - per dhcp session (e.g discover, offer) // ULONG xid; // // HW address in the dhcp packet. // ENetAddr requestorMAC; // // New HW address that arp1394 inserts in the dhcp packet // ENetAddr newMAC; // // Time last checked to be used for aging purposes // UINT TimeLastChecked; // // Task used in unloading DhcpEntry // PRM_TASK pUnloadTask; }ARP1394_ETH_DHCP_ENTRY, *PARP1394_ETH_DHCP_ENTRY; typedef enum _ARP_RESUME_CAUSE { Cause_SetPowerD0, Cause_AfNotify, Cause_Unbind } ARP_RESUME_CAUSE; //========================================================================= // N D I S H A N D L E R S //========================================================================= INT ArpNdBindAdapter( OUT PNDIS_STATUS pStatus, IN NDIS_HANDLE BindContext, IN PNDIS_STRING pDeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2 ); VOID ArpNdUnbindAdapter( OUT PNDIS_STATUS pStatus, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE UnbindContext ); VOID ArpNdOpenAdapterComplete( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus ); VOID ArpNdCloseAdapterComplete( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status ); VOID ArpNdResetComplete( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status ); VOID ArpNdReceiveComplete( IN NDIS_HANDLE ProtocolBindingContext ); VOID ArpNdRequestComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST pNdisRequest, IN NDIS_STATUS Status ); VOID ArpNdStatus( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS GeneralStatus, IN PVOID pStatusBuffer, IN UINT StatusBufferSize ); VOID ArpNdStatusComplete( IN NDIS_HANDLE ProtocolBindingContext ); VOID ArpNdSendComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pNdisPacket, IN NDIS_STATUS Status ); // // Following are some connectionless handlers we provide because we're calling // connectionless entrypoints. // NDIS_STATUS ArpNdReceive ( NDIS_HANDLE ProtocolBindingContext, NDIS_HANDLE Context, VOID *Header, UINT HeaderSize, VOID *Data, UINT Size, UINT TotalSize ); INT ArpNdReceivePacket ( NDIS_HANDLE ProtocolBindingContext, PNDIS_PACKET Packet ); NDIS_STATUS ArpNdPnPEvent( IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent ); VOID ArpNdUnloadProtocol( VOID ); VOID ArpCoSendComplete( IN NDIS_STATUS Status, IN NDIS_HANDLE ProtocolVcContext, IN PNDIS_PACKET pNdisPacket ); VOID ArpCoStatus( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE ProtocolVcContext OPTIONAL, IN NDIS_STATUS GeneralStatus, IN PVOID pStatusBuffer, IN UINT StatusBufferSize ); UINT ArpCoReceivePacket( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE ProtocolVcContext, IN PNDIS_PACKET pNdisPacket ); VOID ArpCoAfRegisterNotify( IN NDIS_HANDLE ProtocolBindingContext, IN PCO_ADDRESS_FAMILY pAddressFamily ); NDIS_STATUS ArpCoCreateVc( IN NDIS_HANDLE ProtocolAfContext, IN NDIS_HANDLE NdisVcHandle, OUT PNDIS_HANDLE pProtocolVcContext ); NDIS_STATUS ArpCoDeleteVc( IN NDIS_HANDLE ProtocolVcContext ); NDIS_STATUS ArpCoIncomingCall( IN NDIS_HANDLE ProtocolSapContext, IN NDIS_HANDLE ProtocolVcContext, IN OUT PCO_CALL_PARAMETERS pCallParameters ); VOID ArpCoCallConnected( IN NDIS_HANDLE ProtocolVcContext ); VOID ArpCoIncomingClose( IN NDIS_STATUS CloseStatus, IN NDIS_HANDLE ProtocolVcContext, IN PVOID pCloseData OPTIONAL, IN UINT Size OPTIONAL ); VOID ArpCoQosChange( IN NDIS_HANDLE ProtocolVcContext, IN PCO_CALL_PARAMETERS pCallParameters ); VOID ArpCoOpenAfComplete( IN NDIS_STATUS Status, IN NDIS_HANDLE ProtocolAfContext, IN NDIS_HANDLE NdisAfHandle ); VOID ArpCoCloseAfComplete( IN NDIS_STATUS Status, IN NDIS_HANDLE ProtocolAfContext ); VOID ArpCoMakeCallComplete( IN NDIS_STATUS Status, IN NDIS_HANDLE ProtocolVcContext, IN NDIS_HANDLE NdisPartyHandle OPTIONAL, IN PCO_CALL_PARAMETERS pCallParameters ); VOID ArpCoCloseCallComplete( IN NDIS_STATUS Status, IN NDIS_HANDLE ProtocolVcContext, IN NDIS_HANDLE ProtocolPartyContext OPTIONAL ); VOID ArpCoModifyQosComplete( IN NDIS_STATUS Status, IN NDIS_HANDLE ProtocolVcContext, IN PCO_CALL_PARAMETERS pCallParameters ); NDIS_STATUS ArpCoRequest( IN NDIS_HANDLE ProtocolAfContext, IN NDIS_HANDLE ProtocolVcContext OPTIONAL, IN NDIS_HANDLE ProtocolPartyContext OPTIONAL, IN OUT PNDIS_REQUEST pNdisRequest ); VOID ArpCoRequestComplete( IN NDIS_STATUS Status, IN NDIS_HANDLE ProtocolAfContext, IN NDIS_HANDLE ProtocolVcContext OPTIONAL, IN NDIS_HANDLE ProtocolPartyContext OPTIONAL, IN PNDIS_REQUEST pNdisRequest ); //========================================================================= // I P H A N D L E R S //========================================================================= INT ArpIpDynRegister( IN PNDIS_STRING pAdapterString, IN PVOID IpContext, IN struct _IP_HANDLERS * pIpHandlers, IN struct LLIPBindInfo * pBindInfo, IN UINT InterfaceNumber ); VOID ArpIpOpen( IN PVOID Context ); VOID ArpIpClose( IN PVOID Context ); UINT ArpIpAddAddress( IN PVOID Context, IN UINT AddressType, IN IP_ADDRESS IpAddress, IN IP_MASK Mask, IN PVOID Context2 ); UINT ArpIpDelAddress( IN PVOID Context, IN UINT AddressType, IN IP_ADDRESS IpAddress, IN IP_MASK Mask ); NDIS_STATUS ArpIpMultiTransmit( IN PVOID Context, IN PNDIS_PACKET * pNdisPacketArray, IN UINT NumberOfPackets, IN IP_ADDRESS Destination, IN RouteCacheEntry * pRCE OPTIONAL, IN VOID * ArpCtxt ); NDIS_STATUS ArpIpTransmit( IN PVOID Context, IN PNDIS_PACKET pNdisPacket, IN IP_ADDRESS Destination, IN RouteCacheEntry * pRCE OPTIONAL, IN VOID * ArpCtxt ); NDIS_STATUS ArpIpTransfer( IN PVOID Context, IN NDIS_HANDLE Context1, IN UINT ArpHdrOffset, IN UINT ProtoOffset, IN UINT BytesWanted, IN PNDIS_PACKET pNdisPacket, OUT PUINT pTransferCount ); VOID ArpIpInvalidate( IN PVOID Context, IN RouteCacheEntry * pRCE ); INT ArpIpQueryInfo( IN PVOID Context, IN TDIObjectID * pID, IN PNDIS_BUFFER pNdisBuffer, IN OUT PUINT pBufferSize, IN PVOID QueryContext ); INT ArpIpSetInfo( IN PVOID Context, IN TDIObjectID * pID, IN PVOID pBuffer, IN UINT BufferSize ); INT ArpIpGetEList( IN PVOID Context, IN TDIEntityID * pEntityList, IN OUT PUINT pEntityListSize ); VOID ArpIpPnPComplete( IN PVOID Context, IN NDIS_STATUS Status, IN PNET_PNP_EVENT pNetPnPEvent ); #ifdef PROMIS EXTERN NDIS_STATUS ArpIpSetNdisRequest( IN PVOID Context, IN NDIS_OID Oid, IN UINT On ); #endif // PROMIS // The following structure has the general form of NDIS_CO_MEDIA_PARAMETERS. // To properly track changes in NDIS_CO_MEDIA_PARAMETERS (however unlikeley!), // code which uses any field in this structure should assert that the field is at // the same offset as the corresponding NDIS structure. // For example: // ASSERT(FIELD_OFFSET(ARP1394_CO_MEDIA_PARAMETERS, Parameters) // == FIELD_OFFSET(CO_MEDIA_PARAMETERS, MediaSpecific.Parameters)) // // typedef struct { // First 3 fields of CO_MEDIA_PARAMETERS // ULONG Flags; // TRANSMIT_VC and/or RECEIVE_VC ULONG ReceivePriority; // 0 (unused) ULONG ReceiveSizeHint; // 0 (unused) // Followed by 1st 2 fields of CO_SPECIFIC_PARAMETERS // ULONG POINTER_ALIGNMENT ParamType; // Set to NIC1394_MEDIA_SPECIFIC ULONG Length; // Set to sizeof(NIC1394_MEDIA_PARAMETERS) // Followed by the NIC1394-specific media parameters. // Note: we can't directly put the NIC1394_MEDIA_PARAMETERS structure here because // it (currently) requires 8-byte alignment. // UCHAR Parameters[sizeof(NIC1394_MEDIA_PARAMETERS)]; } ARP1394_CO_MEDIA_PARAMETERS; typedef enum _TASK_CAUSE { SetLowPower = 1, SetPowerOn }TASK_CAUSE ; typedef struct { RM_TASK TskHdr; // Used to save the true return status (typically a failure status, // which we don't want to forget during async cleanup). // NDIS_STATUS ReturnStatus; } TASK_ADAPTERINIT, *PTASK_ADAPTERINIT; typedef struct { RM_TASK TskHdr; ARP_NDIS_REQUEST ArpNdisRequest; NIC1394_LOCAL_NODE_INFO LocalNodeInfo; // Following is used to switch to PASSIVE before calling IP's add interface // Rtn. // NDIS_WORK_ITEM WorkItem; } TASK_ADAPTERACTIVATE, *PTASK_ADAPTERACTIVATE; typedef struct { RM_TASK TskHdr; NDIS_HANDLE pUnbindContext; } TASK_ADAPTERSHUTDOWN, *PTASK_ADAPTERSHUTDOWN; // This is the task structure to be used with arpTaskActivateInterface // typedef struct { RM_TASK TskHdr; #if ARP_DEFERIFINIT // Following is used when waiting for the adapter to go to connected status // // NDIS_TIMER Timer; #endif // ARP_DEFERIFINIT // Following is used to switch to PASSIVE before calling IP's add interface // Rtn. // NDIS_WORK_ITEM WorkItem; } TASK_ACTIVATE_IF, *PTASK_ACTIVATE_IF; // This is the task structure to be used with arpTaskDeactivateInterface // typedef struct { RM_TASK TskHdr; BOOLEAN fPendingOnIpClose; TASK_CAUSE Cause; // Following is used to switch to PASSIVE before calling IP's del interface // Rtn. // NDIS_WORK_ITEM WorkItem; } TASK_DEACTIVATE_IF, *PTASK_DEACTIVATE_IF; // This is the task structure to be used with arpTaskReinitInterface // typedef struct { RM_TASK TskHdr; NDIS_HANDLE pUnbindContext; // Net PnP event to complete when reinit task is done. // PNET_PNP_EVENT pNetPnPEvent; } TASK_REINIT_IF, *PTASK_REINIT_IF; typedef struct { RM_TASK TskHdr; // Ndis call params and media params for this call. // CO_CALL_PARAMETERS CallParams; ARP1394_CO_MEDIA_PARAMETERS MediaParams; } TASK_MAKECALL; // This is the task structure to be used with arpTaskResolveIpAddress // typedef struct { RM_TASK TskHdr; // Number of retry attempts left before we declare an address resolution failure. // UINT RetriesLeft; // Used for the response timeout // NDIS_TIMER Timer; } TASK_RESOLVE_IP_ADDRESS, *PTASK_RESOLVE_IP_ADDRESS; typedef struct { RM_TASK TskHdr; MYBOOL Quit; // If set, task will quit. NDIS_TIMER Timer; // Used for the periodically sending out packets. PNDIS_PACKET p1394Pkt; // Used for testing forward to ethernet PNDIS_PACKET pEthPkt; // Used for sending connectionless ethernet pkts. UINT Delay; // Delay (ms) in between sending packets. UINT PktType; // Type of operation: do nothing, send over ethernet // etc. } TASK_ICS_TEST, *PTASK_ICS_TEST; typedef struct { RM_TASK TskHdr; MYBOOL Quit; // If set, task will quit. NDIS_TIMER Timer; // Used for periodically waking up to do stuff. UINT Delay; // Current value of delay (seconds). Can change. UINT RemoteIpMaintenanceTime; // Absolute time in seconds UINT RemoteEthMaintenanceTime; // Absolute time in seconds UINT LocalIpMaintenanceTime; // Absolute time in seconds. UINT McapDbMaintenanceTime; // Absolute time in seconds. UINT DhcpTableMaintainanceTime; // Absolute time in seconds } TASK_IF_MAINTENANCE, *PTASK_IF_MAINTENANCE; typedef struct _TASK_BACKUP { RM_TASK Hdr; // // We are using Backup Task flag at position 31 because we do // not want to conflict with the ResumeDelayed flags // #define ARP_BACKUP_TASK_MASK 0x80000000 #define ARP_BACKUP_TASK_FLAG 0x80000000 #define MARK_TASK_AS_BACKUP(_pT) \ RM_SET_STATE(_pT, ARP_BACKUP_TASK_MASK , ARP_BACKUP_TASK_FLAG ) #define CHECK_TASK_IS_BACKUP(_pT) \ RM_CHECK_STATE(_pT, ARP_BACKUP_TASK_MASK , ARP_BACKUP_TASK_FLAG ) #define GET_TASK_BACKUP_STATE(_pT) \ RM_GET_STATE(_pT, ARP_BACKUP_TASK_MASK ) DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) SINGLE_LIST_ENTRY List; // Linked list pointing to next task } TASK_BACKUP, *PTASK_BACKUP; // This is the task structure to be used with arpTaskResolveIpAddress // typedef struct { RM_TASK TskHdr; NDIS_WORK_ITEM WorkItem; } TASK_UNLOAD_REMOTE, *PTASK_UNLOAD_REMOTE; // // This task is used during a SetPower. // It contains structures that will be track of the // the numbero of calls that are closed /opened // and the events that need to be waited for. // typedef struct _CALL_COUNT { // Count of Destination that will closeVc // ULONG DestCount; // Event which the Close VC will wait on. // NDIS_EVENT VcEvent; } CALL_COUNT, *PCALL_COUNT; typedef struct _TASK_POWER { RM_TASK Hdr; // Event which the Set Power will wait on. // NDIS_EVENT CompleteEvent; // Status of the Task // PNDIS_STATUS pStatus; // Power state we are transitioning to // NET_DEVICE_POWER_STATE PowerState; // //WorkItem to switch to passive NDIS_WORK_ITEM WorkItem; // // Last working Stage of task - dbg purpose only // UINT LastStage; // // Previous state of parent object. This is used so // that the object can be placed back into its previous // state. // UINT PrevState; } TASK_POWER, *PTASK_POWER; // // This structure is used to keep track of a close call // that originated becuase of a SetPower // typedef struct _TASK_SET_POWER_CALL { RM_TASK Hdr; TASK_CAUSE Cause; // The Call Call Count is used as place to count the number of outstanding close calls // It uses DestCount as a place to store this information // PCALL_COUNT pCount; }TASK_SET_POWER_CALL, *PTASK_SET_POWER_CALL; // // ARP1394_TASK is the union of all tasks structures used in arp1394. // arpAllocateTask allocates memory of sizeof(ARP1394_TASK), which is guaranteed // to be large enough to hold any task. // typedef union { RM_TASK TskHdr; TASK_ADAPTERINIT AdapterInit; TASK_ADAPTERSHUTDOWN AdapterShutdown; TASK_ADAPTERACTIVATE AdapterActivate; TASK_ACTIVATE_IF ActivateIf; TASK_DEACTIVATE_IF DeactivateIf; TASK_REINIT_IF ReinitIf; TASK_MAKECALL MakeFifoCall; TASK_RESOLVE_IP_ADDRESS ResolveIpAddress; #if TEST_ICS_HACK TASK_ICS_TEST IcsTest; #endif // TEST_ICS_HACK TASK_IF_MAINTENANCE IfMaintenance; TASK_BACKUP Backup; TASK_UNLOAD_REMOTE Unload; TASK_SET_POWER_CALL CloseCall; TASK_POWER TaskPower; } ARP1394_TASK; // // ---------------------------- DESTINATION (REMOTE) KEY -------------- // #pragma pack (push, 1) typedef union _REMOTE_DEST_KEY { ENetAddr ENetAddress; IPAddr IpAddress; UCHAR Addr[ARP_802_ADDR_LENGTH]; struct { ULONG u32; USHORT u16; } u; } REMOTE_DEST_KEY, *PREMOTE_DEST_KEY; #pragma pack (pop) #define REMOTE_DEST_IP_ADDRESS_FLAG 0xffff #define IS_REMOTE_DEST_IP_ADDRESS(_R) ((_R)->u.u16 == REMOTE_DEST_IP_ADDRESS_FLAG ) #define REMOTE_DEST_IP_ADDRESS(_R) ((&(_R)->IpAddress)) #define REMOTE_DEST_ETH_ADDRESS(_R) ((&(_R)->ENetAddress)) #define REMOTE_DEST_KEY_INIT(_R) { (_R)->u.u32 = 0; (_R)->u.u16=REMOTE_DEST_IP_ADDRESS_FLAG ; }; //const REMOTE_DEST_KEY DefaultRemoteDestKey = {0,0,0,0,0xff,0xff}; // // ---------------------------- DESTINATION (REMOTE) IP CONTROL BLOCK -------------- // // Contains information about one destination (remote) IP address. // // Parent Object: pInterface // Lock: It's own lock. // // There is atmost one ARP Table entry for a given IP address. // // The IP Entry participates in two lists: // (1) A list of all entries that hash to the same bucket in the ARP Table // (2) A list of all entries that resolve to the same destination H/W Address -- // this is only if the IP address is unicast. // // A pointer to this structure is also used as our context value in the // Route Cache Entry prepared by the higher layer protocol(s). // // Reference Count: We add one to its ref count for each of the following: // TBD: // typedef struct _ARPCB_REMOTE_IP { RM_OBJECT_HEADER Hdr; // Common header // // State flags for RemoteIp (in Hdr.State) // #define ARPREMOTEIP_RESOLVED_MASK 0x0f #define ARPREMOTEIP_UNRESOLVED 0x00 #define ARPREMOTEIP_RESOLVED 0x01 #define ARPREMOTEIP_SDTYPE_MASK 0x10 // "SD" == Static/Dynamic #define ARPREMOTEIP_STATIC 0x00 #define ARPREMOTEIP_DYNAMIC 0x10 #define ARPREMOTEIP_FCTYPE_MASK 0x20 // "FC" == FIFO/Channel #define ARPREMOTEIP_FIFO 0x00 #define ARPREMOTEIP_CHANNEL 0x20 #define ARPREMOTEIP_MCAP_MASK 0x40 // "FC" == FIFO/Channel #define ARPREMOTEIP_MCAP_CAPABLE 0x40 #define SET_REMOTEIP_RESOLVE_STATE(_pRIp, _IfState) \ RM_SET_STATE(_pRIp, ARPREMOTEIP_RESOLVED_MASK, _IfState) #define CHECK_REMOTEIP_RESOLVE_STATE(_pRIp, _IfState) \ RM_CHECK_STATE(_pRIp, ARPREMOTEIP_RESOLVED_MASK, _IfState) #define SET_REMOTEIP_SDTYPE(_pRIp, _IfState) \ RM_SET_STATE(_pRIp, ARPREMOTEIP_SDTYPE_MASK, _IfState) #define CHECK_REMOTEIP_SDTYPE(_pRIp, _IfState) \ RM_CHECK_STATE(_pRIp, ARPREMOTEIP_SDTYPE_MASK, _IfState) #define SET_REMOTEIP_FCTYPE(_pRIp, _IfState) \ RM_SET_STATE(_pRIp, ARPREMOTEIP_FCTYPE_MASK, _IfState) #define CHECK_REMOTEIP_FCTYPE(_pRIp, _IfState) \ RM_CHECK_STATE(_pRIp, ARPREMOTEIP_FCTYPE_MASK, _IfState) #define SET_REMOTEIP_MCAP(_pRIp, _IfState) \ RM_SET_STATE(_pRIp, ARPREMOTEIP_MCAP_MASK, _IfState) #define CHECK_REMOTEIP_MCAP(_pRIp, _IfState) \ RM_CHECK_STATE(_pRIp, ARPREMOTEIP_MCAP_MASK, _IfState) IP_ADDRESS IpAddress; // IP Address LIST_ENTRY linkSameDest; // List of entries pointing to // the same destination. ARPCB_DEST *pDest; // Pointer to destination CB. REMOTE_DEST_KEY Key; // Ip address or Mac Address #if TODO // Timers are: (all exclusive) // - Aging timer // - Waiting for ARP reply // - Waiting for InARP reply // - Delay after NAK // - Waiting for MARS MULTI // - Delay before marking for reval #endif // TODO ULONG RetriesLeft; // The information in this struct is protected by the IF send lock, // EXCEPT as noted. // struct { // Singly-linked list of Route Cache Entries (no space in RCE to hold // a doubly-linked list, unfortunately.) // RouteCacheEntry *pRceList; // listSendPkts is NOT protected by the IF send lock. Instead it is protected // by this object(pRemoteIp)'s lock. // LIST_ENTRY listSendPkts; // This entry is NOT protected by any lock. It is set to ZERO // each time a packet is sent to this address and is set to the // current system time periodically by the garbage collecting task. // UINT TimeLastChecked; } sendinfo; PRM_TASK pSendPktsTask;// Points to the task (if any) // Attempting to send queued packets. PRM_TASK pResolutionTask;// Points to the task (if any) // attempting to resolve // this destination IP address. PRM_TASK pUnloadTask; // Unload (shutdown) this object. } ARPCB_REMOTE_IP, *PARPCB_REMOTE_IP; #define ASSERT_VALID_REMOTE_IP(_pRemoteIp) \ ASSERT((_pRemoteIp)->Hdr.Sig == MTAG_REMOTE_IP) #define VALID_REMOTE_IP(_pRemoteIp) ((_pRemoteIp)->Hdr.Sig == MTAG_REMOTE_IP) // // --------------------- DESTINATION (REMOTE) ETHERNET CONTROL BLOCK -------------- // Creation Params -- passed into the function that creates an // instance of a remote ethernet control block. // typedef struct { ENetAddr EthAddress; IP_ADDRESS IpAddress; } ARP_REMOTE_ETH_PARAMS, *PARP_REMOTE_ETH_PARAMS; // // Contains information about one destination (remote) Ethernet address. // // Parent Object: pInterface // Lock: pInterface // // There is atmost one Ethernet Table entry for a given Remote ethernet address. // // The Ethernet entry participates in one group: // A list of all entries that hash to the same bucket in the Ethernet Table // typedef struct _ARPCB_REMOTE_ETH { RM_OBJECT_HEADER Hdr; // Common header IP_ADDRESS IpAddress; // Remote IP address ENetAddr EthAddress; // Remote Ethernet MAC addres PRM_TASK pUnloadTask; // Unload (shutdown) this object. // This entry is NOT protected by any lock. It is set to ZERO // each time a packet is sent to this address and is set to the // current system time periodically by the garbage collecting task. // UINT TimeLastChecked; } ARPCB_REMOTE_ETH, *PARPCB_REMOTE_ETH; #define ASSERT_VALID_REMOTE_ETH(_pRemoteEth) \ ASSERT((_pRemoteEth)->Hdr.Sig == MTAG_REMOTE_ETH) // // ---------------------------- LOCAL IP CONTROL BLOCK -------------- // // Contains information about one local IP address. // // Parent Object: pInterface // Lock: uses parent's (pInterface's) lock. // typedef struct _ARPCB_LOCAL_IP { RM_OBJECT_HEADER Hdr; // Common header // // State flags for LocalIp (in Hdr.State) // #define ARPLOCALIP_MCAP_MASK 0x40 #define ARPLOCALIP_MCAP_CAPABLE 0x40 #define SET_LOCALIP_MCAP(_pLIp, _IfState) \ RM_SET_STATE(_pLIp, ARPLOCALIP_MCAP_MASK, _IfState) #define CHECK_LOCALIP_MCAP(_pLIp, _IfState) \ RM_CHECK_STATE(_pLIp, ARPLOCALIP_MCAP_MASK, _IfState) UINT IpAddressType; // One of the LLIP_ADDR_* consts IP_ADDRESS IpAddress; // The Address IP_MASK IpMask; // Mask for the above. UINT AddAddressCount; // No of times address was added PRM_TASK pRegistrationTask; // Points to the task (if any) // that is doing the unsolicited // ARP request to report and // validate this IP address is // owned by the local interface. PRM_TASK pUnloadTask; // Unload (shutdown) this object. LIST_ENTRY linkSameDest; // List of entries pointing to ARPCB_DEST *pDest; // Pointer to destination CB. } ARPCB_LOCAL_IP, *PARPCB_LOCAL_IP; // Returns true IFF pLocalIp is in the process of going away (assumes // pLocalIp's lock is held) ... // #define ARP_LOCAL_IP_IS_UNLOADING(pLocalIp) (pLocalIp->pUnloadTask != NULL) typedef struct { NIC1394_DESTINATION HwAddr; // Must be 1st for hash function. UINT ChannelSeqNo; BOOLEAN ReceiveOnly; BOOLEAN AcquireChannel; } ARP_DEST_PARAMS, *PARP_DEST_PARAMS; // // ---------------------------- DESTINATION CONTROL BLOCK -------------- // // All information about an remote destination, including list of VCs to it. // This is used for both unicast destinations and multicast/broadcast // destinations. // // Parent Object: PARCB_INTERFACE (Interface control block). // Lock: uses parent's (Interface). // typedef struct _ARPCB_DEST { RM_OBJECT_HEADER Hdr; // Common header LIST_ENTRY listIpToThisDest; // List of IP entries that // point to this entry LIST_ENTRY listLocalIp; // List of local IP entries // related to this dest. that // (Currently only related to // MCAP recv channels, but // could be extended to // using async stream for // FIFO as well!). ARP_DEST_PARAMS Params; // Dest HW Address, etc. ARP_VC_HEADER VcHdr; // Single VC associated // with this object. PRM_TASK pUnloadTask; // Unload (shutdown) this object. // The following structure is protected by the IF send lock. // It contains all the information required for the fast send path. // struct { PRM_TASK pSuspendedCleanupCallTask; UINT NumOutstandingSends; BOOLEAN OkToSend; BOOLEAN IsFifo; } sendinfo; #define ARP_DEST_IS_FIFO(_pDest) ((_pDest)->sendinfo.IsFifo != 0) #define ARP_CAN_SEND_ON_DEST(_pDest) ((_pDest)->sendinfo.OkToSend != 0) } ARPCB_DEST, *PARPCB_DEST; #define ARP_OBJECT_IS_DEST(_pHdr) ((_pHdr)->Sig == MTAG_DEST) #define ASSERT_VALID_DEST(_pDest) \ ASSERTEX((_pDest)->Hdr.Sig == MTAG_DEST, (_pDest)) #if OBSOLETE // // ---------------------------- RECV CHANNEL CONTROL BLOCK -------------- // // All information about a receive channel destination. // // Parent Object: PARCB_INTERFACE (Interface control block). // Lock: uses parent's (Interface). // typedef struct _ARPCB_RCVCH { RM_OBJECT_HEADER Hdr; // Common header LIST_ENTRY listLIpToThisDest; // List of Local IP entries // that point to this entry NIC1394_DESTINATION HwAddr; // Destination HW Address. ARP_VC_HEADER VcHdr; // Single VC associated // with this object. PRM_TASK pUnloadTask; // Unload (shutdown) this object. } ARPCB_DEST, *PARPCB_RCVCH; #endif // OBSOLETE // Following sits in the miniport-reserved portion of send-pkts, before they // are sent out. We have 4 UINT_PTRs of space available to us. // typedef struct { LIST_ENTRY linkQueue; union { struct { IP_ADDRESS IpAddress; ULONG Flags; #define ARPSPI_BACKFILLED 0x1 #define ARPSPI_HEADBUF 0x2 #define ARPSPI_FIFOPKT 0x4 #define ARPSPI_CHANNELPKT 0x8 } IpXmit; }; } ARP_SEND_PKT_MPR_INFO; // // Various macros for getting and setting information saved in the // MiniportReserved portion of packets waiting to be sent... // #define ARP_OUR_CTXT_FROM_SEND_PACKET(_pPkt) \ ((ARP_SEND_PKT_MPR_INFO *) &(_pPkt)->MiniportReserved) #define ARP_SEND_PKT_FROM_OUR_CTXT(_pCtxt) \ CONTAINING_RECORD((_pCtxt), NDIS_PACKET, MiniportReserved) // Our context in the IP RouteCacheEntry. // (Max 2 UINT_PTRs available) // Since we also want to keep the destination type (FIFO or CHANNEL) in the RCE, // we resort to the questionable technique of saving the FIFO/CHANNEL info in // LSB bit of the UINT_PTR used for storing the pointer to the RemoteIp object. // We want to keep the FIFO/CHANNEL info in the RCE so that we can prepend // the correct header block WITHOUT holding the send lock. We want to keep // the send lock held for as little time as possible. // typedef struct { ARPCB_REMOTE_IP *pRemoteIp; // Ptr to pRemoteIp RouteCacheEntry *pNextRce; // Ptr to next RCE associated with the above // RemoteIP } ARP_RCE_CONTEXT; #define ARP_OUR_CTXT_FROM_RCE(_pRCE) \ ((ARP_RCE_CONTEXT*) &(_pRCE)->rce_context) // Parsed version of the IP/1394 ARP packet. // typedef struct { NIC1394_FIFO_ADDRESS SenderHwAddr; // requires 8-byte alignment. UINT OpCode; UINT SenderMaxRec; UINT SenderMaxSpeedCode; IP_ADDRESS SenderIpAddress; IP_ADDRESS TargetIpAddress; UCHAR SourceNodeAdddress; UCHAR fPktHasNodeAddress; ENetAddr SourceMacAddress; } IP1394_ARP_PKT_INFO, *PIP1394_ARP_PKT_INFO; // Parsed version of the IP/1394 MCAP Group Descriptor // typedef struct { UINT Expiration; UINT Channel; UINT SpeedCode; IP_ADDRESS GroupAddress; } IP1394_MCAP_GD_INFO, * PIP1394_MCAP_GD_INFO; // Parsed version of an IP/1394 MCAP packet. // typedef struct { UINT SenderNodeID; UINT OpCode; UINT NumGroups; PIP1394_MCAP_GD_INFO pGdis; // Space for storing up-to 4 GD_INFOs // IP1394_MCAP_GD_INFO GdiSpace[4]; } IP1394_MCAP_PKT_INFO, *PIP1394_MCAP_PKT_INFO; typedef struct _EUID_NODE_MAC_TABLE_WORKITEM { // WorkItem used in the request NDIS_WORK_ITEM WorkItem; } EUID_NODE_MAC_TABLE_WORKITEM, *PEUID_NODE_MAC_TABLE_WORKITEM; typedef struct _ARP1394_WORK_ITEM ARP1394_WORK_ITEM, *PARP1394_WORK_ITEM; typedef NDIS_STATUS (*ARP_WORK_ITEM_PROC)( struct _ARP1394_WORK_ITEM*, PRM_OBJECT_HEADER, PRM_STACK_RECORD ); typedef struct _ARP1394_WORK_ITEM { union { EUID_TOPOLOGY Euid; NDIS_WORK_ITEM NdisWorkItem; } u; ARP_WORK_ITEM_PROC pFunc; } ARP1394_WORK_ITEM, *PARP1394_WORK_ITEM; // Structure to express the information carried in an IP header typedef struct _ARP_IP_HEADER_INFO { UCHAR protocol; IP_ADDRESS ipSource, ipTarget; USHORT headerSize; ULONG IpHeaderOffset; ULONG IpPktLength; } ARP_IP_HEADER_INFO, *PARP_IP_HEADER_INFO; //========================================================================= // I N T E R N A L P R O T O T Y P E S //========================================================================= NTSTATUS ArpDeviceIoControl( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ); NTSTATUS ArpWmiDispatch( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ); NTSTATUS ArpHandleIoctlRequest( IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpSp ); NDIS_STATUS arpCfgGetInterfaceConfiguration( IN ARP1394_INTERFACE * pIF, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpCfgReadAdapterConfiguration( IN ARP1394_ADAPTER * pAdapter, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpCfgReadInterfaceConfiguration( IN NDIS_HANDLE InterfaceConfigHandle, IN ARP1394_INTERFACE * pF, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpAllocateTask( IN PRM_OBJECT_HEADER pParentObject, IN PFN_RM_TASK_HANDLER pfnHandler, IN UINT Timeout, IN const char * szDescription, OPTIONAL OUT PRM_TASK *ppTask, IN PRM_STACK_RECORD pSR ); VOID arpFreeTask( IN PRM_TASK pTask, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskInitInterface( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskDeinitInterface( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskReinitInterface( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskActivateInterface( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskDeactivateInterface( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskMakeRecvFifoCall( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskCleanupRecvFifoCall( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskMakeCallToDest( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskCleanupCallToDest( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskResolveIpAddress( IN struct _RM_TASK * pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); PRM_OBJECT_HEADER arpAdapterCreate( PRM_OBJECT_HEADER pParentObject, PVOID pCreateParams, PRM_STACK_RECORD psr ); VOID arpDeinitIf( PARP1394_INTERFACE pIF, PRM_TASK pCallingTask, // OPTIONAL UINT SuspendCode, // OPTIONAL PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskUnloadLocalIp( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskUnloadRemoteIp( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskUnloadRemoteEth( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskUnloadDestination( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); VOID arpObjectDelete ( PRM_OBJECT_HEADER pObj, PRM_STACK_RECORD psr ); VOID arpAdapterDelete ( PRM_OBJECT_HEADER pObj, PRM_STACK_RECORD psr ); NDIS_STATUS arpCopyUnicodeString( OUT PNDIS_STRING pDest, IN PNDIS_STRING pSrc, BOOLEAN fUpCase ); NDIS_STATUS arpTaskInitializeAdapter( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskShutdownAdapter( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskActivateAdapter( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskDeactivateAdapter( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskInterfaceTimer( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskInterfaceTimer( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); #if TEST_ICS_HACK NDIS_STATUS arpTaskDoIcsTest( IN struct _RM_TASK * pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); #endif // TEST_ICS_HACK NDIS_STATUS arpTaskIfMaintenance( IN struct _RM_TASK * pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpInitializeConstBufferPool( IN UINT NumBuffersToCache, IN UINT MaxBuffers, IN const VOID* pvMem, IN UINT cbMem, IN PRM_OBJECT_HEADER pOwningObject, IN OUT ARP_CONST_BUFFER_POOL * pHdrPool, IN PRM_STACK_RECORD pSR ); VOID arpDeinitializeConstBufferPool( IN ARP_CONST_BUFFER_POOL * pHdrPool, IN PRM_STACK_RECORD pSR ); PNDIS_BUFFER arpAllocateConstBuffer( ARP_CONST_BUFFER_POOL * pHdrPool ); VOID arpDeallocateConstBuffer( ARP_CONST_BUFFER_POOL * pHdrPool, PNDIS_BUFFER pNdisBuffer ); VOID arpCompleteSentPkt( IN NDIS_STATUS Status, IN ARP1394_INTERFACE * pIF, IN ARPCB_DEST * pDest, IN PNDIS_PACKET pNdisPacket ); NDIS_STATUS arpParseArpPkt( IN PIP1394_ARP_PKT pArpPkt, IN UINT cbBufferSize, OUT PIP1394_ARP_PKT_INFO pPktInfo ); VOID arpPrepareArpPkt( IN PIP1394_ARP_PKT_INFO pArpPktInfo, // IN UINT SenderMaxRec, OUT PIP1394_ARP_PKT pArpPkt ); NDIS_STATUS arpPrepareArpResponse( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IN PIP1394_ARP_PKT_INFO pArpRequest, OUT PIP1394_ARP_PKT_INFO pArpResponse, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpAddOneStaticArpEntry( IN PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT IN IP_ADDRESS IpAddress, IN PNIC1394_FIFO_ADDRESS pFifoAddr, IN PRM_STACK_RECORD pSR ); VOID arpSetPrimaryIfTask( PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT PRM_TASK pTask, ULONG PrimaryState, PRM_STACK_RECORD pSR ); VOID arpClearPrimaryIfTask( PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT PRM_TASK pTask, ULONG PrimaryState, PRM_STACK_RECORD pSR ); VOID arpSetSecondaryIfTask( PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT PRM_TASK pTask, ULONG SecondaryState, PRM_STACK_RECORD pSR ); VOID arpClearSecondaryIfTask( PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT PRM_TASK pTask, ULONG SecondaryState, PRM_STACK_RECORD pSR ); VOID arpSetPrimaryAdapterTask( PARP1394_ADAPTER pAdapter, // LOCKIN LOCKOUT PRM_TASK pTask, ULONG PrimaryState, PRM_STACK_RECORD pSR ); VOID arpClearPrimaryAdapterTask( PARP1394_ADAPTER pAdapter, // LOCKIN LOCKOUT PRM_TASK pTask, ULONG PrimaryState, PRM_STACK_RECORD pSR ); VOID arpSetSecondaryAdapterTask( PARP1394_ADAPTER pAdapter, // LOCKIN LOCKOUT PRM_TASK pTask, ULONG SecondaryState, PRM_STACK_RECORD pSR ); VOID arpClearSecondaryAdapterTask( PARP1394_ADAPTER pAdapter, // LOCKIN LOCKOUT PRM_TASK pTask, ULONG SecondaryState, PRM_STACK_RECORD pSR ); NDIS_STATUS arpTryReconfigureIf( PARP1394_INTERFACE pIF, PNET_PNP_EVENT pNetPnPEvent, PRM_STACK_RECORD pSR ); VOID arpResetIfStats( IN PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT IN PRM_STACK_RECORD pSR ); VOID arpGetPktCountBins( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IN PNDIS_PACKET pNdisPacket, OUT PULONG pSizeBin, OUT PULONG pTimeBin ); VOID arpLogSendFifoCounts( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IN PNDIS_PACKET pNdisPacket, IN NDIS_STATUS Status ); VOID arpLogRecvFifoCounts( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IN PNDIS_PACKET pNdisPacket ); VOID arpLogSendChannelCounts( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IN PNDIS_PACKET pNdisPacket, IN NDIS_STATUS Status ); VOID arpLogRecvChannelCounts( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IN PNDIS_PACKET pNdisPacket ); NDIS_STATUS arpInitializeVc( PARP1394_INTERFACE pIF, PARP_STATIC_VC_INFO pVcInfo, PRM_OBJECT_HEADER pOwner, PARP_VC_HEADER pVcHdr, PRM_STACK_RECORD pSR ); VOID arpDeinitializeVc( PARP1394_INTERFACE pIF, PARP_VC_HEADER pVcHdr, PRM_OBJECT_HEADER pOwner, // NOLOCKIN NOLOCKOUT PRM_STACK_RECORD pSR ); NDIS_STATUS arpAllocateControlPacketPool( PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT UINT MaxBufferSize, PRM_STACK_RECORD pSR ); VOID arpFreeControlPacketPool( PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT PRM_STACK_RECORD pSR ); NDIS_STATUS arpAllocateControlPacket( IN PARP1394_INTERFACE pIF, IN UINT cbBufferSize, IN UINT PktFlags, OUT PNDIS_PACKET *ppNdisPacket, OUT PVOID *ppvData, PRM_STACK_RECORD pSR ); VOID arpFreeControlPacket( PARP1394_INTERFACE pIF, PNDIS_PACKET pNdisPacket, PRM_STACK_RECORD pSR ); VOID arpRefSendPkt( PNDIS_PACKET pNdisPacket, PARPCB_DEST pDest ); VOID arpProcessArpPkt( PARP1394_INTERFACE pIF, PIP1394_ARP_PKT pArpPkt, UINT cbBufferSize ); VOID arpProcessMcapPkt( PARP1394_INTERFACE pIF, PIP1394_MCAP_PKT pMcapPkt, UINT cbBufferSize ); VOID arpLinkRemoteIpToDest( ARPCB_REMOTE_IP *pRemoteIp, ARPCB_DEST *pDest, PRM_STACK_RECORD pSR ); VOID arpUnlinkRemoteIpFromDest( ARPCB_REMOTE_IP *pRemoteIp, // LOCKIN LOCKOUT PRM_STACK_RECORD pSR ); VOID arpUnlinkAllRemoteIpsFromDest( ARPCB_DEST *pDest, // LOCKIN LOCKOUT PRM_STACK_RECORD pSR ); VOID arpLinkLocalIpToDest( ARPCB_LOCAL_IP * pLocalIp, ARPCB_DEST *pDest, PRM_STACK_RECORD pSR ); VOID arpUnlinkLocalIpFromDest( ARPCB_LOCAL_IP *pLocalIp, // LOCKIN LOCKOUT PRM_STACK_RECORD pSR ); VOID arpUnlinkAllLocalIpsFromDest( ARPCB_DEST *pDest, // LOCKIN LOCKOUT PRM_STACK_RECORD pSR ); #if 0 NDIS_STATUS arpCopyAnsiStringToUnicodeString( OUT PNDIS_STRING pDest, IN PANSI_STRING pSrc ); NDIS_STATUS arpCopyUnicodeStringToAnsiString( OUT PANSI_STRING pDest, IN PNDIS_STRING pSrc ); #endif // 0 VOID arpUpdateReceiveMultichannels( PARP1394_INTERFACE pIF, UINT SecondsSinceLastCall, PRM_STACK_RECORD pSR ); NDIS_STATUS arpPrepareAndSendNdisRequest( IN PARP1394_ADAPTER pAdapter, IN PARP_NDIS_REQUEST pArpNdisRequest, IN PRM_TASK pTask, // OPTIONAL IN UINT PendCode, IN NDIS_OID Oid, IN PVOID pBuffer, IN ULONG BufferLength, IN NDIS_REQUEST_TYPE RequestType, IN PRM_STACK_RECORD pSR ); typedef enum { ARP_ICS_FORWARD_TO_1394, ARP_ICS_FORWARD_TO_ETHERNET, } ARP_ICS_FORWARD_DIRECTION; #if TEST_ICS_HACK VOID arpEthSendComplete( IN ARP1394_ADAPTER * pAdapter, IN PNDIS_PACKET pNdisPacket, IN NDIS_STATUS Status ); NDIS_STATUS arpEthReceive( ARP1394_ADAPTER * pAdapter, NDIS_HANDLE Context, VOID *Header, UINT HeaderSize, VOID *Data, UINT Size, UINT TotalSize ); #endif // TEST_ICS_HACK VOID arpEthReceivePacket( ARP1394_INTERFACE * pIF, PNDIS_PACKET Packet ); NDIS_STATUS arpAllocateEthernetPools( IN PARP1394_INTERFACE pIF, IN PRM_STACK_RECORD pSR ); VOID arpFreeEthernetPools( IN PARP1394_INTERFACE pIF, IN PRM_STACK_RECORD pSR ); #if TEST_ICS_HACK VOID arpDbgStartIcsTest( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT PRM_STACK_RECORD pSR ); VOID arpDbgTryStopIcsTest( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT PRM_STACK_RECORD pSR ); #endif // TEST_ICS_HACK VOID arpDbgIncrementReentrancy( PLONG pReentrancyCount ); VOID arpDbgDecrementReentrancy( PLONG pReentrancyCount ); VOID arpHandleControlPktSendCompletion( IN ARP1394_INTERFACE * pIF, IN PNDIS_PACKET pNdisPacket ); VOID arpStartIfMaintenanceTask( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT PRM_STACK_RECORD pSR ); NDIS_STATUS arpTryStopIfMaintenanceTask( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IN PRM_TASK pTask, // task to pend until M task completes IN UINT PendCode, // Pend code to suspend task. PRM_STACK_RECORD pSR ); UINT arpGetSystemTime(VOID); BOOLEAN arpCanTryMcap( IP_ADDRESS IpAddress ); UINT arpFindAssignedChannel( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IN IP_ADDRESS IpAddress, IN UINT CurrentTime, PRM_STACK_RECORD pSR ); VOID arpUpdateRemoteIpDest( IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IN PARPCB_REMOTE_IP pRemoteIp, IN PARP_DEST_PARAMS pDestParams, PRM_STACK_RECORD pSR ); MYBOOL arpIsActiveMcapChannel( PMCAP_CHANNEL_INFO pMci, UINT CurrentTime ); VOID arpSendControlPkt( IN ARP1394_INTERFACE * pIF, // LOCKIN NOLOCKOUT (IF send lk) IN PNDIS_PACKET pNdisPacket, IN PARPCB_DEST pDest, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpCreateMcapPkt( IN PARP1394_INTERFACE pIF, IN PIP1394_MCAP_PKT_INFO pPktInfo, OUT PNDIS_PACKET *ppNdisPacket, PRM_STACK_RECORD pSR ); UINT arpProcessReceivedPacket( IN PARP1394_INTERFACE pIF, IN PNDIS_PACKET pNdisPacket, IN MYBOOL IsChannel ); VOID arpUpdateArpCache( PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT IP_ADDRESS RemoteIpAddress, ENetAddr *pRemoteEthAddress, PARP_DEST_PARAMS pDestParams, MYBOOL fCreateIfRequired, PRM_STACK_RECORD pSR ); UINT arpEthernetReceivePacket( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE ProtocolVcContext, IN PNDIS_PACKET pNdisPacket ); VOID arpEthReceive1394Packet( IN PARP1394_INTERFACE pIF, IN PNDIS_PACKET pNdisPacket, IN PVOID pvHeader, IN UINT HeaderSize, IN MYBOOL IsChannel ); NDIS_STATUS arpSlowIpTransmit( IN ARP1394_INTERFACE * pIF, IN PNDIS_PACKET pNdisPacket, IN REMOTE_DEST_KEY Destination, IN RouteCacheEntry * pRCE OPTIONAL ); VOID arpDelRceList( IN PARPCB_REMOTE_IP pRemoteIp, // IF send lock WRITELOCKIN WRITELOCKOUTD IN PRM_STACK_RECORD pSR ); VOID arpGenericWorkItem( struct _NDIS_WORK_ITEM * pWorkItem, PVOID pContext ); VOID arpQueueWorkItem ( PARP1394_WORK_ITEM pWorkItem, ARP_WORK_ITEM_PROC pFunc, PRM_OBJECT_HEADER pHdr, PRM_STACK_RECORD pSR ); NDIS_STATUS arpGetEuidTopology ( IN PARP1394_ADAPTER pAdapter, PRM_STACK_RECORD pSR ); VOID arpNdProcessBusReset( IN PARP1394_ADAPTER pAdapter ); NDIS_STATUS arpAddIpAddressToRemoteIp ( PARPCB_REMOTE_IP pRemoteIp, PNDIS_PACKET pNdisPacket ); VOID arpReturnBackupTask ( IN ARP1394_TASK* pTask ); VOID arpAllocateBackupTasks ( ARP1394_GLOBALS* pGlobals ); VOID arpFreeBackupTasks ( ARP1394_GLOBALS* pGlobals ); ARP1394_TASK * arpGetBackupTask ( IN ARP1394_GLOBALS* pGlobals ); NTSTATUS arpDelArpEntry( PARP1394_INTERFACE pIF, IPAddr IpAddress, PRM_STACK_RECORD pSR ); VOID arpAddBackupTasks ( IN ARP1394_GLOBALS* pGlobals, UINT Num ); VOID arpRemoveBackupTasks ( IN ARP1394_GLOBALS* pGlobals, UINT Num ); MYBOOL arpNeedToCleanupDestVc( ARPCB_DEST *pDest // LOCKING LOCKOUT ); VOID arpLowPowerCloseAllCalls ( ARP1394_INTERFACE *pIF, PRM_STACK_RECORD pSR ); VOID arpDeactivateIf( PARP1394_INTERFACE pIF, PRM_TASK pCallingTask, // OPTIONAL UINT SuspendCode, // OPTIONAL PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskLowPower( IN struct _RM_TASK * pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpSetupSpecialDest( IN PARP1394_INTERFACE pIF, IN NIC1394_ADDRESS_TYPE AddressType, IN PRM_TASK pParentTask, IN UINT PendCode, OUT PARPCB_DEST * ppSpecialDest, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpResume ( IN ARP1394_ADAPTER* pAdapter, IN ARP_RESUME_CAUSE Cause, IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpTaskOnPower ( IN PRM_TASK pTask, IN RM_TASK_OPERATION Code, IN UINT_PTR UserParam, // Unused IN PRM_STACK_RECORD pSR ); NDIS_STATUS arpMakeCallOnDest( IN PARPCB_REMOTE_IP pRemoteIp, IN PARPCB_DEST pDest, IN PRM_TASK pTaskToPend, IN ULONG PEND_StageMakeCallComplete, IN PRM_STACK_RECORD pSR ); //========================================================================= // G L O B A L D A T A //========================================================================= extern RM_STATIC_OBJECT_INFO ArpGlobals_AdapterStaticInfo; extern const NIC1394_ENCAPSULATION_HEADER Arp1394_IpEncapHeader; // Warning -- FAIL(NDIS_STATUS_PENDING) == TRUE // #define FAIL(_Status) ((_Status) != NDIS_STATUS_SUCCESS) #define PEND(_Status) ((_Status) == NDIS_STATUS_PENDING) #if RM_EXTRA_CHECKING #define LOCKHDR(_pHdr, _psr) \ RmWriteLockObject((_pHdr), dbg_func_locid, (_psr)) #else // !RM_EXTRA_CHECKING #define LOCKHDR(_pHdr, _psr) \ RmWriteLockObject((_pHdr), (_psr)) #endif // !RM_EXTRA_CHECKING #define LOCKOBJ(_pObj, _psr) \ LOCKHDR(&(_pObj)->Hdr, (_psr)) #define UNLOCKHDR(_pHdr, _psr) \ RmUnlockObject((_pHdr), (_psr)) #define UNLOCKOBJ(_pObj, _psr) \ UNLOCKHDR(&(_pObj)->Hdr, (_psr)) #define ARP_ALLOCSTRUCT(_p, _tag) \ NdisAllocateMemoryWithTag(&(_p), sizeof(*(_p)), (_tag)) #define ARP_FREE(_p) NdisFreeMemory((_p), 0, 0) #define ARP_ZEROSTRUCT(_p) \ NdisZeroMemory((_p), sizeof(*(_p))) #define ARRAY_LENGTH(_array) (sizeof(_array)/sizeof((_array)[0])) #if RM_EXTRA_CHECKING #define DBG_ADDASSOC(_phdr, _e1, _e2, _assoc, _fmt, _psr)\ RmDbgAddAssociation( \ dbg_func_locid, \ (_phdr), \ (UINT_PTR) (_e1), \ (UINT_PTR) (_e2), \ (_assoc), \ (_fmt), \ (_psr) \ ) #define DBG_DELASSOC(_phdr, _e1, _e2, _assoc, _psr) \ RmDbgDeleteAssociation( \ dbg_func_locid, \ (_phdr), \ (UINT_PTR) (_e1), \ (UINT_PTR) (_e2), \ (_assoc), \ (_psr) \ ) // (debug only) Enumeration of types of associations. // enum { ARPASSOC_IP_OPEN, // IP has called ArpIpOpen ARPASSOC_LINK_IPADDR_OF_DEST, ARPASSOC_LINK_DEST_OF_IPADDR, ARPASSOC_LOCALIP_UNLOAD_TASK, ARPASSOC_REMOTEIP_UNLOAD_TASK, ARPASSOC_REMOTEETH_UNLOAD_TASK, ARPASSOC_DEST_UNLOAD_TASK, ARPASSOC_CBUFPOOL_ALLOC, ARPASSOC_EXTLINK_DEST_TO_PKT, ARPASSOC_EXTLINK_RIP_TO_RCE, ARPASSOC_EXTLINK_TO_NDISVCHANDLE, ARPASSOC_REMOTEIP_SENDPKTS_TASK, ARPASSOC_IF_MAKECALL_TASK, ARPASSOC_IF_CLEANUPCALL_TASK, ARPASSOC_DEST_MAKECALL_TASK, ARPASSOC_DEST_CLEANUPCALL_TASK, ARPASSOC_DEST_CLEANUPCALLTASK_WAITING_ON_SENDS, ARPASSOC_PKTS_QUEUED_ON_REMOTEIP, ARPASSOC_PRIMARY_IF_TASK, ARPASSOC_ACTDEACT_IF_TASK, ARPASSOC_IF_OPENAF, ARPASSOC_PRIMARY_AD_TASK, ARPASSOC_ACTDEACT_AD_TASK, ARPASSOC_LINK_IF_OF_BCDEST, ARPASSOC_LINK_BCDEST_OF_IF, ARPASSOC_IF_PROTOPKTPOOL, ARPASSOC_IF_PROTOBUFPOOL, ARPASSOC_RESOLUTION_IF_TASK, ARPASSOC_LINK_IF_OF_MCDEST, ARPASSOC_LINK_MCDEST_OF_IF, ARPASSOC_LINK_IF_OF_ETHDEST, ARPASSOC_LINK_ETHDEST_OF_IF, ARPASSOC_IF_ETHPKTPOOL, ARPASSOC_IF_ETHBUFPOOL, ARPASSOC_ETH_SEND_PACKET, ARPASSOC_IF_MAINTENANCE_TASK, ARPASSOC_WORK_ITEM, ARPASSOC_ETHDHCP_UNLOAD_TASK, ARPASSOC_REMOTEIP_RESOLVE_TASK, ARPASSOC_TASK_TO_RESOLVE_REMOTEIP }; #else // !RM_EXTRA_CHECKING #define DBG_ADDASSOC(_phdr, _e1, _e2, _assoc, _fmt, _psr) (0) #define DBG_DELASSOC(_phdr, _e1, _e2, _assoc, _psr) (0) #endif // !RM_EXTRA_CHECKING #define ARPDBG_REF_EVERY_PACKET 1 #define ARPDBG_REF_EVERY_RCE 1 // USHORT // SWAPBYTES_USHORT(USHORT Val ) // #define SWAPBYTES_USHORT(Val) \ ((((Val) & 0xff) << 8) | (((Val) & 0xff00) >> 8)) // ULONG // SWAPBYTES_ULONG(ULONG Val ) // #define SWAPBYTES_ULONG(Val) \ ((((Val) & 0x000000ff) << 24) | \ (((Val) & 0x0000ff00) << 8) | \ (((Val) & 0x00ff0000) >> 8) | \ (((Val) & 0xff000000) >> 24) ) #define N2H_USHORT(Val) SWAPBYTES_USHORT(Val) #define H2N_USHORT(Val) SWAPBYTES_USHORT(Val) #define N2H_ULONG(Val) SWAPBYTES_ULONG(Val) #define H2N_ULONG(Val) SWAPBYTES_ULONG(Val) #define ARP_ATPASSIVE() (KeGetCurrentIrql()==PASSIVE_LEVEL) #define LOGSTATS_NoCopyRecvs(_pIF, _pNdisPacket) \ NdisInterlockedIncrement(&((_pIF)->stats.recvpkts.NoCopyRecvs)) #define LOGSTATS_CopyRecvs(_pIF, _pNdisPacket) \ NdisInterlockedIncrement(&((_pIF)->stats.recvpkts.CopyRecvs)) #define LOGSTATS_ResourceRecvs(_pIF, _pNdisPacket) \ NdisInterlockedIncrement(&((_pIF)->stats.recvpkts.ResourceRecvs)) #define LOGSTATS_TotRecvs(_pIF, _pNdisPacket) \ NdisInterlockedIncrement(&((_pIF)->stats.recvpkts.TotRecvs)) #define LOGSTATS_RecvFifoCounts(_pIF, _pNdisPacket) \ arpLogRecvFifoCounts(_pIF, _pNdisPacket) #define LOGSTATS_RecvChannelCounts(_pIF, _pNdisPacket) \ arpLogRecvChannelCounts(_pIF, _pNdisPacket) #define LOGSTATS_TotalSendFifoMakeCalls(_pIF) \ NdisInterlockedIncrement(&((_pIF)->stats.calls.TotalSendFifoMakeCalls)) #define LOGSTATS_SuccessfulSendFifoMakeCalls(_pIF) \ NdisInterlockedIncrement(&((_pIF)->stats.calls.SuccessfulSendFifoMakeCalls)) #define LOGSTATS_FailedSendFifoMakeCalls(_pIF) \ NdisInterlockedIncrement(&((_pIF)->stats.calls.FailedSendFifoMakeCalls)) #define LOGSTATS_IncomingClosesOnSendFifos(_pIF) \ NdisInterlockedIncrement(&((_pIF)->stats.calls.IncomingClosesOnSendFifos)) #define LOGSTATS_TotalChannelMakeCalls(_pIF) \ NdisInterlockedIncrement(&((_pIF)->stats.calls.TotalChannelMakeCalls)) #define LOGSTATS_SuccessfulChannelMakeCalls(_pIF) \ NdisInterlockedIncrement(&((_pIF)->stats.calls.SuccessfulChannelMakeCalls)) #define LOGSTATS_FailedChannelMakeCalls(_pIF) \ NdisInterlockedIncrement(&((_pIF)->stats.calls.FailedChannelMakeCalls)) #define LOGSTATS_IncomingClosesOnChannels(_pIF) \ NdisInterlockedIncrement(&((_pIF)->stats.calls.IncomingClosesOnChannels)) #define IF_FROM_LOCALIP(_pLIp) \ (PARP1394_INTERFACE) RM_PARENT_OBJECT(_pLIp) #define IF_FROM_REMOTEIP(_pRIp) \ (PARP1394_INTERFACE) RM_PARENT_OBJECT(_pRIp) #define IF_FROM_DEST(_pDest) \ (PARP1394_INTERFACE) RM_PARENT_OBJECT(_pDest) #if RM_EXTRA_CHECKING #define OBJLOG0(_pObj, _szFmt) \ RmDbgLogToObject( \ &(_pObj)->Hdr, \ NULL, (_szFmt), \ 0, 0, 0, 0, NULL, NULL \ ) #define OBJLOG1(_pObj, _szFmt, _P1) \ RmDbgLogToObject( \ &(_pObj)->Hdr, \ NULL, (_szFmt), \ (UINT_PTR) (_P1), \ 0, 0, 0, NULL, NULL \ ) #define OBJLOG2(_pObj, _szFmt, _P1, _P2) \ RmDbgLogToObject( \ &(_pObj)->Hdr, \ NULL, (_szFmt), \ (UINT_PTR) (_P1), \ (UINT_PTR) (_P2), \ 0, 0, NULL, NULL \ ) #else // !RM_EXTRA_CHECKING #define OBJLOG0(_pObj, _szFmt) (0) #define OBJLOG1(_pObj, _szFmt, _P1) (0) #define OBJLOG2(_pObj, _szFmt, _P1, _P2) (0) #endif // !RM_EXTRA_CHECKING #if ARP_DO_TIMESTAMPS void arpTimeStamp( char *szFormatString, UINT Val ); #define TIMESTAMPX(_FormatString) \ arpTimeStamp("TIMESTAMP %lu:%lu.%lu ARP1394 " _FormatString "\n", 0) #if ARP_DO_ALL_TIMESTAMPS #define TIMESTAMP(_FormatString) \ arpTimeStamp("TIMESTAMP %lu:%lu.%lu ARP1394 " _FormatString "\n", 0) #define TIMESTAMP1(_FormatString, _Val) \ arpTimeStamp("TIMESTAMP %lu:%lu.%lu ARP1394 " _FormatString "\n", (_Val)) #else #define TIMESTAMP(_FormatString) #define TIMESTAMP1(_FormatString, _Val) #endif #else // !ARP_DO_TIMESTAMPS #define TIMESTAMP(_FormatString) #define TIMESTAMPX(_FormatString) #define TIMESTAMP1(_FormatString, _Val) #endif // !ARP_DO_TIMESTAMPS