📄 cardx500.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
// Copyright 2001, Cisco Systems, Inc. All rights reserved.
// No part of this source, or the resulting binary files, may be reproduced,
// transmitted or redistributed in any form or by any means, electronic or
// mechanical, for any purpose, without the express written permission of Cisco.
//
//---------------------------------------------------------------------------
// cardx500.cpp
//---------------------------------------------------------------------------
// Description:
//
// Revision History:
//
// Date
//---------------------------------------------------------------------------
// 09/22/00 jbeaujon -added BOOLEAN parameter to InitFW() to indicate
// that we want to use the current config info.
// The default value of this param is FALSE.
//
// 10/02/00 jbeaujon -fixed throughput (transmit) problem by ensuring that
// DoNextSend() is invoked whenever cbHandleInterrupt()
// is invoked.
// -reformatted code.
//
// 10/11/00 jbeaujon -changed cardname for product numbers 0x07, 0x08 from
// "PC4800" to "340 Series". Changed cardname for prodnum
// "0x0A" from "PC4800" to "350 Series".
//
// 10/30/00 jbeaujon -auto config stuff.
//
// 03/20/01 jraf -softex interrupt problem fix, isr and InitInterrupts modified
//
// 05/04/01 spb001 -Added "fast" initialization option. By changing
// the InitFW() to only reset the device on the
// first call. InitFW1() must then be called to
// finish the initialization. Subsequent calls to InitFW()
// will work as prior to changes.
//
// 5/10/01 spb002 -Fix for interrupt problem.
//
// 5/8/01 spb003 -Fix for slow ftp throughput problem for NCSU
// Took 6.21 cbHandleInterrupt routine and tweaked
// it (Reversed processing of Rx and Tx interrupts)
//
// 05/10/01 spb004 -Work around for network card not sending an updatelinkstatus
// interrupt when it should
//
// 06/05/01 spb009 -Removed part of spb004 in UpdateLinkStatus because
// we now send a disconnect status when we disable
// the card. Now UpdateLinkStatus only has to worry
// about the time when the card is enabled.
//
// 07/10/01 spb018 -MiniportHalt was illegally calling NdisMIndicateStatus
//
// 07/18/01 spb023 -Added firmware flashing during init for Windows XP
//
// 07/23/01 spb026 -Changed firmware flashing during init so that it is
// a blocking function. Broke WZC.
//
// 0801/01 spb027 -Added check to make sure cmdStatus was successful
//
// 08/13/01 raf -Magic Packet fixes
//---------------------------------------------------------------------------
#pragma code_seg("LCODE")
#include "NDISVER.h"
#ifndef UNDER_CE
extern "C"{
#include <ndis.h>
#include <VXDWRAPS.H>
}
#else
extern "C"{
#include <ndis.h>
}
#endif
#include "string.h"
//
#include "HWX500.h"
#include "CardX500.h"
#include <memory.h>
#include <AiroVxdWrap.H>
#include <AiroPCI.h>
#if NDISVER == 5
# include "queue.h"
#endif
char * VxdLoadName = "VXDX500.VXD";
char * VxdUnloadName = "VXDX500";
ULONG fidCounter;
USHORT FidArray[ 3 ];
BOOLEAN validateFid( USHORT & fid )
{
static index = 0;
int size = sizeof(FidArray)/sizeof(FidArray[0]);
for( int i=0; i<size; i++ ){
if( fid == FidArray[ i ] )
return TRUE;
}
fid = FidArray[ index++ ];
return FALSE;
}
//spb027 BOOLEAN IsCardInserted( PCARD card );
typedef struct
{
USHORT SelectedRate;
UCHAR SupRates[8];
UINT LinkSpeed;
char *CardName;
}STSUPRATES;
static STSUPRATES SUPPORTED_RATES[] =
{
{1, {1}, 1*10000/2},
{2, {2}, 1*10000},
{4, {4}, 2*10000},
{11, {11}, 11*10000/2},
{22, {22}, 11*10000},
{0, {2,4}, 2*10000, "PC2500"},
{0, {2,4}, 2*10000, "PC3500"},
{0, {2,4}, 2*10000, "PC4500"},
{0, {2,4,11,22},11*10000, "PC4800"},
{0xFFFF}
};
typedef struct _RADIOTYPE
{
USHORT ProductNum; // FROM capabilities STRUCT;
//
char *CardName; //"PC3500";
USHORT u16RadioType; // FROM capabilities STRUCT;
UINT FrequencyType; //1=HOPPER, 0 = DS
UINT CardType; //VXD_CARDTYPE_PCXX00;
USHORT Pci_Dev_Id; //PC3500_PCI_DEV_ID;
}RADIOTYPE;
static RADIOTYPE RadioTypesArray[] =
{
{0x06, "PC2500", 0x0004, 0, VXD_CARDTYPE_PC2500, PC2500_PCI_DEV_ID},
{0x09, "PC3100", 0x0001, 1, VXD_CARDTYPE_PC3100, PC3100_PCI_DEV_ID},
{0x04, "PC3500", 0x0001, 1, VXD_CARDTYPE_PC3500, PC3500_PCI_DEV_ID},
{0x05, "PC4500", 0x0002, 0, VXD_CARDTYPE_PC4500, PC4500_PCI_DEV_ID},
{0x07, "340 Series", 0x0002, 0, VXD_CARDTYPE_PC4800, PC4800_PCI_DEV_ID},
{0x08, "340 Series", 0x0002, 0, VXD_CARDTYPE_PC4800, PC4800_PCI_DEV_ID},
{0x0A, "350 series", 0x0002, 0, VXD_CARDTYPE_PC4800, PC4800_PCI_DEV_ID},
{0,0},
};
BOOLEAN cardConstruct(PCARD card)
{
// card->m_CardType = CardType;
// card->m_FrequencyType = FrequencyType;
strcpy( card->m_CardName, CardName );
strcpy( card->m_DriverName, DriverName);
card->m_PortIOLen = 64; // 30 words
card->m_IsIO = TRUE;
card->m_IsIO16 = TRUE;
return baseCardConstruct(card);
}
void CardShutdown(PCARD card)
{
disableHostInterrupts(card);
// USHORT usWord;
// NdisRawReadPortUshort( card->m_IOBase+REG_INT_STAT, &usWord );
// NdisRawWritePortUshort( card->m_IOBase+REG_INT_ACK, usWord );
if( ! card->m_CardPresent )
return;
cmdAwaken(card, TRUE );
#if NDISVER == 3 || NDISVER == 41
if( 0xFFFF != (0xFFFF & card->m_MagicPacketMode)) {
cmdMagicPacket( card, TRUE );
}
else {
//Don't send link down during shutdown.
card->m_MSenceStatus = NDIS_STATUS_MEDIA_DISCONNECT;
cmdDisable(card);
}
#else
//Don't send link down during shutdown.
card->m_MSenceStatus = NDIS_STATUS_MEDIA_DISCONNECT;
cmdDisable(card);
#endif
}
void cardDestruct(PCARD card)
{
CardShutdown(card);
baseCardDestruct(card);
}
#define show(a,b) a=b
extern UINT DebugFlag;
//===========================================================================
void cbIsr (OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueDpc,
IN NDIS_HANDLE Context)
//===========================================================================
//
// Description: Hardware ISR (runs at DIRQL)
//
// Inputs: InterruptRecognized
// QueueDpc
// Context
//
// Returns: nothing.
//---------------------------------------------------------------------------
{
PCARD card = (PCARD)Context;
USHORT usWord;
//
// This fixes PCI shared interrupt problem.
//
// (11/08/00 - jbeaujon) Only do this for bus type of PCI
//
//spb002
if (0==GetMaskInterrupts(card)) {
*InterruptRecognized = FALSE;
*QueueDpc = FALSE;
return;
}
#ifdef SOFTEX
if (!ADAPTER_READY(card)) {
*InterruptRecognized = FALSE;
*QueueDpc = FALSE;
return;
}
if (!card->m_InterruptRegistered ) { // should never happen.....but
*InterruptRecognized = FALSE;
*QueueDpc = FALSE;
//spb024 card->m_IntActive = 0;
return;
}
#endif
//StoreHostActiveInterrupts(card);
NdisRawReadPortUshort(card->m_IOBase+REG_INT_STAT, &usWord);
// DbgPrint("cbIsr int %X, mask %X \n",usWord, card->m_IntMask);
if ((usWord & 0x7FFF) && (0xFFFF != usWord)) {
if ((INT_EN_AWAKE == usWord) && card->IsAwake) {
*InterruptRecognized = FALSE;
*QueueDpc = FALSE;
return;
}
//You must always disable interrupts before storing status in m_IntActive
//There are other routines (cmds) that disable interrupts and rely
//on the m_IntActive byte and interrupts being disabled
disableHostInterrupts(card);
card->m_IntActive = usWord;
card->m_InterruptHandled = TRUE;
*InterruptRecognized = TRUE;
*QueueDpc = TRUE;
}
else {
*InterruptRecognized = FALSE;
*QueueDpc = FALSE;
}
}
/*
//===========================================================================
void cbIsr (OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueDpc,
IN NDIS_HANDLE Context)
//===========================================================================
//
// Description: Hardware ISR (runs at DIRQL)
//
// Inputs: InterruptRecognized
// QueueDpc
// Context
//
// Returns: nothing.
//---------------------------------------------------------------------------
{
PCARD card = (PCARD)Context;
//
// This fixes PCI shared interrupt problem.
//
// (11/08/00 - jbeaujon) Only do this for bus type of PCI
//
if (card->m_IntActive && (card->m_BusType == NdisInterfacePci)) {
*InterruptRecognized = FALSE;
*QueueDpc = FALSE;
card->m_IntActive = 0;
return;
}
#ifdef SOFTEX
if (!ADAPTER_READY(card)) {
*InterruptRecognized = FALSE;
*QueueDpc = FALSE;
return;
}
#endif
//StoreHostActiveInterrupts(card);
USHORT usWord;
NdisRawReadPortUshort(card->m_IOBase+REG_INT_STAT, &usWord);
if ((usWord & 0x7FFF) && (0xFFFF != usWord)) {
if ((INT_EN_AWAKE == usWord) && card->IsAwake) {
*InterruptRecognized = FALSE;
*QueueDpc = FALSE;
return;
}
disableHostInterrupts(card);
card->m_IntActive = usWord;
card->m_InterruptHandled = TRUE;
*InterruptRecognized = TRUE;
*QueueDpc = TRUE;
}
else {
*InterruptRecognized = FALSE;
*QueueDpc = FALSE;
}
}
*/
//spb003
void
cbHandleInterrupt(
PCARD card
)
{
// FOR PCMCIA handleing
// StoreHostActiveInterrupts must be called also here
// to handle some machines controllers
#ifdef SOFTEX
if(!ADAPTER_READY( card ))
return;
#endif
// DbgPrint("cbHandleInterrupt\n");
if( FALSE==card->m_InterruptHandled ){
StoreHostActiveInterrupts(card);
disableHostInterrupts(card);
}
card->m_InterruptHandled = FALSE;
#ifndef UNDER_CE
USHORT ints;
#endif
do {
if( isAwakeInterrupt(card ) ){
AckAwakeInterrupt(card);
card->IsAwake = TRUE;
//spb003 DoNextSend(card);
}
if( isAsleepInterrupt(card ) ){
AckAsleepInterrupt(card);
}
if( isCmdInterrupt(card) )
AckCmdInterrupt(card);
while( DoNextSend(card));
if( isTxInterrupt(card) ){
USHORT fid; // reclaim fids
//NdisRawReadPortUshort( card->m_IOBase+REG_FID_TX_COMP, &fid );
NdisRawReadPortUshort( card->m_IOBase+REG_FID_TX_COMP, &fid );
// if (0 == fid ) {
// while (1)
// DbgPrint("Fid is 0 ................\n");
// }
fidCounter++;
CQStore( card->fidQ, fid );
AckTxInterrupt(card);
while( DoNextSend(card));
}
if( isTxExceptInterrupt(card) ){
USHORT fid; // reclaim fids
NdisRawReadPortUshort( card->m_IOBase+REG_FID_TX_COMP, &fid );
// if (0 == fid ) {
// while (1)
// DbgPrint("Fid is 0 ................\n");
// }
fidCounter++;
//validateFid(fid);
CQStore( card->fidQ, fid );
AckTxExceptInterrupt(card);
while( DoNextSend(card));
}
if( isRxInterrupt(card) ){
if( RxFidSetup(card) )
RcvDpc(card);
}
if( isLinkInterrupt(card) ){
UpdateLinkStatus(card);
CheckAutoConfig(card);
AckLinkInterrupt( card );
}
// ACK remaining ints
if(card->m_IntActive ) {
NdisRawWritePortUshort(card->m_IOBase+REG_INT_ACK, card->m_IntActive & ~EVNT_DO_SLEEP);
//Only reset m_IntActive in the defered handler routine
card->m_IntActive = 0; //spb024
//spb005 NdisRawWritePortUshort( card->m_IOBase+REG_INT_ACK, card->m_IntActive );
}
//spb024 card->m_IntActive = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -