/*++

*****************************************************************************
*                                                                           *
*  This software contains proprietary and confiential information of        *
*                                                                           *
*                    Digi International Inc.                                *
*                                                                           *
*  By accepting transfer of this copy, Recipient agrees to retain this      *
*  software in confidence, to prevent disclosure to others, and to make     *
*  no use of this software other than that for which it was delivered.      *
*  This is an unpublished copyrighted work of Digi International Inc.       *
*  Except as permitted by federal law, 17 USC 117, copying is strictly      *
*  prohibited.                                                              *
*                                                                           *
*****************************************************************************

Module Name:

   lanoid.c

Abstract:


Revision History:

   $Log: /Components/Windows/NT/Sync/Wan/LANOID.C $
 * 
 * 4     4/28/97 1:54p Mikez
 * Updated to use DsApi library.  Uses IoBuildDeviceIoControlRequest to
 * alloc Irps causing two problems.  Because ioctls are METHOD_BUFFERED, a
 * systemBuffer is alloc'd, but, because the completionroutines return
 * STATUS_MORE_PROCESSING_REQUIRED, never gets freed.  Also, SystemBuffer
 * is not copied to OutputBuffer until after completionRoutine returns
 * STATUS_SUCCESS.  Need to move from METHOD_BUFFER or from using
 * IoBuildDeviceIoControlRequest.
 * 
 * 3     12/06/96 2:28p Mikez
 * Modified to support new SXB paridigm of "one NT device per adapter"
 * rather than the older "one NT device per port".
 * 
 * 2     10/28/96 1:25p Mikez
 * Updated to support latest firmware release, v1.1.2b.
 * 
 * 1     3/11/96 5:06p Mikez
 * Revision 1.4  1995/10/06  06:59:55  Craig_Harrison
 * Version 1.0.1.2 
 * 
 * Revision 1.3  1995/09/15  00:00:00  Craig_Harrison
 * First beta release
 * 
 * Revision 1.1  1995/01/23  09:22:45  rik
 * Initial revision
 * 

--*/
#include <ndis.h>
#include <ndiswan.h>

#include "DsApi.h"
#include "digix25.h"
#include "digix25p.h"


#define X25_MAJOR_VERSION 2
#define X25_MINOR_VERSION 0

//
// Lan OID's
//
static UINT SupportedLanOids[] =
{
   OID_GEN_SUPPORTED_LIST,
   OID_GEN_HARDWARE_STATUS,
   OID_GEN_MEDIA_SUPPORTED,
   OID_GEN_MEDIA_IN_USE,
   OID_GEN_MAXIMUM_LOOKAHEAD,
   OID_GEN_MAXIMUM_FRAME_SIZE,
   OID_GEN_MAXIMUM_TOTAL_SIZE,
   OID_GEN_MAC_OPTIONS,
   OID_GEN_PROTOCOL_OPTIONS,
   OID_GEN_LINK_SPEED,
   OID_GEN_TRANSMIT_BUFFER_SPACE,
   OID_GEN_RECEIVE_BUFFER_SPACE,
   OID_GEN_TRANSMIT_BLOCK_SIZE,
   OID_GEN_RECEIVE_BLOCK_SIZE,
   OID_GEN_VENDOR_DESCRIPTION,
   OID_GEN_VENDOR_ID,
   OID_GEN_DRIVER_VERSION,
   OID_GEN_CURRENT_PACKET_FILTER,
   OID_GEN_CURRENT_LOOKAHEAD,
   OID_GEN_XMIT_OK,
   OID_GEN_RCV_OK,
   OID_GEN_XMIT_ERROR,
   OID_GEN_RCV_ERROR,
   OID_GEN_RCV_NO_BUFFER,
   OID_802_3_PERMANENT_ADDRESS,
   OID_802_3_CURRENT_ADDRESS,
   OID_802_3_MULTICAST_LIST,
   OID_802_3_MAXIMUM_LIST_SIZE,
   OID_802_3_RCV_ERROR_ALIGNMENT,
   OID_802_3_XMIT_ONE_COLLISION,
   OID_802_3_XMIT_MORE_COLLISIONS
};

#define  MAX_SUPPORTED_LAN_OIDS  (sizeof(SupportedLanOids) / sizeof(UINT))


NDIS_STATUS LanOidHandler( NDIS_HANDLE AdapterContext,
                           NDIS_OID Oid,
                           PVOID InfoBuffer,
                           ULONG InfoBufferLen,
                           PULONG BytesReadWritten,
                           PULONG BytesNeeded )
{
   PDIGIWAN_ADAPTER_OBJECT AdapterObject=(PDIGIWAN_ADAPTER_OBJECT)AdapterContext;
   ULONG GenericULong;
   USHORT   GenericUShort;
   UCHAR GenericArray[6];
   UINT  MoveBytes = sizeof(ULONG);
   PVOID MoveSource = (PVOID)(&GenericULong);
   UINT BytesLeft = InfoBufferLen;
   NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
   NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
   NDIS_MEDIUM Medium = NdisMedium802_3;
   ULONG    OidType = 0;
   ULONG    Filter;

   switch( Oid )
   {
      case OID_802_3_MULTICAST_LIST:
         DigiDump( DIGIFLOW, ("OID_802_3_MULTICAST_LIST:\n") );
      case OID_GEN_CURRENT_LOOKAHEAD:
         DigiDump( DIGIFLOW, ("OID_GEN_CURRENT_LOOKAHEAD:\n") );
         MoveBytes = BytesLeft;
         OidType = 1;
         break;

      case OID_GEN_CURRENT_PACKET_FILTER:
         DigiDump( DIGIFLOW, ("OID_GEN_CURRENT_PACKET_FILTER:\n") );
         MoveBytes = BytesLeft;
         OidType = 1;
         NdisMoveMemory(&Filter, InfoBuffer, 4);

         if( Filter & (NDIS_PACKET_TYPE_SOURCE_ROUTING |
                       NDIS_PACKET_TYPE_SMT |
                       NDIS_PACKET_TYPE_MAC_FRAME |
                       NDIS_PACKET_TYPE_FUNCTIONAL |
                       NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
                       NDIS_PACKET_TYPE_GROUP) )
            StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
         break;

      case OID_GEN_MAC_OPTIONS:
         DigiDump( DIGIFLOW, ("OID_GEN_MAC_OPTIONS:\n") );
         GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
                                NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
                                NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
                                NDIS_MAC_OPTION_NO_LOOPBACK);

         break;

      case OID_GEN_SUPPORTED_LIST:
         DigiDump( DIGIFLOW, ("OID_GEN_SUPPORTED_LIST:\n") );
         MoveSource = (PVOID)(SupportedLanOids);
         MoveBytes = sizeof(SupportedLanOids);
         break;

      case OID_GEN_HARDWARE_STATUS:
         DigiDump( DIGIFLOW, ("OID_GEN_HARDWARE_STATUS:\n") );
         MoveSource = (PVOID)(&HardwareStatus);
         MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
         break;

      case OID_GEN_MEDIA_SUPPORTED:
         DigiDump( DIGIFLOW, ("OID_GEN_MEDIA_SUPPORTED:\n") );
      case OID_GEN_MEDIA_IN_USE:
         DigiDump( DIGIFLOW, ("OID_GEN_MEDIA_IN_USE:\n") );
         MoveSource = (PVOID)(&Medium);
         MoveBytes = sizeof(NDIS_MEDIUM);
         break;

      case OID_GEN_MAXIMUM_LOOKAHEAD:
         DigiDump( DIGIFLOW, ("OID_GEN_MAXIMUM_LOOKAHEAD:\n") );
         GenericULong = (ULONG)1514;
         break;

      case OID_GEN_MAXIMUM_FRAME_SIZE:
         DigiDump( DIGIFLOW, ("OID_GEN_MAXIMUM_FRAME_SIZE:\n") );
         GenericULong = (ULONG)1500;
         break;

      case OID_GEN_MAXIMUM_TOTAL_SIZE:
         DigiDump( DIGIFLOW, ("OID_GEN_MAXIMUM_TOTAL_SIZE:\n") );
         GenericULong = (ULONG)1514;
         break;

      case OID_GEN_LINK_SPEED:
         DigiDump( DIGIFLOW, ("OID_GEN_LINK_SPEED:\n") );
         GenericULong = (ULONG)12800;
         break;

      case OID_GEN_TRANSMIT_BUFFER_SPACE:
         DigiDump( DIGIFLOW, ("OID_GEN_TRANSMIT_BUFFER_SPACE:\n") );
         GenericULong = (ULONG)(1514 * 16);
         break;

      case OID_GEN_RECEIVE_BUFFER_SPACE:
         DigiDump( DIGIFLOW, ("OID_GEN_RECEIVE_BUFFER_SPACE:\n") );
         GenericULong = (ULONG)(1514 * 16);
         break;

      case OID_GEN_TRANSMIT_BLOCK_SIZE:
         DigiDump( DIGIFLOW, ("OID_GEN_TRANSMIT_BLOCK_SIZE:\n") );
         GenericULong = (ULONG)256;
         break;

      case OID_GEN_RECEIVE_BLOCK_SIZE:
         DigiDump( DIGIFLOW, ("OID_GEN_RECEIVE_BLOCK_SIZE:\n") );
         GenericULong = (ULONG)256;
         break;

      case OID_GEN_VENDOR_ID:
         DigiDump( DIGIFLOW, ("OID_GEN_VENDOR_ID:\n") );
         NdisMoveMemory( (PVOID)&GenericULong,
                         AdapterObject->StationAddress,
                         3 );

         GenericULong &= 0xFFFFFF00;
         GenericULong |= 0x01;
         break;

      case OID_GEN_VENDOR_DESCRIPTION:
         DigiDump( DIGIFLOW, ("OID_GEN_VENDOR_DESCRIPTION:\n") );
         MoveSource = (PVOID)"DigiBoard X.25 Adapter.";
         MoveBytes = strlen("DigiBoard X.25 Adapter.");
         break;

      case OID_GEN_DRIVER_VERSION:
         DigiDump( DIGIFLOW, ("OID_GEN_DRIVER_VERSION:\n") );
         GenericUShort = ((USHORT)X25_MAJOR_VERSION << 8) | X25_MINOR_VERSION;
         MoveSource = (PVOID)(&GenericUShort);
         MoveBytes = sizeof(USHORT);
         break;

      case OID_802_3_PERMANENT_ADDRESS:
         DigiDump( DIGIFLOW, ("OID_802_3_PERMANENT_ADDRESS:\n") );
         NdisMoveMemory( (PVOID)GenericArray,
                         AdapterObject->StationAddress,
                         6 );
         MoveSource = (PVOID)GenericArray;
         MoveBytes = 6;
         break;

      case OID_802_3_CURRENT_ADDRESS:
         DigiDump( DIGIFLOW, ("OID_802_3_CURRENT_ADDRESS:\n") );
         NdisMoveMemory( (PVOID)GenericArray,
                         AdapterObject->StationAddress,
                         6);
         MoveSource = (PVOID)GenericArray;
         MoveBytes = 6;
         break;

      case OID_GEN_XMIT_OK:
         DigiDump( DIGIFLOW, ("OID_GEN_XMIT_OK:\n") );
      case OID_GEN_RCV_OK:
         DigiDump( DIGIFLOW, ("OID_GEN_RCV_OK:\n") );
      case OID_GEN_XMIT_ERROR:
         DigiDump( DIGIFLOW, ("OID_GEN_XMIT_ERROR:\n") );
      case OID_GEN_RCV_ERROR:
         DigiDump( DIGIFLOW, ("OID_GEN_RCV_ERROR:\n") );
      case OID_GEN_RCV_NO_BUFFER:
         DigiDump( DIGIFLOW, ("OID_GEN_RCV_NO_BUFFER:\n") );
      case OID_802_3_RCV_ERROR_ALIGNMENT:
         DigiDump( DIGIFLOW, ("OID_802_3_RCV_ERROR_ALIGNMENT:\n") );
      case OID_802_3_XMIT_ONE_COLLISION:
         DigiDump( DIGIFLOW, ("OID_802_3_XMIT_ONE_COLLISION:\n") );
      case OID_802_3_XMIT_MORE_COLLISIONS:
         DigiDump( DIGIFLOW, ("OID_802_3_XMIT_MORE_COLLISIONS:\n") );
         GenericULong = (ULONG)0;
         break;

      case OID_802_3_MAXIMUM_LIST_SIZE:
         DigiDump( DIGIFLOW, ("OID_802_3_MAXIMUM_LIST_SIZE:\n") );
         GenericULong = (ULONG)16;
         break;

      default:
         StatusToReturn = NDIS_STATUS_INVALID_OID;
         break;
   }

   if( StatusToReturn == NDIS_STATUS_SUCCESS )
   {
      (*BytesNeeded) = 0;
      if( MoveBytes > BytesLeft )
      {
         (*BytesNeeded) = MoveBytes;
         StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
      }
      else if (OidType == 0)
      {
         NdisMoveMemory( InfoBuffer, MoveSource, MoveBytes );
         (*BytesReadWritten) = MoveBytes;
      }
   }

   return( StatusToReturn );
}



