Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
int.c
Go to the documentation of this file.
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_INFO; /* MSG_LEVEL_DEBUG */
45 
46 /*--------------------- Static Classes ----------------------------*/
47 
48 /*--------------------- Static Variables --------------------------*/
49 
50 /*--------------------- Static Functions --------------------------*/
51 
52 /*--------------------- Export Variables --------------------------*/
53 
54 /*--------------------- Export Functions --------------------------*/
55 
56 /*+
57  *
58  * Function: InterruptPollingThread
59  *
60  * Synopsis: Thread running at IRQL PASSIVE_LEVEL.
61  *
62  * Arguments: Device Extension
63  *
64  * Returns:
65  *
66  * Algorithm: Call USBD for input data;
67  *
68  * History: dd-mm-yyyy Author Comment
69  *
70  *
71  * Notes:
72  *
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
76  *
77 -*/
78 void INTvWorkItem(void *Context)
79 {
80  PSDevice pDevice = Context;
81  int ntStatus;
82 
83  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n");
84 
85  spin_lock_irq(&pDevice->lock);
86  if (pDevice->fKillEventPollingThread != TRUE)
87  ntStatus = PIPEnsInterruptRead(pDevice);
88  spin_unlock_irq(&pDevice->lock);
89 }
90 
92 {
93  PSINTData pINTData;
94  PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
95  struct net_device_stats *pStats = &pDevice->stats;
96 
97  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n");
98 
99  pINTData = (PSINTData) pDevice->intBuf.pDataBuf;
100  if (pINTData->byTSR0 & TSR_VALID) {
102  (BYTE)(pINTData->byPkt0 & 0x0F),
103  (BYTE)(pINTData->byPkt0>>4),
104  pINTData->byTSR0);
105  BSSvUpdateNodeTxCounter(pDevice,
106  &(pDevice->scStatistic),
107  pINTData->byTSR0,
108  pINTData->byPkt0);
109  /*DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0));*/
110  }
111  if (pINTData->byTSR1 & TSR_VALID) {
113  (BYTE)(pINTData->byPkt1 & 0x0F),
114  (BYTE)(pINTData->byPkt1>>4),
115  pINTData->byTSR1);
116  BSSvUpdateNodeTxCounter(pDevice,
117  &(pDevice->scStatistic),
118  pINTData->byTSR1,
119  pINTData->byPkt1);
120  /*DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1));*/
121  }
122  if (pINTData->byTSR2 & TSR_VALID) {
124  (BYTE)(pINTData->byPkt2 & 0x0F),
125  (BYTE)(pINTData->byPkt2>>4),
126  pINTData->byTSR2);
127  BSSvUpdateNodeTxCounter(pDevice,
128  &(pDevice->scStatistic),
129  pINTData->byTSR2,
130  pINTData->byPkt2);
131  /*DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2));*/
132  }
133  if (pINTData->byTSR3 & TSR_VALID) {
135  (BYTE)(pINTData->byPkt3 & 0x0F),
136  (BYTE)(pINTData->byPkt3>>4),
137  pINTData->byTSR3);
138  BSSvUpdateNodeTxCounter(pDevice,
139  &(pDevice->scStatistic),
140  pINTData->byTSR3,
141  pINTData->byPkt3);
142  /*DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3));*/
143  }
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 =
150  FALSE;
151  } else if (pMgmt->byDTIMCount == 0) {
152  /* check if multicast tx buffering */
153  pMgmt->byDTIMCount =
154  pMgmt->byDTIMPeriod-1;
155  pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE;
156  if (pMgmt->sNodeDBTable[0].bPSEnable)
157  bScheduleCommand((void *) pDevice,
159  NULL);
160  }
161  bScheduleCommand((void *) pDevice,
163  NULL);
164  } /* if (pDevice->eOPMode == OP_MODE_AP) */
165  pDevice->bBeaconSent = TRUE;
166  } else {
167  pDevice->bBeaconSent = FALSE;
168  }
169  if (pINTData->byISR0 & ISR_TBTT) {
170  if (pDevice->bEnablePSMode)
171  bScheduleCommand((void *) pDevice,
173  NULL);
174  if (pDevice->bChannelSwitch) {
175  pDevice->byChannelSwitchCount--;
176  if (pDevice->byChannelSwitchCount == 0)
177  bScheduleCommand((void *) pDevice,
179  NULL);
180  }
181  }
182  LODWORD(pDevice->qwCurrTSF) = pINTData->dwLoTSF;
183  HIDWORD(pDevice->qwCurrTSF) = pINTData->dwHiTSF;
184  /*DBG_PRN_GRP01(("ISR0 = %02x ,
185  LoTsf = %08x,
186  HiTsf = %08x\n",
187  pINTData->byISR0,
188  pINTData->dwLoTSF,
189  pINTData->dwHiTSF)); */
190 
192  &pDevice->scStatistic,
193  pINTData->byRTSSuccess,
194  pINTData->byRTSFail,
195  pINTData->byACKFail,
196  pINTData->byFCSErr);
198  pINTData->byISR0,
199  pINTData->byISR1);
200  }
201  if (pINTData->byISR1 != 0)
202  if (pINTData->byISR1 & ISR_GPIO3)
203  bScheduleCommand((void *) pDevice,
205  NULL);
206  pDevice->intBuf.uDataLen = 0;
207  pDevice->intBuf.bInUse = FALSE;
208 
209  pStats->tx_packets = pDevice->scStatistic.ullTsrOK;
210  pStats->tx_bytes = pDevice->scStatistic.ullTxDirectedBytes +
213  pStats->tx_errors = pDevice->scStatistic.dwTsrErr;
214  pStats->tx_dropped = pDevice->scStatistic.dwTsrErr;
215 }