summaryrefslogblamecommitdiffstats
path: root/private/ntos/tdi/st/stmac.c
blob: 157c96a173342ef75c2a7c1988657dc8d1a8163f (plain) (tree)



































































































































































































































































































































































                                                                                     
/*++

Copyright (c) 1989-1993  Microsoft Corporation

Module Name:

    nbfmac.c

Abstract:

    This module contains code which implements Mac type dependent code for
    the ST transport.

Environment:

    Kernel mode (Actually, unimportant)

Revision History:

--*/

#include "st.h"

UCHAR SingleRouteSourceRouting[] = { 0xc2, 0x70 };
UCHAR GeneralRouteSourceRouting[] = { 0x82, 0x70 };
ULONG DefaultSourceRoutingLength = 2;

VOID
MacInitializeMacInfo(
    IN NDIS_MEDIUM MacType,
    OUT PST_NDIS_IDENTIFICATION MacInfo
    );

//
// This is the interpretation of the length bits in
// the 802.5 source-routing information.
//

ULONG SR802_5Lengths[8] = {  516,  1500,  2052,  4472,
                            8144, 11407, 17800, 17800 };


#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,MacInitializeMacInfo)
#pragma alloc_text(INIT,MacSetMulticastAddress)
#endif



VOID
MacInitializeMacInfo(
    IN NDIS_MEDIUM MacType,
    OUT PST_NDIS_IDENTIFICATION MacInfo
    )

/*++

Routine Description:

    Fills in the MacInfo table based on MacType.

Arguments:

    MacType - The MAC type we wish to decode.

    MacInfo - The MacInfo structure to fill in.

Return Value:

    None.

--*/

{
    switch (MacType) {
    case NdisMedium802_3:
        MacInfo->DestinationOffset = 0;
        MacInfo->SourceOffset = 6;
        MacInfo->SourceRouting = FALSE;
        MacInfo->AddressLength = 6;
        MacInfo->MaxHeaderLength = 14;
        MacInfo->MediumType = NdisMedium802_3;
        break;
    case NdisMedium802_5:
        MacInfo->DestinationOffset = 2;
        MacInfo->SourceOffset = 8;
        MacInfo->SourceRouting = TRUE;
        MacInfo->AddressLength = 6;
        MacInfo->MaxHeaderLength = 32;
        MacInfo->MediumType = NdisMedium802_5;
        break;
    case NdisMediumFddi:
        MacInfo->DestinationOffset = 1;
        MacInfo->SourceOffset = 7;
        MacInfo->SourceRouting = FALSE;
        MacInfo->AddressLength = 6;
        MacInfo->MaxHeaderLength = 13;
        MacInfo->MediumType = NdisMediumFddi;
        break;
    default:
        ASSERT(FALSE);
    }
}

VOID
MacConstructHeader (
    IN PST_NDIS_IDENTIFICATION MacInfo,
    IN PUCHAR Buffer,
    IN PUCHAR DestinationAddress,
    IN PUCHAR SourceAddress,
    IN UINT PacketLength,
    IN PUCHAR SourceRouting,
    IN UINT SourceRoutingLength,
    OUT PUINT HeaderLength
    )

