Commit | Line | Data |
---|---|---|
92b96797 FB |
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 | ||
92b96797 | 35 | #include "int.h" |
92b96797 | 36 | #include "tmacro.h" |
92b96797 | 37 | #include "mac.h" |
92b96797 | 38 | #include "power.h" |
92b96797 | 39 | #include "bssdb.h" |
92b96797 | 40 | #include "usbpipe.h" |
92b96797 | 41 | |
ea15b7b2 | 42 | static int msglevel = MSG_LEVEL_INFO; /* MSG_LEVEL_DEBUG */ |
92b96797 | 43 | |
92b96797 FB |
44 | /*+ |
45 | * | |
46 | * Function: InterruptPollingThread | |
47 | * | |
48 | * Synopsis: Thread running at IRQL PASSIVE_LEVEL. | |
49 | * | |
50 | * Arguments: Device Extension | |
51 | * | |
52 | * Returns: | |
53 | * | |
54 | * Algorithm: Call USBD for input data; | |
55 | * | |
56 | * History: dd-mm-yyyy Author Comment | |
57 | * | |
58 | * | |
59 | * Notes: | |
60 | * | |
ff8041bb DKT |
61 | * USB reads are by nature 'Blocking', and when in a read, the device looks |
62 | * like it's in a 'stall' condition, so we deliberately time out every second | |
63 | * if we've gotten no data | |
92b96797 FB |
64 | * |
65 | -*/ | |
fe5d00eb | 66 | void INTvWorkItem(struct vnt_private *pDevice) |
92b96797 | 67 | { |
0b596b2a | 68 | unsigned long flags; |
6487c49e | 69 | int ntStatus; |
92b96797 | 70 | |
ff8041bb | 71 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n"); |
92b96797 | 72 | |
0b596b2a | 73 | spin_lock_irqsave(&pDevice->lock, flags); |
749627f2 MP |
74 | |
75 | ntStatus = PIPEnsInterruptRead(pDevice); | |
76 | ||
0b596b2a | 77 | spin_unlock_irqrestore(&pDevice->lock, flags); |
ff8041bb | 78 | } |
92b96797 | 79 | |
210098a5 | 80 | void INTnsProcessData(struct vnt_private *priv) |
92b96797 | 81 | { |
210098a5 MP |
82 | struct vnt_interrupt_data *int_data; |
83 | struct vnt_manager *mgmt = &priv->vnt_mgmt; | |
84 | struct net_device_stats *stats = &priv->stats; | |
ff8041bb DKT |
85 | |
86 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n"); | |
87 | ||
f764e00d | 88 | int_data = (struct vnt_interrupt_data *)priv->int_buf.data_buf; |
210098a5 MP |
89 | |
90 | if (int_data->tsr0 & TSR_VALID) { | |
91 | if (int_data->tsr0 & (TSR_TMO | TSR_RETRYTMO)) | |
92 | priv->wstats.discard.retries++; | |
ae27b142 | 93 | else |
210098a5 | 94 | stats->tx_packets++; |
ae27b142 | 95 | |
210098a5 MP |
96 | BSSvUpdateNodeTxCounter(priv, |
97 | int_data->tsr0, | |
98 | int_data->pkt0); | |
ff8041bb | 99 | } |
210098a5 MP |
100 | |
101 | if (int_data->tsr1 & TSR_VALID) { | |
102 | if (int_data->tsr1 & (TSR_TMO | TSR_RETRYTMO)) | |
103 | priv->wstats.discard.retries++; | |
ae27b142 | 104 | else |
210098a5 | 105 | stats->tx_packets++; |
ae27b142 MP |
106 | |
107 | ||
210098a5 MP |
108 | BSSvUpdateNodeTxCounter(priv, |
109 | int_data->tsr1, | |
110 | int_data->pkt1); | |
ff8041bb | 111 | } |
210098a5 MP |
112 | |
113 | if (int_data->tsr2 & TSR_VALID) { | |
114 | if (int_data->tsr2 & (TSR_TMO | TSR_RETRYTMO)) | |
115 | priv->wstats.discard.retries++; | |
ae27b142 | 116 | else |
210098a5 | 117 | stats->tx_packets++; |
ae27b142 | 118 | |
210098a5 MP |
119 | BSSvUpdateNodeTxCounter(priv, |
120 | int_data->tsr2, | |
121 | int_data->pkt2); | |
ff8041bb | 122 | } |
210098a5 MP |
123 | |
124 | if (int_data->tsr3 & TSR_VALID) { | |
125 | if (int_data->tsr3 & (TSR_TMO | TSR_RETRYTMO)) | |
126 | priv->wstats.discard.retries++; | |
ae27b142 | 127 | else |
210098a5 | 128 | stats->tx_packets++; |
ae27b142 | 129 | |
210098a5 MP |
130 | BSSvUpdateNodeTxCounter(priv, |
131 | int_data->tsr3, | |
132 | int_data->pkt3); | |
ff8041bb | 133 | } |
210098a5 MP |
134 | |
135 | if (int_data->isr0 != 0) { | |
136 | if (int_data->isr0 & ISR_BNTX) { | |
137 | if (priv->op_mode == NL80211_IFTYPE_AP) { | |
138 | if (mgmt->byDTIMCount > 0) { | |
139 | mgmt->byDTIMCount--; | |
140 | mgmt->sNodeDBTable[0].bRxPSPoll = | |
e269fc2d | 141 | false; |
210098a5 | 142 | } else if (mgmt->byDTIMCount == 0) { |
a0a1f61a | 143 | /* check if multicast tx buffering */ |
210098a5 MP |
144 | mgmt->byDTIMCount = |
145 | mgmt->byDTIMPeriod-1; | |
146 | mgmt->sNodeDBTable[0].bRxPSPoll = true; | |
147 | if (mgmt->sNodeDBTable[0].bPSEnable) | |
148 | bScheduleCommand((void *) priv, | |
0cbd8d98 AM |
149 | WLAN_CMD_RX_PSPOLL, |
150 | NULL); | |
ff8041bb | 151 | } |
210098a5 | 152 | bScheduleCommand((void *) priv, |
ff8041bb DKT |
153 | WLAN_CMD_BECON_SEND, |
154 | NULL); | |
a0ad2776 | 155 | } |
210098a5 | 156 | priv->bBeaconSent = true; |
ff8041bb | 157 | } else { |
210098a5 | 158 | priv->bBeaconSent = false; |
ff8041bb | 159 | } |
210098a5 MP |
160 | |
161 | if (int_data->isr0 & ISR_TBTT) { | |
162 | if (priv->bEnablePSMode) | |
163 | bScheduleCommand((void *) priv, | |
ff8041bb DKT |
164 | WLAN_CMD_TBTT_WAKEUP, |
165 | NULL); | |
210098a5 MP |
166 | if (priv->bChannelSwitch) { |
167 | priv->byChannelSwitchCount--; | |
168 | if (priv->byChannelSwitchCount == 0) | |
169 | bScheduleCommand((void *) priv, | |
ff8041bb DKT |
170 | WLAN_CMD_11H_CHSW, |
171 | NULL); | |
172 | } | |
173 | } | |
210098a5 | 174 | priv->qwCurrTSF = le64_to_cpu(int_data->tsf); |
ff8041bb | 175 | } |
210098a5 MP |
176 | |
177 | if (int_data->isr1 != 0) | |
178 | if (int_data->isr1 & ISR_GPIO3) | |
179 | bScheduleCommand((void *) priv, | |
ff8041bb DKT |
180 | WLAN_CMD_RADIO, |
181 | NULL); | |
f764e00d MP |
182 | |
183 | priv->int_buf.in_use = false; | |
ff8041bb | 184 | |
210098a5 MP |
185 | stats->tx_errors = priv->wstats.discard.retries; |
186 | stats->tx_dropped = priv->wstats.discard.retries; | |
92b96797 | 187 | } |