423 lines
12 KiB
C
423 lines
12 KiB
C
|
/*
|
||
|
************************************************************************
|
||
|
*
|
||
|
* REQUEST.c
|
||
|
*
|
||
|
*
|
||
|
* (C) Copyright 1996 National Semiconductor Corp.
|
||
|
* (C) Copyright 1996 Microsoft Corp.
|
||
|
*
|
||
|
*
|
||
|
* (ep)
|
||
|
*
|
||
|
*************************************************************************
|
||
|
*/
|
||
|
|
||
|
#include "nsc.h"
|
||
|
#include "newdong.h"
|
||
|
|
||
|
|
||
|
|
||
|
const NDIS_OID NSCGlobalSupportedOids[] = {
|
||
|
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_SEND_PACKETS,
|
||
|
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_DRIVER_VERSION,
|
||
|
OID_GEN_DRIVER_VERSION,
|
||
|
OID_GEN_CURRENT_PACKET_FILTER,
|
||
|
OID_GEN_CURRENT_LOOKAHEAD,
|
||
|
OID_GEN_MEDIA_CONNECT_STATUS,
|
||
|
OID_IRDA_RECEIVING,
|
||
|
OID_IRDA_SUPPORTED_SPEEDS,
|
||
|
OID_IRDA_LINK_SPEED,
|
||
|
OID_IRDA_MEDIA_BUSY,
|
||
|
OID_IRDA_TURNAROUND_TIME,
|
||
|
OID_IRDA_MAX_RECEIVE_WINDOW_SIZE,
|
||
|
OID_IRDA_EXTRA_RCV_BOFS,
|
||
|
OID_IRDA_MAX_SEND_WINDOW_SIZE
|
||
|
};
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// //
|
||
|
// Function: MiniportQueryInformation //
|
||
|
// //
|
||
|
// Description: //
|
||
|
// Query the capabilities and status of the miniport driver. //
|
||
|
// //
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
NDIS_STATUS MiniportQueryInformation (
|
||
|
IN NDIS_HANDLE MiniportAdapterContext,
|
||
|
IN NDIS_OID Oid,
|
||
|
IN PVOID InformationBuffer,
|
||
|
IN ULONG InformationBufferLength,
|
||
|
OUT PULONG BytesWritten,
|
||
|
OUT PULONG BytesNeeded)
|
||
|
{
|
||
|
NDIS_STATUS result = NDIS_STATUS_SUCCESS;
|
||
|
IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
|
||
|
INT i, speeds, speedSupported;
|
||
|
UINT *infoPtr;
|
||
|
|
||
|
NDIS_MEDIUM Medium = NdisMediumIrda;
|
||
|
ULONG GenericUlong;
|
||
|
PVOID SourceBuffer = (PVOID) (&GenericUlong);
|
||
|
ULONG SourceLength = sizeof(ULONG);
|
||
|
|
||
|
|
||
|
ULONG BaudRateTable[NUM_BAUDRATES];
|
||
|
|
||
|
|
||
|
switch (Oid){
|
||
|
|
||
|
case OID_GEN_SUPPORTED_LIST:
|
||
|
SourceBuffer = (PVOID) (NSCGlobalSupportedOids);
|
||
|
SourceLength = sizeof(NSCGlobalSupportedOids);
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_HARDWARE_STATUS:
|
||
|
GenericUlong = thisDev->hardwareStatus;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MEDIA_SUPPORTED:
|
||
|
case OID_GEN_MEDIA_IN_USE:
|
||
|
SourceBuffer = (PVOID) (&Medium);
|
||
|
SourceLength = sizeof(NDIS_MEDIUM);
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_RECEIVING:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_IRDA_RECEIVING)"));
|
||
|
GenericUlong = (ULONG)thisDev->nowReceiving;
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_SUPPORTED_SPEEDS:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_IRDA_SUPPORTED_SPEEDS)"));
|
||
|
|
||
|
speeds = thisDev->portInfo.hwCaps.supportedSpeedsMask &
|
||
|
thisDev->AllowedSpeedMask &
|
||
|
ALL_IRDA_SPEEDS;
|
||
|
|
||
|
for (i = 0, infoPtr = (PUINT)BaudRateTable, SourceLength=0;
|
||
|
(i < NUM_BAUDRATES) && speeds;
|
||
|
i++){
|
||
|
|
||
|
if (supportedBaudRateTable[i].ndisCode & speeds){
|
||
|
*infoPtr++ = supportedBaudRateTable[i].bitsPerSec;
|
||
|
SourceLength += sizeof(UINT);
|
||
|
speeds &= ~supportedBaudRateTable[i].ndisCode;
|
||
|
DBGOUT((" - supporting speed %d bps", supportedBaudRateTable[i].bitsPerSec));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SourceBuffer = (PVOID) BaudRateTable;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_LINK_SPEED:
|
||
|
// The maximum speed of NIC is 4Mbps
|
||
|
GenericUlong = 40000; // 100bps increments
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_LINK_SPEED:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_IRDA_LINK_SPEED)"));
|
||
|
if (thisDev->linkSpeedInfo){
|
||
|
GenericUlong = (ULONG)thisDev->linkSpeedInfo->bitsPerSec;
|
||
|
}
|
||
|
else {
|
||
|
GenericUlong = DEFAULT_BAUD_RATE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_MEDIA_BUSY:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_IRDA_MEDIA_BUSY)"));
|
||
|
GenericUlong = (UINT)thisDev->mediaBusy;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_CURRENT_LOOKAHEAD:
|
||
|
case OID_GEN_MAXIMUM_LOOKAHEAD:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_GEN_MAXIMUM_LOOKAHEAD)"));
|
||
|
GenericUlong = MAX_I_DATA_SIZE;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||
|
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||
|
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
||
|
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_GEN_MAXIMUM_LOOKAHEAD)"));
|
||
|
|
||
|
// Normally there's some difference in these values, based on the
|
||
|
// MAC header, but IrDA doesn't have one.
|
||
|
|
||
|
GenericUlong = MAX_I_DATA_SIZE;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_RECEIVE_BUFFER_SPACE:
|
||
|
case OID_GEN_TRANSMIT_BUFFER_SPACE:
|
||
|
GenericUlong = (ULONG) (MAX_IRDA_DATA_SIZE * 8);
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MAC_OPTIONS:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_GEN_MAC_OPTIONS)"));
|
||
|
GenericUlong = 0;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MAXIMUM_SEND_PACKETS:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_GEN_MAXIMUM_SEND_PACKETS)"));
|
||
|
GenericUlong = 16;
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_TURNAROUND_TIME:
|
||
|
// Indicate the amount of time that the transceiver needs
|
||
|
// to recuperate after a send.
|
||
|
DBGOUT(("MiniportQueryInformation(OID_IRDA_TURNAROUND_TIME)"));
|
||
|
GenericUlong =
|
||
|
(ULONG)thisDev->portInfo.hwCaps.turnAroundTime_usec;
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_EXTRA_RCV_BOFS:
|
||
|
// Pass back the number of _extra_ BOFs to be prepended
|
||
|
// to packets sent to this unit at 115.2 baud, the
|
||
|
// maximum Slow IR speed. This will be scaled for other
|
||
|
// speed according to the table in the
|
||
|
// Infrared Extensions to NDIS' spec.
|
||
|
DBGOUT(("MiniportQueryInformation(OID_IRDA_EXTRA_RCV_BOFS)"));
|
||
|
GenericUlong = (ULONG)thisDev->portInfo.hwCaps.extraBOFsRequired;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_GEN_CURRENT_PACKET_FILTER)"));
|
||
|
GenericUlong = NDIS_PACKET_TYPE_PROMISCUOUS;
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_MAX_RECEIVE_WINDOW_SIZE:
|
||
|
DBGOUT(("MiniportQueryInformation(OID_IRDA_MAX_RECEIVE_WINDOW_SIZE)"));
|
||
|
GenericUlong = MAX_RX_PACKETS;
|
||
|
//GenericUlong = 1;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_VENDOR_DESCRIPTION:
|
||
|
SourceBuffer = (PVOID)"NSC Infrared Port";
|
||
|
SourceLength = 18;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_VENDOR_DRIVER_VERSION:
|
||
|
// This value is used to know whether to update driver.
|
||
|
GenericUlong = (NSC_MAJOR_VERSION << 16) +
|
||
|
(NSC_MINOR_VERSION << 8) +
|
||
|
NSC_LETTER_VERSION;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_DRIVER_VERSION:
|
||
|
GenericUlong = (NDIS_MAJOR_VERSION << 8) + NDIS_MINOR_VERSION;
|
||
|
SourceLength = 2;
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_MAX_SEND_WINDOW_SIZE:
|
||
|
GenericUlong = 7;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||
|
GenericUlong = (ULONG) NdisMediaStateConnected;
|
||
|
break;
|
||
|
|
||
|
|
||
|
default:
|
||
|
DBGERR(("MiniportQueryInformation(%d=0x%x), unsupported OID", Oid, Oid));
|
||
|
result = NDIS_STATUS_NOT_SUPPORTED;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (result == NDIS_STATUS_SUCCESS) {
|
||
|
if (SourceLength > InformationBufferLength) {
|
||
|
*BytesNeeded = SourceLength;
|
||
|
result = NDIS_STATUS_INVALID_LENGTH;
|
||
|
}
|
||
|
else {
|
||
|
*BytesNeeded = 0;
|
||
|
*BytesWritten = SourceLength;
|
||
|
NdisMoveMemory(InformationBuffer, SourceBuffer, SourceLength);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DBGOUT(("MiniportQueryInformation succeeded (info <- %d)", *(UINT *)InformationBuffer));
|
||
|
return result;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// //
|
||
|
// Function: MiniportSetInformation //
|
||
|
// //
|
||
|
// Description: //
|
||
|
// Allow other layers of the network software (e.g., a transport //
|
||
|
// driver) to control the miniport driver by changing information that //
|
||
|
// the miniport driver maintains in its OIDs, such as the packet //
|
||
|
// or multicast addresses. //
|
||
|
// //
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
NDIS_STATUS MiniportSetInformation (
|
||
|
IN NDIS_HANDLE MiniportAdapterContext,
|
||
|
IN NDIS_OID Oid,
|
||
|
IN PVOID InformationBuffer,
|
||
|
IN ULONG InformationBufferLength,
|
||
|
OUT PULONG BytesRead,
|
||
|
OUT PULONG BytesNeeded)
|
||
|
{
|
||
|
NDIS_STATUS result = NDIS_STATUS_SUCCESS;
|
||
|
IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
|
||
|
UINT i,speedSupported;
|
||
|
const baudRateInfo * CurrentLinkSpeed;
|
||
|
|
||
|
if (InformationBufferLength >= sizeof(UINT)){
|
||
|
|
||
|
UINT info = *(UINT *)InformationBuffer;
|
||
|
*BytesRead = sizeof(UINT);
|
||
|
*BytesNeeded = 0;
|
||
|
|
||
|
switch (Oid){
|
||
|
case OID_IRDA_LINK_SPEED:
|
||
|
DBGOUT(("MiniportSetInformation(OID_IRDA_LINK_SPEED, %xh)",
|
||
|
info));
|
||
|
result = NDIS_STATUS_INVALID_DATA;
|
||
|
|
||
|
CurrentLinkSpeed=thisDev->linkSpeedInfo;
|
||
|
|
||
|
// Find the appropriate speed and set it
|
||
|
speedSupported = NUM_BAUDRATES;
|
||
|
for (i = 0; i < speedSupported; i++){
|
||
|
if (supportedBaudRateTable[i].bitsPerSec == info){
|
||
|
thisDev->linkSpeedInfo = &supportedBaudRateTable[i];
|
||
|
result = NDIS_STATUS_SUCCESS;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (result == NDIS_STATUS_SUCCESS){
|
||
|
|
||
|
if (CurrentLinkSpeed != thisDev->linkSpeedInfo) {
|
||
|
//
|
||
|
// different from the current
|
||
|
//
|
||
|
BOOLEAN DoItNow=TRUE;
|
||
|
|
||
|
NdisAcquireSpinLock(&thisDev->QueueLock);
|
||
|
|
||
|
if (!IsListEmpty(&thisDev->SendQueue)){
|
||
|
//
|
||
|
// packets queued, change after this one
|
||
|
//
|
||
|
thisDev->lastPacketAtOldSpeed = CONTAINING_RECORD(thisDev->SendQueue.Blink,
|
||
|
NDIS_PACKET,
|
||
|
MiniportReserved);
|
||
|
DBGOUT(("delaying set-speed because send pkts queued"));
|
||
|
DoItNow=FALSE;
|
||
|
|
||
|
|
||
|
} else {
|
||
|
//
|
||
|
// no packets in the queue
|
||
|
//
|
||
|
if (thisDev->CurrentPacket != NULL) {
|
||
|
//
|
||
|
// the current packet is the only one
|
||
|
//
|
||
|
thisDev->lastPacketAtOldSpeed=thisDev->CurrentPacket;
|
||
|
thisDev->setSpeedAfterCurrentSendPacket = TRUE;
|
||
|
|
||
|
DBGOUT(("delaying set-speed because send pkts queued"));
|
||
|
DoItNow=FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if (DoItNow) {
|
||
|
|
||
|
if (!SetSpeed(thisDev)){
|
||
|
result = NDIS_STATUS_FAILURE;
|
||
|
}
|
||
|
|
||
|
thisDev->TransmitIsIdle=FALSE;
|
||
|
}
|
||
|
|
||
|
NdisReleaseSpinLock(&thisDev->QueueLock);
|
||
|
|
||
|
if (DoItNow) {
|
||
|
|
||
|
ProcessSendQueue(thisDev);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
*BytesRead = 0;
|
||
|
*BytesNeeded = 0;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_MEDIA_BUSY:
|
||
|
DBGOUT(("MiniportSetInformation(OID_IRDA_MEDIA_BUSY, %xh)",
|
||
|
info));
|
||
|
|
||
|
// The protocol can use this OID to reset the busy field
|
||
|
// in order to check it later for intervening activity.
|
||
|
//
|
||
|
thisDev->mediaBusy = (BOOLEAN)info;
|
||
|
InterlockedExchange(&thisDev->RxInterrupts,0);
|
||
|
result = NDIS_STATUS_SUCCESS;
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
||
|
DBGOUT(
|
||
|
("MiniportSetInformation(OID_GEN_CURRENT_PACKET_FILTER, %xh)",
|
||
|
info));
|
||
|
result = NDIS_STATUS_SUCCESS;
|
||
|
break;
|
||
|
|
||
|
|
||
|
case OID_GEN_CURRENT_LOOKAHEAD:
|
||
|
result = (info<=MAX_I_DATA_SIZE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_INVALID_LENGTH;
|
||
|
break;
|
||
|
|
||
|
// We don't support these
|
||
|
//
|
||
|
case OID_IRDA_RATE_SNIFF:
|
||
|
case OID_IRDA_UNICAST_LIST:
|
||
|
|
||
|
// These are query-only parameters.
|
||
|
//
|
||
|
case OID_IRDA_SUPPORTED_SPEEDS:
|
||
|
case OID_IRDA_MAX_UNICAST_LIST_SIZE:
|
||
|
case OID_IRDA_TURNAROUND_TIME:
|
||
|
|
||
|
default:
|
||
|
DBGERR(("MiniportSetInformation(OID=%d=0x%x, value=%xh) - unsupported OID", Oid, Oid, info));
|
||
|
*BytesRead = 0;
|
||
|
*BytesNeeded = 0;
|
||
|
result = NDIS_STATUS_NOT_SUPPORTED;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
*BytesRead = 0;
|
||
|
*BytesNeeded = sizeof(UINT);
|
||
|
result = NDIS_STATUS_INVALID_LENGTH;
|
||
|
}
|
||
|
|
||
|
DBGOUT(("MiniportSetInformation succeeded"));
|
||
|
return result;
|
||
|
}
|