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_DEBUG; */
45 static int msglevel
= MSG_LEVEL_INFO
;
48 /*--------------------- Static Classes ----------------------------*/
50 /*--------------------- Static Variables --------------------------*/
52 /*--------------------- Static Functions --------------------------*/
54 /*--------------------- Export Variables --------------------------*/
57 /*--------------------- Export Functions --------------------------*/
62 * Function: InterruptPollingThread
64 * Synopsis: Thread running at IRQL PASSIVE_LEVEL.
66 * Arguments: Device Extension
70 * Algorithm: Call USBD for input data;
72 * History: dd-mm-yyyy Author Comment
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
82 void INTvWorkItem(void *Context
)
84 PSDevice pDevice
= (PSDevice
) Context
;
87 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"---->Interrupt Polling Thread\n");
89 spin_lock_irq(&pDevice
->lock
);
90 if (pDevice
->fKillEventPollingThread
!= TRUE
)
91 ntStatus
= PIPEnsInterruptRead(pDevice
);
92 spin_unlock_irq(&pDevice
->lock
);
95 void INTnsProcessData(PSDevice pDevice
)
98 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
99 struct net_device_stats
*pStats
= &pDevice
->stats
;
101 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"---->s_nsInterruptProcessData\n");
103 pINTData
= (PSINTData
) pDevice
->intBuf
.pDataBuf
;
104 if (pINTData
->byTSR0
& TSR_VALID
) {
105 STAvUpdateTDStatCounter(&(pDevice
->scStatistic
),
106 (BYTE
) (pINTData
->byPkt0
& 0x0F),
107 (BYTE
) (pINTData
->byPkt0
>>4),
109 BSSvUpdateNodeTxCounter(pDevice
,
110 &(pDevice
->scStatistic
),
113 /*DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0));*/
115 if (pINTData
->byTSR1
& TSR_VALID
) {
116 STAvUpdateTDStatCounter(&(pDevice
->scStatistic
),
117 (BYTE
) (pINTData
->byPkt1
& 0x0F),
118 (BYTE
) (pINTData
->byPkt1
>>4),
120 BSSvUpdateNodeTxCounter(pDevice
,
121 &(pDevice
->scStatistic
),
124 /*DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1));*/
126 if (pINTData
->byTSR2
& TSR_VALID
) {
127 STAvUpdateTDStatCounter(&(pDevice
->scStatistic
),
128 (BYTE
) (pINTData
->byPkt2
& 0x0F),
129 (BYTE
) (pINTData
->byPkt2
>>4),
131 BSSvUpdateNodeTxCounter(pDevice
,
132 &(pDevice
->scStatistic
),
135 /*DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2));*/
137 if (pINTData
->byTSR3
& TSR_VALID
) {
138 STAvUpdateTDStatCounter(&(pDevice
->scStatistic
),
139 (BYTE
) (pINTData
->byPkt3
& 0x0F),
140 (BYTE
) (pINTData
->byPkt3
>>4),
142 BSSvUpdateNodeTxCounter(pDevice
,
143 &(pDevice
->scStatistic
),
146 /*DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3));*/
148 if (pINTData
->byISR0
!= 0) {
149 if (pINTData
->byISR0
& ISR_BNTX
) {
150 if (pDevice
->eOPMode
== OP_MODE_AP
) {
151 if (pMgmt
->byDTIMCount
> 0) {
152 pMgmt
->byDTIMCount
--;
153 pMgmt
->sNodeDBTable
[0].bRxPSPoll
=
155 } else if (pMgmt
->byDTIMCount
== 0) {
156 /* check if mutltcast tx bufferring */
158 pMgmt
->byDTIMPeriod
-1;
159 pMgmt
->sNodeDBTable
[0].bRxPSPoll
= TRUE
;
160 if (pMgmt
->sNodeDBTable
[0].bPSEnable
)
161 bScheduleCommand((void *) pDevice
,
165 bScheduleCommand((void *) pDevice
,
168 } /* if (pDevice->eOPMode == OP_MODE_AP) */
169 pDevice
->bBeaconSent
= TRUE
;
171 pDevice
->bBeaconSent
= FALSE
;
173 if (pINTData
->byISR0
& ISR_TBTT
) {
174 if (pDevice
->bEnablePSMode
)
175 bScheduleCommand((void *) pDevice
,
176 WLAN_CMD_TBTT_WAKEUP
,
178 if (pDevice
->bChannelSwitch
) {
179 pDevice
->byChannelSwitchCount
--;
180 if (pDevice
->byChannelSwitchCount
== 0)
181 bScheduleCommand((void *) pDevice
,
186 LODWORD(pDevice
->qwCurrTSF
) = pINTData
->dwLoTSF
;
187 HIDWORD(pDevice
->qwCurrTSF
) = pINTData
->dwHiTSF
;
188 /*DBG_PRN_GRP01(("ISR0 = %02x ,
193 pINTData->dwHiTSF)); */
195 STAvUpdate802_11Counter(&pDevice
->s802_11Counter
,
196 &pDevice
->scStatistic
,
197 pINTData
->byRTSSuccess
,
201 STAvUpdateIsrStatCounter(&pDevice
->scStatistic
,
206 if (pINTData
->byISR1
!= 0)
207 if (pINTData
->byISR1
& ISR_GPIO3
)
208 bScheduleCommand((void *) pDevice
,
211 pDevice
->intBuf
.uDataLen
= 0;
212 pDevice
->intBuf
.bInUse
= FALSE
;
214 pStats
->tx_packets
= pDevice
->scStatistic
.ullTsrOK
;
215 pStats
->tx_bytes
= pDevice
->scStatistic
.ullTxDirectedBytes
+
216 pDevice
->scStatistic
.ullTxMulticastBytes
+
217 pDevice
->scStatistic
.ullTxBroadcastBytes
;
218 pStats
->tx_errors
= pDevice
->scStatistic
.dwTsrErr
;
219 pStats
->tx_dropped
= pDevice
->scStatistic
.dwTsrErr
;