|
|
/*
************************************************************************ * * REQUEST.c * * * (C) Copyright 1996 National Semiconductor Corp. * (C) Copyright 1996 Microsoft Corp. * * * (ep) * ************************************************************************* */
#include "nsc.h"
#include "request.tmh"
#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; }
|