📄 cmdx500.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.
//---------------------------------------------------------------------------
// CmdX500.cpp
//---------------------------------------------------------------------------
// Description:
//
// Revision History:
//
// Date
//---------------------------------------------------------------------------
// 09/22/00 jbeaujon -modified cmdConfigSet, cmdSSIDSet, cmdAPsSet so
// that if the second parameter is NULL, we use the
// copy stored in card.
// 11/10/00 jbeaujon -In AckCommand: clear the EVNT_STAT_CMD bit in
// card->m_IntActive so we don;t ack the same
// command twice.
//
// 06/05/01 spb009 -Send the disconnect status when we disable the
// Radio
//
// 06/12/01 spb010 -Make sure the buffer is an even number of bytes
// during a RidSet and RidGet
//
//---------------------------------------------------------------------------
#pragma code_seg("LCODE")
#include "NDISVER.h"
extern "C"{
#include <ndis.h>
}
extern ULONG fidCounter;
#include "CmdX500.h"
#include "support.h"
#include "memory.h"
#include "Airodef.h"
#include "CardX500.h"
BOOLEAN
exec(PCARD card)
{
return(exec(card, 100));
}
BOOLEAN
exec(PCARD card, int delay )
{
if( !WaitBusy(card, 10 ) ) {
return FALSE;
}
if ( ! WaitLastCmd( card, delay ) ) {
return FALSE;
}
WriteCommand( card );
CmdRestoreInterrupts(card);
return TRUE;
}
BOOLEAN
exec(PCARD card, int delay, USHORT p0 )
{
if( !WaitBusy(card, 10 ) ) {
return FALSE;
}
if ( ! WaitLastCmd( card, delay ) ) {
return FALSE;
}
WriteCommand( card, p0 );
CmdRestoreInterrupts(card);
return TRUE;
}
BOOLEAN
WaitComplete(PCARD card, int delay)// delay in us, 1 second default
{
#ifndef CE_FLAG_USE_NDISM_SLEEP
for( ; ! IsCmdComplete(card) && delay > 0; delay -=10 ){
DelayUS( 10 );
}
#else
//
// CE can't guarantee granularity of < 1 ms.
//
for( ; ! IsCmdComplete(card) && delay > 0; delay -=1000 ){
DelayUS( 1000 );
}
#endif
if( ! IsCmdComplete(card) ) {
return FALSE;
}
return TRUE;
}
BOOLEAN
WaitAllocComplete(PCARD card, int delay )
{
while( ! IsAllocComplete(card) && --delay ){
DelayMS( 1 );
}
if( ! IsAllocComplete(card) )
return FALSE;
return TRUE;
}
CMD_STATUS_X500
GetCmdStatus(PCARD card, CMD_X500 cmd )
{
USHORT usWord;
NdisRawReadPortUshort( card->m_IOBase+REG_CMD_STATUS, &usWord );
if ( 0xFFFF != cmd && (0x3f & cmd) != (usWord & 0x3f) ){
return CMD_STATUS_NOTCMD;
}
if ( 0x0000 == (usWord & 0x7F00) )
return CMD_STATUS_SUCCESS;
if ( 0x0100 == (usWord & 0x7F00) )
return CMD_STATUS_NOTASSOC;
if ( 0x0200 == (usWord & 0x7F00) )
return CMD_STATUS_FAILURE;
if ( 0x3F00 == (usWord & 0x7F00) )
return CMD_STATUS_CMDERROR;
return CMD_STATUS_UKNOWNERROR;
}
void
WriteCommand(PCARD card )
{
card->m_PrevCmdTick = 1;
card->m_PrevCmdDone = FALSE;
NdisRawWritePortUshort( card->m_IOBase+REG_CMD, card->m_cmd );
card->m_PrevCommand = card->m_cmd;
}
void
WriteCommand(PCARD card, USHORT p0 )
{
NdisRawWritePortUshort( card->m_IOBase+REG_CMD_P0, p0 );
WriteCommand(card);
}
void
GetResponce(PCARD card, USHORT *p0,USHORT *p1,USHORT *p2)
{
if( p0 ) ReadRespParam( card, (REGX500)(card->m_IOBase+REG_CMD_RESP0) , p0 );
if( p1 ) ReadRespParam( card, (REGX500)(card->m_IOBase+REG_CMD_RESP1), p1 );
if( p2 ) ReadRespParam( card, (REGX500)(card->m_IOBase+REG_CMD_RESP2), p2 );
}
BOOLEAN
IsCmdReady(PCARD card)
{
USHORT usWord;
NdisRawReadPortUshort( card->m_IOBase+REG_CMD, &usWord );
return 0 == (0x8000&usWord);
}
BOOLEAN
IsEventAllocReady(PCARD card)
{
USHORT usWord;
NdisRawReadPortUshort( card->m_IOBase+REG_INT_STAT, &usWord );
return 0 != (0x0008&usWord);
}
BOOLEAN
IsResponceReady(PCARD card)
{
USHORT usWord;
NdisRawReadPortUshort( card->m_IOBase+REG_CMD_STATUS, &usWord );
return 0 != (0x8000&usWord);
}
BOOLEAN
IsCmdComplete(PCARD card)
{
USHORT usWord;
if( card->m_PrevCmdDone )
return TRUE;
// if( ! card->m_IsPolling )
// return FALSE;
NdisRawReadPortUshort( card->m_IOBase+REG_INT_STAT, &usWord );
if( EVNT_STAT_CMD & usWord ){
AckCommand(card);
return TRUE;
}
return FALSE;
}
BOOLEAN
IsAllocComplete(PCARD card)
{
USHORT usWord;
NdisRawReadPortUshort( card->m_IOBase+REG_INT_STAT, &usWord );
return EVNT_STAT_Alloc & usWord;
}
void
AckCommand(PCARD card)
{
NdisRawWritePortUshort( card->m_IOBase+REG_INT_ACK, EVNT_ACK_CMD );
//
// Clear the command bit in our copy in case we get here before cbHandleInterrupt()
// gets invoked. (jbeaujon 11/09/00)
//
card->m_IntActive &= ~EVNT_STAT_CMD;
card->m_PrevCmdDone = TRUE;
}
void
AckAlloc(PCARD card)
{
NdisRawWritePortUshort( card->m_IOBase+REG_INT_ACK, EVNT_ACK_Alloc );
}
/*
BOOLEAN
WaitBusy(PCARD card, int us)
{
USHORT usWord = 0xFFFF;
int delay = 0;
while( (usWord & 0x8000) && delay <= us){
DelayUS(2);
delay += 2;
NdisRawReadPortUshort( card->m_IOBase+REG_CMD, &usWord );
}
return 0 == (0x8000&usWord);
}
*/
void
UnstickBusyCommand(PCARD card )
{
USHORT usWord;
NdisRawWritePortUshort( card->m_IOBase+REG_INT_ACK, 0x4000 );
NdisRawReadPortUshort( card->m_IOBase+REG_CMD, &usWord );
if( 0x7FFF & usWord && 0==(0x8000 & usWord))
NdisRawWritePortUshort( card->m_IOBase+REG_CMD, usWord );
}
BOOLEAN
WaitBusy(PCARD card, int us)
{
USHORT usWord = 0xFFFF;
int timeout = 1000 * 100; // 100 milliseconds
int delay = 0;
while( (usWord & 0x8000) && delay <= timeout){
#ifndef CE_FLAG_USE_NDISM_SLEEP
DelayUS(10);
delay += 10;
#else
//
// CE can't guarantee granularity of < 1 ms.
//
DelayUS(1000);
delay += 1000;
#endif
NdisRawReadPortUshort( card->m_IOBase+REG_CMD, &usWord );
if( (0x8000 & usWord) && 0==(delay%200) ){
UnstickBusyCommand(card);
card->m_PrevCmdDone = TRUE;
}
}
return 0 == (0x8000&usWord);
}
BOOLEAN
WaitLastCmd(PCARD card, int delay)
{
BOOLEAN res;
int tmp = 0;
while( !(res = IsCmdComplete(card))&& tmp <= delay ){
tmp += 10;
DelayUS( 10 );
}
if( ! res ) {
return FALSE;
}
CmdDisableInterrupts(card);
tmp = delay - tmp;
while( !(res = IsCmdComplete(card))&& tmp <= delay ){
tmp += 10;
DelayUS( 10 );
}
if ( ! res ){
CmdRestoreInterrupts(card);
return FALSE;
}
return TRUE;
}
#if 1
//BOOLEAN IsBapStuck(int IOBase, USHORT BapRegSel );
//void BapStuck(int IOBase, USHORT BapRegSel, USHORT fid, USHORT off );
BOOLEAN IsBapStuck(int IOBase, USHORT BapRegSel )
{
USHORT usWord;
NdisRawReadPortUshort( IOBase+BapRegSel, &usWord );
return 0==usWord;
}
void BapStuck(PCARD card, USHORT BapRegSel, USHORT fid, USHORT off )
{
// 1) disable interrupts
// 2) rewrite the Selector
// 3) rewrite the Offset
// 4) read SwSupport0
// 5) write SwSupport1 // -- this step MAY not actually be necessary
// 6) reenable interrupts
// 7) wait for busy to become unstuck
// 8) restart the entire bap access
USHORT usWord;
USHORT usInt;
NdisRawReadPortUshort(card->m_IOBase+REG_INT_EN, &usInt ); // read ints enable
NdisRawWritePortUshort(card->m_IOBase+REG_INT_EN, 0 ); // disable ints
//spb024
//If m_IntActive is set, then it means we got an interrupt after
//reading active interrupts but before we were able to disable
//interrupts. Therefore interupts really should be disabled
//when we return from this routine.
//Trust me this happens. (Caused lost fids at Microsoft)
if (card->m_IntActive) {
usInt=0;
}
NdisRawWritePortUshort(card->m_IOBase+BapRegSel, fid );
NdisRawWritePortUshort(card->m_IOBase+BapRegSel+4, off );
NdisRawReadPortUshort(card->m_IOBase+REG_SWS0, &usWord );
NdisRawWritePortUshort(card->m_IOBase+REG_SWS1, 0 );
NdisRawWritePortUshort(card->m_IOBase+REG_INT_EN, usInt ); // renable
NdisRawWritePortUshort(card->m_IOBase+BapRegSel, fid );
NdisRawWritePortUshort(card->m_IOBase+BapRegSel+BAPOFF_OFFSET_BAPX, off );
}
#endif
BOOLEAN
BapSet(PCARD card, USHORT BAPOff, FID fid, int FidOff)
{
USHORT offValue;
int delay = 0;
int stuck = 0;
while( delay <= 3000 ) {
NdisRawWritePortUshort( card->m_IOBase+BAPOff, fid );
NdisRawWritePortUshort( card->m_IOBase+BAPOff+BAPOFF_OFFSET_BAPX, (USHORT)FidOff );
do {
DelayUS( 25 );
delay += 25;
NdisRawReadPortUshort( card->m_IOBase+BAPOff+BAPOFF_OFFSET_BAPX, &offValue );
if( IsFidRdy(offValue) )
return TRUE;
if( 300 <= stuck ){
BapStuck(card, BAPOff, fid, (USHORT)FidOff );
stuck =25;
continue;
}
stuck +=25;
}while( IsFidBusy(offValue) && 1000 >= delay );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -