1/* 2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * 20 * File: int.c 21 * 22 * Purpose: Handle USB interrupt endpoint 23 * 24 * Author: Jerry Chen 25 * 26 * Date: Apr. 2, 2004 27 * 28 * Functions: 29 * 30 * Revision History: 31 * 04-02-2004 Jerry Chen: Initial release 32 * 33 */ 34 35#include "int.h" 36#include "mib.h" 37#include "tmacro.h" 38#include "mac.h" 39#include "power.h" 40#include "bssdb.h" 41#include "usbpipe.h" 42 43/*--------------------- Static Definitions -------------------------*/ 44/* static int msglevel = MSG_LEVEL_DEBUG; */ 45static int msglevel = MSG_LEVEL_INFO; 46 47 48/*--------------------- Static Classes ----------------------------*/ 49 50/*--------------------- Static Variables --------------------------*/ 51 52/*--------------------- Static Functions --------------------------*/ 53 54/*--------------------- Export Variables --------------------------*/ 55 56 57/*--------------------- Export Functions --------------------------*/ 58 59 60/*+ 61 * 62 * Function: InterruptPollingThread 63 * 64 * Synopsis: Thread running at IRQL PASSIVE_LEVEL. 65 * 66 * Arguments: Device Extension 67 * 68 * Returns: 69 * 70 * Algorithm: Call USBD for input data; 71 * 72 * History: dd-mm-yyyy Author Comment 73 * 74 * 75 * Notes: 76 * 77 * USB reads are by nature 'Blocking', and when in a read, the device looks 78 * like it's in a 'stall' condition, so we deliberately time out every second 79 * if we've gotten no data 80 * 81-*/ 82void INTvWorkItem(void *Context) 83{ 84 PSDevice pDevice = (PSDevice) Context; 85 int ntStatus; 86 87 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n"); 88 89 spin_lock_irq(&pDevice->lock); 90 if (pDevice->fKillEventPollingThread != TRUE) 91 ntStatus = PIPEnsInterruptRead(pDevice); 92 spin_unlock_irq(&pDevice->lock); 93} 94 95int INTnsProcessData(PSDevice pDevice) 96{ 97 int status = STATUS_SUCCESS; 98 PSINTData pINTData; 99 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 100 struct net_device_stats *pStats = &pDevice->stats; 101 102 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n"); 103 104 pINTData = (PSINTData) pDevice->intBuf.pDataBuf; 105 if (pINTData->byTSR0 & TSR_VALID) { 106 STAvUpdateTDStatCounter(&(pDevice->scStatistic), 107 (BYTE) (pINTData->byPkt0 & 0x0F), 108 (BYTE) (pINTData->byPkt0>>4), 109 pINTData->byTSR0); 110 BSSvUpdateNodeTxCounter(pDevice, 111 &(pDevice->scStatistic), 112 pINTData->byTSR0, 113 pINTData->byPkt0); 114 /*DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0));*/ 115 } 116 if (pINTData->byTSR1 & TSR_VALID) { 117 STAvUpdateTDStatCounter(&(pDevice->scStatistic), 118 (BYTE) (pINTData->byPkt1 & 0x0F), 119 (BYTE) (pINTData->byPkt1>>4), 120 pINTData->byTSR1); 121 BSSvUpdateNodeTxCounter(pDevice, 122 &(pDevice->scStatistic), 123 pINTData->byTSR1, 124 pINTData->byPkt1); 125 /*DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1));*/ 126 } 127 if (pINTData->byTSR2 & TSR_VALID) { 128 STAvUpdateTDStatCounter(&(pDevice->scStatistic), 129 (BYTE) (pINTData->byPkt2 & 0x0F), 130 (BYTE) (pINTData->byPkt2>>4), 131 pINTData->byTSR2); 132 BSSvUpdateNodeTxCounter(pDevice, 133 &(pDevice->scStatistic), 134 pINTData->byTSR2, 135 pINTData->byPkt2); 136 /*DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2));*/ 137 } 138 if (pINTData->byTSR3 & TSR_VALID) { 139 STAvUpdateTDStatCounter(&(pDevice->scStatistic), 140 (BYTE) (pINTData->byPkt3 & 0x0F), 141 (BYTE) (pINTData->byPkt3>>4), 142 pINTData->byTSR3); 143 BSSvUpdateNodeTxCounter(pDevice, 144 &(pDevice->scStatistic), 145 pINTData->byTSR3, 146 pINTData->byPkt3); 147 /*DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3));*/ 148 } 149 if (pINTData->byISR0 != 0) { 150 if (pINTData->byISR0 & ISR_BNTX) { 151 if (pDevice->eOPMode == OP_MODE_AP) { 152 if (pMgmt->byDTIMCount > 0) { 153 pMgmt->byDTIMCount--; 154 pMgmt->sNodeDBTable[0].bRxPSPoll = 155 FALSE; 156 } else if (pMgmt->byDTIMCount == 0) { 157 /* check if mutltcast tx bufferring */ 158 pMgmt->byDTIMCount = 159 pMgmt->byDTIMPeriod-1; 160 pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE; 161 if (pMgmt->sNodeDBTable[0].bPSEnable) 162 bScheduleCommand((void *) pDevice, 163 WLAN_CMD_RX_PSPOLL, 164 NULL); 165 } 166 bScheduleCommand((void *) pDevice, 167 WLAN_CMD_BECON_SEND, 168 NULL); 169 } /* if (pDevice->eOPMode == OP_MODE_AP) */ 170 pDevice->bBeaconSent = TRUE; 171 } else { 172 pDevice->bBeaconSent = FALSE; 173 } 174 if (pINTData->byISR0 & ISR_TBTT) { 175 if (pDevice->bEnablePSMode) 176 bScheduleCommand((void *) pDevice, 177 WLAN_CMD_TBTT_WAKEUP, 178 NULL); 179 if (pDevice->bChannelSwitch) { 180 pDevice->byChannelSwitchCount--; 181 if (pDevice->byChannelSwitchCount == 0) 182 bScheduleCommand((void *) pDevice, 183 WLAN_CMD_11H_CHSW, 184 NULL); 185 } 186 } 187 LODWORD(pDevice->qwCurrTSF) = pINTData->dwLoTSF; 188 HIDWORD(pDevice->qwCurrTSF) = pINTData->dwHiTSF; 189 /*DBG_PRN_GRP01(("ISR0 = %02x , 190 LoTsf = %08x, 191 HiTsf = %08x\n", 192 pINTData->byISR0, 193 pINTData->dwLoTSF, 194 pINTData->dwHiTSF)); */ 195 196 STAvUpdate802_11Counter(&pDevice->s802_11Counter, 197 &pDevice->scStatistic, 198 pINTData->byRTSSuccess, 199 pINTData->byRTSFail, 200 pINTData->byACKFail, 201 pINTData->byFCSErr); 202 STAvUpdateIsrStatCounter(&pDevice->scStatistic, 203 pINTData->byISR0, 204 pINTData->byISR1); 205 } 206 207 if (pINTData->byISR1 != 0) 208 if (pINTData->byISR1 & ISR_GPIO3) 209 bScheduleCommand((void *) pDevice, 210 WLAN_CMD_RADIO, 211 NULL); 212 pDevice->intBuf.uDataLen = 0; 213 pDevice->intBuf.bInUse = FALSE; 214 215 pStats->tx_packets = pDevice->scStatistic.ullTsrOK; 216 pStats->tx_bytes = pDevice->scStatistic.ullTxDirectedBytes + 217 pDevice->scStatistic.ullTxMulticastBytes + 218 pDevice->scStatistic.ullTxBroadcastBytes; 219 pStats->tx_errors = pDevice->scStatistic.dwTsrErr; 220 pStats->tx_dropped = pDevice->scStatistic.dwTsrErr; 221 222 return status; 223} 224