/*++

Routine Description:

    This routine is called to construct the Mac header for the particular
    network type we're talking to.

Arguments:

    MacInfo - Describes the mac we wish to build a header for.

    Buffer - Where to build the header.

    DestinationAddress - the address this packet is to be sent to.

    SourceAddress - Our address. Passing it in as a parameter allows us to play
            games with source if we need to.

    PacketLength - The length of this packet. Note that this does not
            includes the Mac header.

    SourceRouting - Optional source routing information.

    SourceRoutingLength - The length of SourceRouting.

    HeaderLength - Returns the length of the constructed header.

Return Value:

    None.

--*/
{
    //
    // Note network order of bytes.
    //

    switch (MacInfo->MediumType) {

    case NdisMedium802_3:

        *(ULONG UNALIGNED *)&Buffer[6] = *(ULONG UNALIGNED *)&SourceAddress[0];
        Buffer[10] = SourceAddress[4];
        Buffer[11] = SourceAddress[5];

        *(ULONG UNALIGNED *)&Buffer[0] = *(ULONG UNALIGNED *)&DestinationAddress[0];
        Buffer[4] = DestinationAddress[4];
        Buffer[5] = DestinationAddress[5];

        Buffer[12] = (UCHAR)(PacketLength >> 8);
        Buffer[13] = (UCHAR)PacketLength;

        *HeaderLength = 14;

        break;

    case NdisMedium802_5:

        Buffer[0] = TR_HEADER_BYTE_0;
        Buffer[1] = TR_HEADER_BYTE_1;

        ASSERT (TR_ADDRESS_LENGTH == 6);

        *(ULONG UNALIGNED *)&Buffer[8] = *(ULONG UNALIGNED *)&SourceAddress[0];
        Buffer[12] = SourceAddress[4];
        Buffer[13] = SourceAddress[5];

        *(ULONG UNALIGNED *)&Buffer[2] = *(ULONG UNALIGNED *)&DestinationAddress[0];
        Buffer[6] = DestinationAddress[4];
        Buffer[7] = DestinationAddress[5];

        *HeaderLength = 14;
        if (SourceRouting != NULL) {
            RtlCopyMemory (&Buffer[14], SourceRouting, SourceRoutingLength);
            Buffer[8] |= 0x80;           // add SR bit in source address
            *HeaderLength = 14 + SourceRoutingLength;
        }

        break;

    case NdisMediumFddi:

        Buffer[0] = FDDI_HEADER_BYTE;

        *(ULONG UNALIGNED *)&Buffer[7] = *(ULONG UNALIGNED *)&SourceAddress[0];
        Buffer[11] = SourceAddress[4];
        Buffer[12] = SourceAddress[5];

        *(ULONG UNALIGNED *)&Buffer[1] = *(ULONG UNALIGNED *)&DestinationAddress[0];
        Buffer[5] = DestinationAddress[4];
        Buffer[6] = DestinationAddress[5];

        *HeaderLength = 13;

        break;

    default:
        PANIC ("MacConstructHeader: PANIC! called with unsupported Mac type.\n");
    }
}


VOID
MacReturnMaxDataSize(
    IN PST_NDIS_IDENTIFICATION MacInfo,
    IN PUCHAR SourceRouting,
    IN UINT SourceRoutingLength,
    IN UINT DeviceMaxFrameSize,
    OUT PUINT MaxFrameSize
    )

/*++

Routine Description:

    This routine returns the space available for user data in a MAC packet.
    This will be the available space after the MAC header; all headers
    headers will be included in this space.

Arguments:

    MacInfo - Describes the MAC we wish to decode.

    SourceRouting - If we are concerned about a reply to a specific
        frame, then this information is used.

    SourceRouting - The length of SourceRouting.

    MaxFrameSize - The maximum frame size as returned by the adapter.

    MaxDataSize - The maximum data size computed.

Return Value:

    None.

--*/

{
    switch (MacInfo->MediumType) {

    case NdisMedium802_3:

        //
        // For 802.3, we always have a 14-byte MAC header.
        //

        *MaxFrameSize = DeviceMaxFrameSize - 14;
        break;

    case NdisMedium802_5:

        //
        // For 802.5, if we have source routing information then
        // use that, otherwise assume the worst.
        //

        if (SourceRouting && SourceRoutingLength >= 2) {

            UINT SRLength;

            SRLength = SR802_5Lengths[(SourceRouting[1] & 0x70) >> 4];
            DeviceMaxFrameSize -= (SourceRoutingLength + 14);

            if (DeviceMaxFrameSize < SRLength) {
                *MaxFrameSize = DeviceMaxFrameSize;
            } else {
                *MaxFrameSize = SRLength;
            }

        } else {

            if (DeviceMaxFrameSize < 548) {
                *MaxFrameSize = DeviceMaxFrameSize - 32;
            } else {
                *MaxFrameSize = 516;
            }
        }

        break;

    case NdisMediumFddi:

        //
        // For FDDI, we always have a 13-byte MAC header.
        //

        *MaxFrameSize = DeviceMaxFrameSize - 13;
        break;

    }
}



VOID
MacSetMulticastAddress (
    IN NDIS_MEDIUM Type,
    IN PUCHAR Buffer
    )
/*++

Routine Description:

    This routine sets the multicast address into a buffer provided
    by the user.

Arguments:

    Type the Mac Medium type.

    Buffer the buffer to put the multicast address in.


Return Value:

    none.

--*/
{
    switch (Type) {
    case NdisMedium802_3:
    case NdisMediumFddi:
        Buffer[0] = 0x03;
        Buffer[1] = 0x07;
        Buffer[2] = 0x03;
        Buffer[3] = 0x07;
        Buffer[4] = 0x03;
        Buffer[5] = 0x07;
        break;

    case NdisMedium802_5:
        Buffer[0] = 0xc0;
        Buffer[3] = 0x20;
        break;

    default:
        PANIC ("MacSetMulticastAddress: PANIC! called with unsupported Mac type.\n");
    }
}