/* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * File: int.c * * Purpose: Handle USB interrupt endpoint * * Author: Jerry Chen * * Date: Apr. 2, 2004 * * Functions: * * Revision History: * 04-02-2004 Jerry Chen: Initial release * */ #include "int.h" #include "mib.h" #include "tmacro.h" #include "mac.h" #include "power.h" #include "bssdb.h" #include "usbpipe.h" /*--------------------- Static Definitions -------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ /*--------------------- Static Functions --------------------------*/ /*--------------------- Export Variables --------------------------*/ /*--------------------- Export Functions --------------------------*/ /*+ * * Function: InterruptPollingThread * * Synopsis: Thread running at IRQL PASSIVE_LEVEL. * * Arguments: Device Extension * * Returns: * * Algorithm: Call USBD for input data; * * History: dd-mm-yyyy Author Comment * * * Notes: * * USB reads are by nature 'Blocking', and when in a read, the device looks like it's * in a 'stall' condition, so we deliberately time out every second if we've gotten no data * -*/ VOID INTvWorkItem( PVOID Context ) { PSDevice pDevice = (PSDevice) Context; NTSTATUS ntStatus; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n"); spin_lock_irq(&pDevice->lock); if (pDevice->fKillEventPollingThread != TRUE) { ntStatus = PIPEnsInterruptRead(pDevice); } spin_unlock_irq(&pDevice->lock); } NTSTATUS INTnsProcessData( IN PSDevice pDevice ) { NTSTATUS status = STATUS_SUCCESS; PSINTData pINTData; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct net_device_stats* pStats = &pDevice->stats; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n"); pINTData = (PSINTData) pDevice->intBuf.pDataBuf; if (pINTData->byTSR0 & TSR_VALID) { STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt0 & 0x0F), (BYTE) (pINTData->byPkt0>>4), pINTData->byTSR0); BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic), pINTData->byTSR0, pINTData->byPkt0); //DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0)); } if (pINTData->byTSR1 & TSR_VALID) { STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt1 & 0x0F), (BYTE) (pINTData->byPkt1>>4), pINTData->byTSR1); BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic), pINTData->byTSR1, pINTData->byPkt1); //DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1)); } if (pINTData->byTSR2 & TSR_VALID) { STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt2 & 0x0F), (BYTE) (pINTData->byPkt2>>4), pINTData->byTSR2); BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic), pINTData->byTSR2, pINTData->byPkt2); //DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2)); } if (pINTData->byTSR3 & TSR_VALID) { STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt3 & 0x0F), (BYTE) (pINTData->byPkt3>>4), pINTData->byTSR3); BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic), pINTData->byTSR3, pINTData->byPkt3); //DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3)); } if ( pINTData->byISR0 != 0 ) { if (pINTData->byISR0 & ISR_BNTX) { if (pDevice->eOPMode == OP_MODE_AP) { if(pMgmt->byDTIMCount > 0) { pMgmt->byDTIMCount --; pMgmt->sNodeDBTable[0].bRxPSPoll = FALSE; } else if(pMgmt->byDTIMCount == 0) { // check if mutltcast tx bufferring pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE; if (pMgmt->sNodeDBTable[0].bPSEnable) { bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL); } } bScheduleCommand((HANDLE)pDevice, WLAN_CMD_BECON_SEND, NULL); } // if (pDevice->eOPMode == OP_MODE_AP) pDevice->bBeaconSent = TRUE; } else { pDevice->bBeaconSent = FALSE; } if (pINTData->byISR0 & ISR_TBTT) { if ( pDevice->bEnablePSMode ) { bScheduleCommand((HANDLE) pDevice, WLAN_CMD_TBTT_WAKEUP, NULL); } if ( pDevice->bChannelSwitch ) { pDevice->byChannelSwitchCount--; if ( pDevice->byChannelSwitchCount == 0 ) { bScheduleCommand((HANDLE) pDevice, WLAN_CMD_11H_CHSW, NULL); } } } LODWORD(pDevice->qwCurrTSF) = pINTData->dwLoTSF; HIDWORD(pDevice->qwCurrTSF) = pINTData->dwHiTSF; //DBG_PRN_GRP01(("ISR0 = %02x ,LoTsf = %08x,HiTsf = %08x\n", pINTData->byISR0, pINTData->dwLoTSF,pINTData->dwHiTSF)); STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, pINTData->byRTSSuccess, pINTData->byRTSFail, pINTData->byACKFail, pINTData->byFCSErr ); STAvUpdateIsrStatCounter(&pDevice->scStatistic, pINTData->byISR0, pINTData->byISR1); } if ( pINTData->byISR1 != 0 ) { if (pINTData->byISR1 & ISR_GPIO3) { bScheduleCommand((HANDLE) pDevice, WLAN_CMD_RADIO, NULL); } } pDevice->intBuf.uDataLen = 0; pDevice->intBuf.bInUse = FALSE; pStats->tx_packets = pDevice->scStatistic.ullTsrOK; pStats->tx_bytes = pDevice->scStatistic.ullTxDirectedBytes + pDevice->scStatistic.ullTxMulticastBytes + pDevice->scStatistic.ullTxBroadcastBytes; pStats->tx_errors = pDevice->scStatistic.dwTsrErr; pStats->tx_dropped = pDevice->scStatistic.dwTsrErr; return status; }