2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
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.
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.
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.
22 * Purpose: Handle USB interrupt endpoint
31 * 04-02-2004 Jerry Chen: Initial release
43 /*--------------------- Static Definitions -------------------------*/
44 static int msglevel
= MSG_LEVEL_INFO
; /* MSG_LEVEL_DEBUG */
46 /*--------------------- Static Classes ----------------------------*/
48 /*--------------------- Static Variables --------------------------*/
50 /*--------------------- Static Functions --------------------------*/
52 /*--------------------- Export Variables --------------------------*/
54 /*--------------------- Export Functions --------------------------*/
58 * Function: InterruptPollingThread
60 * Synopsis: Thread running at IRQL PASSIVE_LEVEL.
62 * Arguments: Device Extension
66 * Algorithm: Call USBD for input data;
68 * History: dd-mm-yyyy Author Comment
73 * USB reads are by nature 'Blocking', and when in a read, the device looks
74 * like it's in a 'stall' condition, so we deliberately time out every second
75 * if we've gotten no data
78 void INTvWorkItem(void *Context
)
80 PSDevice pDevice
= Context
;
83 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"---->Interrupt Polling Thread\n");
85 spin_lock_irq(&pDevice
->lock
);
86 if (pDevice
->fKillEventPollingThread
!= TRUE
)
87 ntStatus
= PIPEnsInterruptRead(pDevice
);
88 spin_unlock_irq(&pDevice
->lock
);
91 void INTnsProcessData(PSDevice pDevice
)
94 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
95 struct net_device_stats
*pStats
= &pDevice
->stats
;
97 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"---->s_nsInterruptProcessData\n");
99 pINTData
= (PSINTData
) pDevice
->intBuf
.pDataBuf
;
100 if (pINTData
->byTSR0
& TSR_VALID
) {
101 STAvUpdateTDStatCounter(&(pDevice
->scStatistic
),
102 (BYTE
)(pINTData
->byPkt0
& 0x0F),
103 (BYTE
)(pINTData
->byPkt0
>>4),
105 BSSvUpdateNodeTxCounter(pDevice
,
106 &(pDevice
->scStatistic
),
109 /*DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0));*/
111 if (pINTData
->byTSR1
& TSR_VALID
) {
112 STAvUpdateTDStatCounter(&(pDevice
->scStatistic
),
113 (BYTE
)(pINTData
->byPkt1
& 0x0F),
114 (BYTE
)(pINTData
->byPkt1
>>4),
116 BSSvUpdateNodeTxCounter(pDevice
,
117 &(pDevice
->scStatistic
),
120 /*DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1));*/
122 if (pINTData
->byTSR2
& TSR_VALID
) {
123 STAvUpdateTDStatCounter(&(pDevice
->scStatistic
),
124 (BYTE
)(pINTData
->byPkt2
& 0x0F),
125 (BYTE
)(pINTData
->byPkt2
>>4),
127 BSSvUpdateNodeTxCounter(pDevice
,
128 &(pDevice
->scStatistic
),
131 /*DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2));*/
133 if (pINTData
->byTSR3
& TSR_VALID
) {
134 STAvUpdateTDStatCounter(&(pDevice
->scStatistic
),
135 (BYTE
)(pINTData
->byPkt3
& 0x0F),
136 (BYTE
)(pINTData
->byPkt3
>>4),
138 BSSvUpdateNodeTxCounter(pDevice
,
139 &(pDevice
->scStatistic
),
142 /*DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3));*/
144 if (pINTData
->byISR0
!= 0) {
145 if (pINTData
->byISR0
& ISR_BNTX
) {
146 if (pDevice
->eOPMode
== OP_MODE_AP
) {
147 if (pMgmt
->byDTIMCount
> 0) {
148 pMgmt
->byDTIMCount
--;
149 pMgmt
->sNodeDBTable
[0].bRxPSPoll
=
151 } else if (pMgmt
->byDTIMCount
== 0) {
152 /* check if mutltcast tx bufferring */
154 pMgmt
->byDTIMPeriod
-1;
155 pMgmt
->sNodeDBTable
[0].bRxPSPoll
= TRUE
;
156 if (pMgmt
->sNodeDBTable
[0].bPSEnable
)
157 bScheduleCommand((void *) pDevice
,
161 bScheduleCommand((void *) pDevice
,
164 } /* if (pDevice->eOPMode == OP_MODE_AP) */
165 pDevice
->bBeaconSent
= TRUE
;
167 pDevice
->bBeaconSent
= FALSE
;
169 if (pINTData
->byISR0
& ISR_TBTT
) {
170 if (pDevice
->bEnablePSMode
)
171 bScheduleCommand((void *) pDevice
,
172 WLAN_CMD_TBTT_WAKEUP
,
174 if (pDevice
->bChannelSwitch
) {
175 pDevice
->byChannelSwitchCount
--;
176 if (pDevice
->byChannelSwitchCount
== 0)
177 bScheduleCommand((void *) pDevice
,
182 LODWORD(pDevice
->qwCurrTSF
) = pINTData
->dwLoTSF
;
183 HIDWORD(pDevice
->qwCurrTSF
) = pINTData
->dwHiTSF
;
184 /*DBG_PRN_GRP01(("ISR0 = %02x ,
189 pINTData->dwHiTSF)); */
191 STAvUpdate802_11Counter(&pDevice
->s802_11Counter
,
192 &pDevice
->scStatistic
,
193 pINTData
->byRTSSuccess
,
197 STAvUpdateIsrStatCounter(&pDevice
->scStatistic
,
201 if (pINTData
->byISR1
!= 0)
202 if (pINTData
->byISR1
& ISR_GPIO3
)
203 bScheduleCommand((void *) pDevice
,
206 pDevice
->intBuf
.uDataLen
= 0;
207 pDevice
->intBuf
.bInUse
= FALSE
;
209 pStats
->tx_packets
= pDevice
->scStatistic
.ullTsrOK
;
210 pStats
->tx_bytes
= pDevice
->scStatistic
.ullTxDirectedBytes
+
211 pDevice
->scStatistic
.ullTxMulticastBytes
+
212 pDevice
->scStatistic
.ullTxBroadcastBytes
;
213 pStats
->tx_errors
= pDevice
->scStatistic
.dwTsrErr
;
214 pStats
->tx_dropped
= pDevice
->scStatistic
.dwTsrErr
;