aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/rndis.c
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2005-04-28 16:45:25 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-27 17:43:50 -0400
commit340600ab4cf0cc41efd01a65af97ebb7d35a7f85 (patch)
tree4834521d8ccf7e7b63bbc8500fbe5323ee174b3b /drivers/usb/gadget/rndis.c
parent247f3105636caa9d1d8a4c3dfb755de42633bc80 (diff)
[PATCH] USB: rndis updates (mostly cleanup)
Some bugfixes and lots of cleanup (net code shrink): - On reset, force the RNDIS state machine its initial state - Hook up the RNDIS (outgoing) filters to the CDC mechanism - Lots of cleanup: * Eliminate duplicate copy of OID table; * Unify handlying of the OID "query" response data pointer; * Reduce code duplication for calculating query response lengths; * Remove some checks for "can't happen" errors; * Get rid of debugging #ifdefs by making the debug flag an integer level Most of the patch, by volume, relates to those query response cleanups. It incidentally shaves off a few hundred bytes of object code. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/rndis.c')
-rw-r--r--drivers/usb/gadget/rndis.c509
1 files changed, 263 insertions, 246 deletions
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 7457268d5f28..c9a0af29ecb6 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -41,6 +41,7 @@
41 41
42 42
43#undef RNDIS_PM 43#undef RNDIS_PM
44#undef RNDIS_WAKEUP
44#undef VERBOSE 45#undef VERBOSE
45 46
46#include "rndis.h" 47#include "rndis.h"
@@ -60,7 +61,7 @@
60 } while (0) 61 } while (0)
61static int rndis_debug = 0; 62static int rndis_debug = 0;
62 63
63module_param (rndis_debug, bool, 0); 64module_param (rndis_debug, int, 0);
64MODULE_PARM_DESC (rndis_debug, "enable debugging"); 65MODULE_PARM_DESC (rndis_debug, "enable debugging");
65 66
66#else 67#else
@@ -78,22 +79,103 @@ static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
78static const __le32 rndis_driver_version = __constant_cpu_to_le32 (1); 79static const __le32 rndis_driver_version = __constant_cpu_to_le32 (1);
79 80
80/* Function Prototypes */ 81/* Function Prototypes */
81static int rndis_init_response (int configNr, rndis_init_msg_type *buf);
82static int rndis_query_response (int configNr, rndis_query_msg_type *buf);
83static int rndis_set_response (int configNr, rndis_set_msg_type *buf);
84static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf);
85static int rndis_keepalive_response (int configNr,
86 rndis_keepalive_msg_type *buf);
87
88static rndis_resp_t *rndis_add_response (int configNr, u32 length); 82static rndis_resp_t *rndis_add_response (int configNr, u32 length);
89 83
90 84
85/* supported OIDs */
86static const u32 oid_supported_list [] =
87{
88 /* the general stuff */
89 OID_GEN_SUPPORTED_LIST,
90 OID_GEN_HARDWARE_STATUS,
91 OID_GEN_MEDIA_SUPPORTED,
92 OID_GEN_MEDIA_IN_USE,
93 OID_GEN_MAXIMUM_FRAME_SIZE,
94 OID_GEN_LINK_SPEED,
95 OID_GEN_TRANSMIT_BLOCK_SIZE,
96 OID_GEN_RECEIVE_BLOCK_SIZE,
97 OID_GEN_VENDOR_ID,
98 OID_GEN_VENDOR_DESCRIPTION,
99 OID_GEN_VENDOR_DRIVER_VERSION,
100 OID_GEN_CURRENT_PACKET_FILTER,
101 OID_GEN_MAXIMUM_TOTAL_SIZE,
102 OID_GEN_MEDIA_CONNECT_STATUS,
103 OID_GEN_PHYSICAL_MEDIUM,
104#if 0
105 OID_GEN_RNDIS_CONFIG_PARAMETER,
106#endif
107
108 /* the statistical stuff */
109 OID_GEN_XMIT_OK,
110 OID_GEN_RCV_OK,
111 OID_GEN_XMIT_ERROR,
112 OID_GEN_RCV_ERROR,
113 OID_GEN_RCV_NO_BUFFER,
114#ifdef RNDIS_OPTIONAL_STATS
115 OID_GEN_DIRECTED_BYTES_XMIT,
116 OID_GEN_DIRECTED_FRAMES_XMIT,
117 OID_GEN_MULTICAST_BYTES_XMIT,
118 OID_GEN_MULTICAST_FRAMES_XMIT,
119 OID_GEN_BROADCAST_BYTES_XMIT,
120 OID_GEN_BROADCAST_FRAMES_XMIT,
121 OID_GEN_DIRECTED_BYTES_RCV,
122 OID_GEN_DIRECTED_FRAMES_RCV,
123 OID_GEN_MULTICAST_BYTES_RCV,
124 OID_GEN_MULTICAST_FRAMES_RCV,
125 OID_GEN_BROADCAST_BYTES_RCV,
126 OID_GEN_BROADCAST_FRAMES_RCV,
127 OID_GEN_RCV_CRC_ERROR,
128 OID_GEN_TRANSMIT_QUEUE_LENGTH,
129#endif /* RNDIS_OPTIONAL_STATS */
130
131 /* mandatory 802.3 */
132 /* the general stuff */
133 OID_802_3_PERMANENT_ADDRESS,
134 OID_802_3_CURRENT_ADDRESS,
135 OID_802_3_MULTICAST_LIST,
136 OID_802_3_MAC_OPTIONS,
137 OID_802_3_MAXIMUM_LIST_SIZE,
138
139 /* the statistical stuff */
140 OID_802_3_RCV_ERROR_ALIGNMENT,
141 OID_802_3_XMIT_ONE_COLLISION,
142 OID_802_3_XMIT_MORE_COLLISIONS,
143#ifdef RNDIS_OPTIONAL_STATS
144 OID_802_3_XMIT_DEFERRED,
145 OID_802_3_XMIT_MAX_COLLISIONS,
146 OID_802_3_RCV_OVERRUN,
147 OID_802_3_XMIT_UNDERRUN,
148 OID_802_3_XMIT_HEARTBEAT_FAILURE,
149 OID_802_3_XMIT_TIMES_CRS_LOST,
150 OID_802_3_XMIT_LATE_COLLISIONS,
151#endif /* RNDIS_OPTIONAL_STATS */
152
153#ifdef RNDIS_PM
154 /* PM and wakeup are mandatory for USB: */
155
156 /* power management */
157 OID_PNP_CAPABILITIES,
158 OID_PNP_QUERY_POWER,
159 OID_PNP_SET_POWER,
160
161#ifdef RNDIS_WAKEUP
162 /* wake up host */
163 OID_PNP_ENABLE_WAKE_UP,
164 OID_PNP_ADD_WAKE_UP_PATTERN,
165 OID_PNP_REMOVE_WAKE_UP_PATTERN,
166#endif /* RNDIS_WAKEUP */
167#endif /* RNDIS_PM */
168};
169
170
91/* NDIS Functions */ 171/* NDIS Functions */
92static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) 172static int
173gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
174 rndis_resp_t *r)
93{ 175{
94 int retval = -ENOTSUPP; 176 int retval = -ENOTSUPP;
95 u32 length = 0; 177 u32 length = 4; /* usually */
96 __le32 *tmp; 178 __le32 *outbuf;
97 int i, count; 179 int i, count;
98 rndis_query_cmplt_type *resp; 180 rndis_query_cmplt_type *resp;
99 181
@@ -101,7 +183,22 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
101 resp = (rndis_query_cmplt_type *) r->buf; 183 resp = (rndis_query_cmplt_type *) r->buf;
102 184
103 if (!resp) return -ENOMEM; 185 if (!resp) return -ENOMEM;
104 186
187 if (buf_len && rndis_debug > 1) {
188 DEBUG("query OID %08x value, len %d:\n", OID, buf_len);
189 for (i = 0; i < buf_len; i += 16) {
190 DEBUG ("%03d: %08x %08x %08x %08x\n", i,
191 le32_to_cpup((__le32 *)&buf[i]),
192 le32_to_cpup((__le32 *)&buf[i + 4]),
193 le32_to_cpup((__le32 *)&buf[i + 8]),
194 le32_to_cpup((__le32 *)&buf[i + 12]));
195 }
196 }
197
198 /* response goes here, right after the header */
199 outbuf = (__le32 *) &resp[1];
200 resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
201
105 switch (OID) { 202 switch (OID) {
106 203
107 /* general oids (table 4-1) */ 204 /* general oids (table 4-1) */
@@ -111,42 +208,36 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
111 DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__); 208 DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
112 length = sizeof (oid_supported_list); 209 length = sizeof (oid_supported_list);
113 count = length / sizeof (u32); 210 count = length / sizeof (u32);
114 tmp = (__le32 *) ((u8 *)resp + 24);
115 for (i = 0; i < count; i++) 211 for (i = 0; i < count; i++)
116 tmp[i] = cpu_to_le32 (oid_supported_list[i]); 212 outbuf[i] = cpu_to_le32 (oid_supported_list[i]);
117 retval = 0; 213 retval = 0;
118 break; 214 break;
119 215
120 /* mandatory */ 216 /* mandatory */
121 case OID_GEN_HARDWARE_STATUS: 217 case OID_GEN_HARDWARE_STATUS:
122 DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__); 218 DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
123 length = 4;
124 /* Bogus question! 219 /* Bogus question!
125 * Hardware must be ready to receive high level protocols. 220 * Hardware must be ready to receive high level protocols.
126 * BTW: 221 * BTW:
127 * reddite ergo quae sunt Caesaris Caesari 222 * reddite ergo quae sunt Caesaris Caesari
128 * et quae sunt Dei Deo! 223 * et quae sunt Dei Deo!
129 */ 224 */
130 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0); 225 *outbuf = __constant_cpu_to_le32 (0);
131 retval = 0; 226 retval = 0;
132 break; 227 break;
133 228
134 /* mandatory */ 229 /* mandatory */
135 case OID_GEN_MEDIA_SUPPORTED: 230 case OID_GEN_MEDIA_SUPPORTED:
136 DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__); 231 DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
137 length = 4; 232 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
138 *((__le32 *) resp + 6) = cpu_to_le32 (
139 rndis_per_dev_params [configNr].medium);
140 retval = 0; 233 retval = 0;
141 break; 234 break;
142 235
143 /* mandatory */ 236 /* mandatory */
144 case OID_GEN_MEDIA_IN_USE: 237 case OID_GEN_MEDIA_IN_USE:
145 DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__); 238 DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
146 length = 4;
147 /* one medium, one transport... (maybe you do it better) */ 239 /* one medium, one transport... (maybe you do it better) */
148 *((__le32 *) resp + 6) = cpu_to_le32 ( 240 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
149 rndis_per_dev_params [configNr].medium);
150 retval = 0; 241 retval = 0;
151 break; 242 break;
152 243
@@ -154,25 +245,21 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
154 case OID_GEN_MAXIMUM_FRAME_SIZE: 245 case OID_GEN_MAXIMUM_FRAME_SIZE:
155 DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__); 246 DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
156 if (rndis_per_dev_params [configNr].dev) { 247 if (rndis_per_dev_params [configNr].dev) {
157 length = 4; 248 *outbuf = cpu_to_le32 (
158 *((__le32 *) resp + 6) = cpu_to_le32 (
159 rndis_per_dev_params [configNr].dev->mtu); 249 rndis_per_dev_params [configNr].dev->mtu);
160 retval = 0; 250 retval = 0;
161 } else {
162 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
163 retval = 0;
164 } 251 }
165 break; 252 break;
166 253
167 /* mandatory */ 254 /* mandatory */
168 case OID_GEN_LINK_SPEED: 255 case OID_GEN_LINK_SPEED:
169// DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); 256 if (rndis_debug > 1)
170 length = 4; 257 DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
171 if (rndis_per_dev_params [configNr].media_state 258 if (rndis_per_dev_params [configNr].media_state
172 == NDIS_MEDIA_STATE_DISCONNECTED) 259 == NDIS_MEDIA_STATE_DISCONNECTED)
173 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0); 260 *outbuf = __constant_cpu_to_le32 (0);
174 else 261 else
175 *((__le32 *) resp + 6) = cpu_to_le32 ( 262 *outbuf = cpu_to_le32 (
176 rndis_per_dev_params [configNr].speed); 263 rndis_per_dev_params [configNr].speed);
177 retval = 0; 264 retval = 0;
178 break; 265 break;
@@ -181,8 +268,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
181 case OID_GEN_TRANSMIT_BLOCK_SIZE: 268 case OID_GEN_TRANSMIT_BLOCK_SIZE:
182 DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__); 269 DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
183 if (rndis_per_dev_params [configNr].dev) { 270 if (rndis_per_dev_params [configNr].dev) {
184 length = 4; 271 *outbuf = cpu_to_le32 (
185 *((__le32 *) resp + 6) = cpu_to_le32 (
186 rndis_per_dev_params [configNr].dev->mtu); 272 rndis_per_dev_params [configNr].dev->mtu);
187 retval = 0; 273 retval = 0;
188 } 274 }
@@ -192,8 +278,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
192 case OID_GEN_RECEIVE_BLOCK_SIZE: 278 case OID_GEN_RECEIVE_BLOCK_SIZE:
193 DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__); 279 DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
194 if (rndis_per_dev_params [configNr].dev) { 280 if (rndis_per_dev_params [configNr].dev) {
195 length = 4; 281 *outbuf = cpu_to_le32 (
196 *((__le32 *) resp + 6) = cpu_to_le32 (
197 rndis_per_dev_params [configNr].dev->mtu); 282 rndis_per_dev_params [configNr].dev->mtu);
198 retval = 0; 283 retval = 0;
199 } 284 }
@@ -202,8 +287,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
202 /* mandatory */ 287 /* mandatory */
203 case OID_GEN_VENDOR_ID: 288 case OID_GEN_VENDOR_ID:
204 DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__); 289 DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
205 length = 4; 290 *outbuf = cpu_to_le32 (
206 *((__le32 *) resp + 6) = cpu_to_le32 (
207 rndis_per_dev_params [configNr].vendorID); 291 rndis_per_dev_params [configNr].vendorID);
208 retval = 0; 292 retval = 0;
209 break; 293 break;
@@ -212,51 +296,44 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
212 case OID_GEN_VENDOR_DESCRIPTION: 296 case OID_GEN_VENDOR_DESCRIPTION:
213 DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__); 297 DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
214 length = strlen (rndis_per_dev_params [configNr].vendorDescr); 298 length = strlen (rndis_per_dev_params [configNr].vendorDescr);
215 memcpy ((u8 *) resp + 24, 299 memcpy (outbuf,
216 rndis_per_dev_params [configNr].vendorDescr, length); 300 rndis_per_dev_params [configNr].vendorDescr, length);
217 retval = 0; 301 retval = 0;
218 break; 302 break;
219 303
220 case OID_GEN_VENDOR_DRIVER_VERSION: 304 case OID_GEN_VENDOR_DRIVER_VERSION:
221 DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__); 305 DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
222 length = 4;
223 /* Created as LE */ 306 /* Created as LE */
224 *((__le32 *) resp + 6) = rndis_driver_version; 307 *outbuf = rndis_driver_version;
225 retval = 0; 308 retval = 0;
226 break; 309 break;
227 310
228 /* mandatory */ 311 /* mandatory */
229 case OID_GEN_CURRENT_PACKET_FILTER: 312 case OID_GEN_CURRENT_PACKET_FILTER:
230 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__); 313 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
231 length = 4; 314 *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
232 *((__le32 *) resp + 6) = cpu_to_le32 (
233 rndis_per_dev_params[configNr].filter);
234 retval = 0; 315 retval = 0;
235 break; 316 break;
236 317
237 /* mandatory */ 318 /* mandatory */
238 case OID_GEN_MAXIMUM_TOTAL_SIZE: 319 case OID_GEN_MAXIMUM_TOTAL_SIZE:
239 DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__); 320 DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
240 length = 4; 321 *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
241 *((__le32 *) resp + 6) = __constant_cpu_to_le32(
242 RNDIS_MAX_TOTAL_SIZE);
243 retval = 0; 322 retval = 0;
244 break; 323 break;
245 324
246 /* mandatory */ 325 /* mandatory */
247 case OID_GEN_MEDIA_CONNECT_STATUS: 326 case OID_GEN_MEDIA_CONNECT_STATUS:
248 DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__); 327 if (rndis_debug > 1)
249 length = 4; 328 DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
250 *((__le32 *) resp + 6) = cpu_to_le32 ( 329 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
251 rndis_per_dev_params [configNr]
252 .media_state); 330 .media_state);
253 retval = 0; 331 retval = 0;
254 break; 332 break;
255 333
256 case OID_GEN_PHYSICAL_MEDIUM: 334 case OID_GEN_PHYSICAL_MEDIUM:
257 DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__); 335 DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
258 length = 4; 336 *outbuf = __constant_cpu_to_le32 (0);
259 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
260 retval = 0; 337 retval = 0;
261 break; 338 break;
262 339
@@ -266,8 +343,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
266 */ 343 */
267 case OID_GEN_MAC_OPTIONS: /* from WinME */ 344 case OID_GEN_MAC_OPTIONS: /* from WinME */
268 DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__); 345 DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
269 length = 4; 346 *outbuf = __constant_cpu_to_le32(
270 *((__le32 *) resp + 6) = __constant_cpu_to_le32(
271 NDIS_MAC_OPTION_RECEIVE_SERIALIZED 347 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
272 | NDIS_MAC_OPTION_FULL_DUPLEX); 348 | NDIS_MAC_OPTION_FULL_DUPLEX);
273 retval = 0; 349 retval = 0;
@@ -277,62 +353,49 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
277 353
278 /* mandatory */ 354 /* mandatory */
279 case OID_GEN_XMIT_OK: 355 case OID_GEN_XMIT_OK:
280 DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__); 356 if (rndis_debug > 1)
357 DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
281 if (rndis_per_dev_params [configNr].stats) { 358 if (rndis_per_dev_params [configNr].stats) {
282 length = 4; 359 *outbuf = cpu_to_le32 (
283 *((__le32 *) resp + 6) = cpu_to_le32 (
284 rndis_per_dev_params [configNr].stats->tx_packets - 360 rndis_per_dev_params [configNr].stats->tx_packets -
285 rndis_per_dev_params [configNr].stats->tx_errors - 361 rndis_per_dev_params [configNr].stats->tx_errors -
286 rndis_per_dev_params [configNr].stats->tx_dropped); 362 rndis_per_dev_params [configNr].stats->tx_dropped);
287 retval = 0; 363 retval = 0;
288 } else {
289 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
290 retval = 0;
291 } 364 }
292 break; 365 break;
293 366
294 /* mandatory */ 367 /* mandatory */
295 case OID_GEN_RCV_OK: 368 case OID_GEN_RCV_OK:
296 DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__); 369 if (rndis_debug > 1)
370 DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
297 if (rndis_per_dev_params [configNr].stats) { 371 if (rndis_per_dev_params [configNr].stats) {
298 length = 4; 372 *outbuf = cpu_to_le32 (
299 *((__le32 *) resp + 6) = cpu_to_le32 (
300 rndis_per_dev_params [configNr].stats->rx_packets - 373 rndis_per_dev_params [configNr].stats->rx_packets -
301 rndis_per_dev_params [configNr].stats->rx_errors - 374 rndis_per_dev_params [configNr].stats->rx_errors -
302 rndis_per_dev_params [configNr].stats->rx_dropped); 375 rndis_per_dev_params [configNr].stats->rx_dropped);
303 retval = 0; 376 retval = 0;
304 } else {
305 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
306 retval = 0;
307 } 377 }
308 break; 378 break;
309 379
310 /* mandatory */ 380 /* mandatory */
311 case OID_GEN_XMIT_ERROR: 381 case OID_GEN_XMIT_ERROR:
312 DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__); 382 if (rndis_debug > 1)
383 DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
313 if (rndis_per_dev_params [configNr].stats) { 384 if (rndis_per_dev_params [configNr].stats) {
314 length = 4; 385 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
315 *((__le32 *) resp + 6) = cpu_to_le32 (
316 rndis_per_dev_params [configNr]
317 .stats->tx_errors); 386 .stats->tx_errors);
318 retval = 0; 387 retval = 0;
319 } else {
320 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
321 retval = 0;
322 } 388 }
323 break; 389 break;
324 390
325 /* mandatory */ 391 /* mandatory */
326 case OID_GEN_RCV_ERROR: 392 case OID_GEN_RCV_ERROR:
327 DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__); 393 if (rndis_debug > 1)
394 DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
328 if (rndis_per_dev_params [configNr].stats) { 395 if (rndis_per_dev_params [configNr].stats) {
329 *((__le32 *) resp + 6) = cpu_to_le32 ( 396 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
330 rndis_per_dev_params [configNr]
331 .stats->rx_errors); 397 .stats->rx_errors);
332 retval = 0; 398 retval = 0;
333 } else {
334 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
335 retval = 0;
336 } 399 }
337 break; 400 break;
338 401
@@ -340,13 +403,9 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
340 case OID_GEN_RCV_NO_BUFFER: 403 case OID_GEN_RCV_NO_BUFFER:
341 DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__); 404 DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
342 if (rndis_per_dev_params [configNr].stats) { 405 if (rndis_per_dev_params [configNr].stats) {
343 *((__le32 *) resp + 6) = cpu_to_le32 ( 406 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
344 rndis_per_dev_params [configNr]
345 .stats->rx_dropped); 407 .stats->rx_dropped);
346 retval = 0; 408 retval = 0;
347 } else {
348 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
349 retval = 0;
350 } 409 }
351 break; 410 break;
352 411
@@ -359,8 +418,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
359 * divided by weight of Alpha Centauri 418 * divided by weight of Alpha Centauri
360 */ 419 */
361 if (rndis_per_dev_params [configNr].stats) { 420 if (rndis_per_dev_params [configNr].stats) {
362 length = 4; 421 *outbuf = cpu_to_le32 (
363 *((__le32 *) resp + 6) = cpu_to_le32 (
364 (rndis_per_dev_params [configNr] 422 (rndis_per_dev_params [configNr]
365 .stats->tx_packets - 423 .stats->tx_packets -
366 rndis_per_dev_params [configNr] 424 rndis_per_dev_params [configNr]
@@ -369,9 +427,6 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
369 .stats->tx_dropped) 427 .stats->tx_dropped)
370 * 123); 428 * 123);
371 retval = 0; 429 retval = 0;
372 } else {
373 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
374 retval = 0;
375 } 430 }
376 break; 431 break;
377 432
@@ -379,8 +434,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
379 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__); 434 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
380 /* dito */ 435 /* dito */
381 if (rndis_per_dev_params [configNr].stats) { 436 if (rndis_per_dev_params [configNr].stats) {
382 length = 4; 437 *outbuf = cpu_to_le32 (
383 *((__le32 *) resp + 6) = cpu_to_le32 (
384 (rndis_per_dev_params [configNr] 438 (rndis_per_dev_params [configNr]
385 .stats->tx_packets - 439 .stats->tx_packets -
386 rndis_per_dev_params [configNr] 440 rndis_per_dev_params [configNr]
@@ -389,144 +443,105 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
389 .stats->tx_dropped) 443 .stats->tx_dropped)
390 / 123); 444 / 123);
391 retval = 0; 445 retval = 0;
392 } else {
393 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
394 retval = 0;
395 } 446 }
396 break; 447 break;
397 448
398 case OID_GEN_MULTICAST_BYTES_XMIT: 449 case OID_GEN_MULTICAST_BYTES_XMIT:
399 DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__); 450 DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
400 if (rndis_per_dev_params [configNr].stats) { 451 if (rndis_per_dev_params [configNr].stats) {
401 *((__le32 *) resp + 6) = cpu_to_le32 ( 452 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
402 rndis_per_dev_params [configNr]
403 .stats->multicast*1234); 453 .stats->multicast*1234);
404 retval = 0; 454 retval = 0;
405 } else {
406 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
407 retval = 0;
408 } 455 }
409 break; 456 break;
410 457
411 case OID_GEN_MULTICAST_FRAMES_XMIT: 458 case OID_GEN_MULTICAST_FRAMES_XMIT:
412 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__); 459 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
413 if (rndis_per_dev_params [configNr].stats) { 460 if (rndis_per_dev_params [configNr].stats) {
414 *((__le32 *) resp + 6) = cpu_to_le32 ( 461 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
415 rndis_per_dev_params [configNr]
416 .stats->multicast); 462 .stats->multicast);
417 retval = 0; 463 retval = 0;
418 } else {
419 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
420 retval = 0;
421 } 464 }
422 break; 465 break;
423 466
424 case OID_GEN_BROADCAST_BYTES_XMIT: 467 case OID_GEN_BROADCAST_BYTES_XMIT:
425 DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__); 468 DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
426 if (rndis_per_dev_params [configNr].stats) { 469 if (rndis_per_dev_params [configNr].stats) {
427 *((__le32 *) resp + 6) = cpu_to_le32 ( 470 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
428 rndis_per_dev_params [configNr]
429 .stats->tx_packets/42*255); 471 .stats->tx_packets/42*255);
430 retval = 0; 472 retval = 0;
431 } else {
432 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
433 retval = 0;
434 } 473 }
435 break; 474 break;
436 475
437 case OID_GEN_BROADCAST_FRAMES_XMIT: 476 case OID_GEN_BROADCAST_FRAMES_XMIT:
438 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); 477 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
439 if (rndis_per_dev_params [configNr].stats) { 478 if (rndis_per_dev_params [configNr].stats) {
440 *((__le32 *) resp + 6) = cpu_to_le32 ( 479 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
441 rndis_per_dev_params [configNr]
442 .stats->tx_packets/42); 480 .stats->tx_packets/42);
443 retval = 0; 481 retval = 0;
444 } else {
445 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
446 retval = 0;
447 } 482 }
448 break; 483 break;
449 484
450 case OID_GEN_DIRECTED_BYTES_RCV: 485 case OID_GEN_DIRECTED_BYTES_RCV:
451 DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); 486 DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
452 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0); 487 *outbuf = __constant_cpu_to_le32 (0);
453 retval = 0; 488 retval = 0;
454 break; 489 break;
455 490
456 case OID_GEN_DIRECTED_FRAMES_RCV: 491 case OID_GEN_DIRECTED_FRAMES_RCV:
457 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); 492 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
458 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0); 493 *outbuf = __constant_cpu_to_le32 (0);
459 retval = 0; 494 retval = 0;
460 break; 495 break;
461 496
462 case OID_GEN_MULTICAST_BYTES_RCV: 497 case OID_GEN_MULTICAST_BYTES_RCV:
463 DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); 498 DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
464 if (rndis_per_dev_params [configNr].stats) { 499 if (rndis_per_dev_params [configNr].stats) {
465 *((__le32 *) resp + 6) = cpu_to_le32 ( 500 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
466 rndis_per_dev_params [configNr]
467 .stats->multicast * 1111); 501 .stats->multicast * 1111);
468 retval = 0; 502 retval = 0;
469 } else {
470 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
471 retval = 0;
472 } 503 }
473 break; 504 break;
474 505
475 case OID_GEN_MULTICAST_FRAMES_RCV: 506 case OID_GEN_MULTICAST_FRAMES_RCV:
476 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); 507 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
477 if (rndis_per_dev_params [configNr].stats) { 508 if (rndis_per_dev_params [configNr].stats) {
478 *((__le32 *) resp + 6) = cpu_to_le32 ( 509 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
479 rndis_per_dev_params [configNr]
480 .stats->multicast); 510 .stats->multicast);
481 retval = 0; 511 retval = 0;
482 } else {
483 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
484 retval = 0;
485 } 512 }
486 break; 513 break;
487 514
488 case OID_GEN_BROADCAST_BYTES_RCV: 515 case OID_GEN_BROADCAST_BYTES_RCV:
489 DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); 516 DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
490 if (rndis_per_dev_params [configNr].stats) { 517 if (rndis_per_dev_params [configNr].stats) {
491 *((__le32 *) resp + 6) = cpu_to_le32 ( 518 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
492 rndis_per_dev_params [configNr]
493 .stats->rx_packets/42*255); 519 .stats->rx_packets/42*255);
494 retval = 0; 520 retval = 0;
495 } else {
496 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
497 retval = 0;
498 } 521 }
499 break; 522 break;
500 523
501 case OID_GEN_BROADCAST_FRAMES_RCV: 524 case OID_GEN_BROADCAST_FRAMES_RCV:
502 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); 525 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
503 if (rndis_per_dev_params [configNr].stats) { 526 if (rndis_per_dev_params [configNr].stats) {
504 *((__le32 *) resp + 6) = cpu_to_le32 ( 527 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
505 rndis_per_dev_params [configNr]
506 .stats->rx_packets/42); 528 .stats->rx_packets/42);
507 retval = 0; 529 retval = 0;
508 } else {
509 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
510 retval = 0;
511 } 530 }
512 break; 531 break;
513 532
514 case OID_GEN_RCV_CRC_ERROR: 533 case OID_GEN_RCV_CRC_ERROR:
515 DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); 534 DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
516 if (rndis_per_dev_params [configNr].stats) { 535 if (rndis_per_dev_params [configNr].stats) {
517 *((__le32 *) resp + 6) = cpu_to_le32 ( 536 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
518 rndis_per_dev_params [configNr]
519 .stats->rx_crc_errors); 537 .stats->rx_crc_errors);
520 retval = 0; 538 retval = 0;
521 } else {
522 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
523 retval = 0;
524 } 539 }
525 break; 540 break;
526 541
527 case OID_GEN_TRANSMIT_QUEUE_LENGTH: 542 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
528 DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); 543 DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
529 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0); 544 *outbuf = __constant_cpu_to_le32 (0);
530 retval = 0; 545 retval = 0;
531 break; 546 break;
532#endif /* RNDIS_OPTIONAL_STATS */ 547#endif /* RNDIS_OPTIONAL_STATS */
@@ -538,13 +553,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
538 DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); 553 DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
539 if (rndis_per_dev_params [configNr].dev) { 554 if (rndis_per_dev_params [configNr].dev) {
540 length = ETH_ALEN; 555 length = ETH_ALEN;
541 memcpy ((u8 *) resp + 24, 556 memcpy (outbuf,
542 rndis_per_dev_params [configNr].host_mac, 557 rndis_per_dev_params [configNr].host_mac,
543 length); 558 length);
544 retval = 0; 559 retval = 0;
545 } else {
546 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
547 retval = 0;
548 } 560 }
549 break; 561 break;
550 562
@@ -553,7 +565,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
553 DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); 565 DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
554 if (rndis_per_dev_params [configNr].dev) { 566 if (rndis_per_dev_params [configNr].dev) {
555 length = ETH_ALEN; 567 length = ETH_ALEN;
556 memcpy ((u8 *) resp + 24, 568 memcpy (outbuf,
557 rndis_per_dev_params [configNr].host_mac, 569 rndis_per_dev_params [configNr].host_mac,
558 length); 570 length);
559 retval = 0; 571 retval = 0;
@@ -563,18 +575,16 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
563 /* mandatory */ 575 /* mandatory */
564 case OID_802_3_MULTICAST_LIST: 576 case OID_802_3_MULTICAST_LIST:
565 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); 577 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
566 length = 4;
567 /* Multicast base address only */ 578 /* Multicast base address only */
568 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0xE0000000); 579 *outbuf = __constant_cpu_to_le32 (0xE0000000);
569 retval = 0; 580 retval = 0;
570 break; 581 break;
571 582
572 /* mandatory */ 583 /* mandatory */
573 case OID_802_3_MAXIMUM_LIST_SIZE: 584 case OID_802_3_MAXIMUM_LIST_SIZE:
574 DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); 585 DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
575 length = 4;
576 /* Multicast base address only */ 586 /* Multicast base address only */
577 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (1); 587 *outbuf = __constant_cpu_to_le32 (1);
578 retval = 0; 588 retval = 0;
579 break; 589 break;
580 590
@@ -587,11 +597,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
587 /* mandatory */ 597 /* mandatory */
588 case OID_802_3_RCV_ERROR_ALIGNMENT: 598 case OID_802_3_RCV_ERROR_ALIGNMENT:
589 DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__); 599 DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
590 if (rndis_per_dev_params [configNr].stats) 600 if (rndis_per_dev_params [configNr].stats) {
591 { 601 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
592 length = 4;
593 *((__le32 *) resp + 6) = cpu_to_le32 (
594 rndis_per_dev_params [configNr]
595 .stats->rx_frame_errors); 602 .stats->rx_frame_errors);
596 retval = 0; 603 retval = 0;
597 } 604 }
@@ -600,16 +607,14 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
600 /* mandatory */ 607 /* mandatory */
601 case OID_802_3_XMIT_ONE_COLLISION: 608 case OID_802_3_XMIT_ONE_COLLISION:
602 DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); 609 DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
603 length = 4; 610 *outbuf = __constant_cpu_to_le32 (0);
604 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
605 retval = 0; 611 retval = 0;
606 break; 612 break;
607 613
608 /* mandatory */ 614 /* mandatory */
609 case OID_802_3_XMIT_MORE_COLLISIONS: 615 case OID_802_3_XMIT_MORE_COLLISIONS:
610 DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); 616 DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
611 length = 4; 617 *outbuf = __constant_cpu_to_le32 (0);
612 *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
613 retval = 0; 618 retval = 0;
614 break; 619 break;
615 620
@@ -655,27 +660,18 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
655 case OID_PNP_CAPABILITIES: 660 case OID_PNP_CAPABILITIES:
656 DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__); 661 DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__);
657 662
658 /* just PM, and remote wakeup on link status change 663 /* for now, no wakeup capabilities */
659 * (not magic packet or pattern match)
660 */
661 length = sizeof (struct NDIS_PNP_CAPABILITIES); 664 length = sizeof (struct NDIS_PNP_CAPABILITIES);
662 memset (resp, 0, length); 665 memset(outbuf, 0, length);
663 {
664 struct NDIS_PNP_CAPABILITIES *caps = (void *) resp;
665
666 caps->Flags = NDIS_DEVICE_WAKE_UP_ENABLE;
667 caps->WakeUpCapabilities.MinLinkChangeWakeUp
668 = NdisDeviceStateD3;
669
670 /* FIXME then use usb_gadget_wakeup(), and
671 * set USB_CONFIG_ATT_WAKEUP in config desc
672 */
673 }
674 retval = 0; 666 retval = 0;
675 break; 667 break;
676 case OID_PNP_QUERY_POWER: 668 case OID_PNP_QUERY_POWER:
677 DEBUG("%s: OID_PNP_QUERY_POWER\n", __FUNCTION__); 669 DEBUG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__,
678 /* sure, handle any power state that maps to USB suspend */ 670 le32_to_cpup((__le32 *) buf) - 1);
671 /* only suspend is a real power state, and
672 * it can't be entered by OID_PNP_SET_POWER...
673 */
674 length = 0;
679 retval = 0; 675 retval = 0;
680 break; 676 break;
681#endif 677#endif
@@ -684,11 +680,12 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
684 printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", 680 printk (KERN_WARNING "%s: query unknown OID 0x%08X\n",
685 __FUNCTION__, OID); 681 __FUNCTION__, OID);
686 } 682 }
683 if (retval < 0)
684 length = 0;
687 685
688 resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
689 resp->InformationBufferLength = cpu_to_le32 (length); 686 resp->InformationBufferLength = cpu_to_le32 (length);
690 resp->MessageLength = cpu_to_le32 (24 + length); 687 r->length = length + sizeof *resp;
691 r->length = 24 + length; 688 resp->MessageLength = cpu_to_le32 (r->length);
692 return retval; 689 return retval;
693} 690}
694 691
@@ -705,45 +702,40 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
705 if (!resp) 702 if (!resp)
706 return -ENOMEM; 703 return -ENOMEM;
707 704
708 DEBUG("set OID %08x value, len %d:\n", OID, buf_len); 705 if (buf_len && rndis_debug > 1) {
709 for (i = 0; i < buf_len; i += 16) { 706 DEBUG("set OID %08x value, len %d:\n", OID, buf_len);
710 DEBUG ("%03d: " 707 for (i = 0; i < buf_len; i += 16) {
711 " %02x %02x %02x %02x" 708 DEBUG ("%03d: %08x %08x %08x %08x\n", i,
712 " %02x %02x %02x %02x" 709 le32_to_cpup((__le32 *)&buf[i]),
713 " %02x %02x %02x %02x" 710 le32_to_cpup((__le32 *)&buf[i + 4]),
714 " %02x %02x %02x %02x" 711 le32_to_cpup((__le32 *)&buf[i + 8]),
715 "\n", 712 le32_to_cpup((__le32 *)&buf[i + 12]));
716 i, 713 }
717 buf[i], buf [i+1],
718 buf[i+2], buf[i+3],
719 buf[i+4], buf [i+5],
720 buf[i+6], buf[i+7],
721 buf[i+8], buf [i+9],
722 buf[i+10], buf[i+11],
723 buf[i+12], buf [i+13],
724 buf[i+14], buf[i+15]);
725 } 714 }
726 715
716 params = &rndis_per_dev_params [configNr];
727 switch (OID) { 717 switch (OID) {
728 case OID_GEN_CURRENT_PACKET_FILTER: 718 case OID_GEN_CURRENT_PACKET_FILTER:
729 params = &rndis_per_dev_params [configNr];
730 retval = 0;
731 719
732 /* FIXME use these NDIS_PACKET_TYPE_* bitflags to 720 /* these NDIS_PACKET_TYPE_* bitflags are shared with
733 * set the cdc_filter; it's not RNDIS-specific 721 * cdc_filter; it's not RNDIS-specific
734 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in: 722 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
735 * PROMISCUOUS, DIRECTED, 723 * PROMISCUOUS, DIRECTED,
736 * MULTICAST, ALL_MULTICAST, BROADCAST 724 * MULTICAST, ALL_MULTICAST, BROADCAST
737 */ 725 */
738 params->filter = le32_to_cpup((__le32 *)buf); 726 *params->filter = (u16) le32_to_cpup((__le32 *)buf);
739 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", 727 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
740 __FUNCTION__, params->filter); 728 __FUNCTION__, *params->filter);
741 729
742 /* this call has a significant side effect: it's 730 /* this call has a significant side effect: it's
743 * what makes the packet flow start and stop, like 731 * what makes the packet flow start and stop, like
744 * activating the CDC Ethernet altsetting. 732 * activating the CDC Ethernet altsetting.
745 */ 733 */
746 if (params->filter) { 734#ifdef RNDIS_PM
735update_linkstate:
736#endif
737 retval = 0;
738 if (*params->filter) {
747 params->state = RNDIS_DATA_INITIALIZED; 739 params->state = RNDIS_DATA_INITIALIZED;
748 netif_carrier_on(params->dev); 740 netif_carrier_on(params->dev);
749 if (netif_running(params->dev)) 741 if (netif_running(params->dev))
@@ -776,21 +768,34 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
776 768
777#ifdef RNDIS_PM 769#ifdef RNDIS_PM
778 case OID_PNP_SET_POWER: 770 case OID_PNP_SET_POWER:
779 DEBUG ("OID_PNP_SET_POWER\n"); 771 /* The only real power state is USB suspend, and RNDIS requests
780 /* sure, handle any power state that maps to USB suspend */ 772 * can't enter it; this one isn't really about power. After
781 retval = 0; 773 * resuming, Windows forces a reset, and then SET_POWER D0.
782 break; 774 * FIXME ... then things go batty; Windows wedges itself.
783 775 */
784 case OID_PNP_ENABLE_WAKE_UP: 776 i = le32_to_cpup((__force __le32 *)buf);
785 /* always-connected ... */ 777 DEBUG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1);
786 DEBUG ("OID_PNP_ENABLE_WAKE_UP\n"); 778 switch (i) {
787 retval = 0; 779 case NdisDeviceStateD0:
780 *params->filter = params->saved_filter;
781 goto update_linkstate;
782 case NdisDeviceStateD3:
783 case NdisDeviceStateD2:
784 case NdisDeviceStateD1:
785 params->saved_filter = *params->filter;
786 retval = 0;
787 break;
788 }
788 break; 789 break;
789 790
790 // no PM resume patterns supported (specified where?) 791#ifdef RNDIS_WAKEUP
791 // so OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN always fails 792 // no wakeup support advertised, so wakeup OIDs always fail:
793 // - OID_PNP_ENABLE_WAKE_UP
794 // - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN
792#endif 795#endif
793 796
797#endif /* RNDIS_PM */
798
794 default: 799 default:
795 printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", 800 printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n",
796 __FUNCTION__, OID, buf_len); 801 __FUNCTION__, OID, buf_len);
@@ -811,13 +816,10 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
811 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; 816 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
812 817
813 r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type)); 818 r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
814 819 if (!r)
815 if (!r) return -ENOMEM; 820 return -ENOMEM;
816
817 resp = (rndis_init_cmplt_type *) r->buf; 821 resp = (rndis_init_cmplt_type *) r->buf;
818 822
819 if (!resp) return -ENOMEM;
820
821 resp->MessageType = __constant_cpu_to_le32 ( 823 resp->MessageType = __constant_cpu_to_le32 (
822 REMOTE_NDIS_INITIALIZE_CMPLT); 824 REMOTE_NDIS_INITIALIZE_CMPLT);
823 resp->MessageLength = __constant_cpu_to_le32 (52); 825 resp->MessageLength = __constant_cpu_to_le32 (52);
@@ -857,20 +859,22 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
857 * oid_supported_list is the largest answer 859 * oid_supported_list is the largest answer
858 */ 860 */
859 r = rndis_add_response (configNr, sizeof (oid_supported_list)); 861 r = rndis_add_response (configNr, sizeof (oid_supported_list));
860 862 if (!r)
861 if (!r) return -ENOMEM; 863 return -ENOMEM;
862 resp = (rndis_query_cmplt_type *) r->buf; 864 resp = (rndis_query_cmplt_type *) r->buf;
863 865
864 if (!resp) return -ENOMEM;
865
866 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); 866 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
867 resp->MessageLength = __constant_cpu_to_le32 (24);
868 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ 867 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
869 868
870 if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID), r)) { 869 if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID),
870 le32_to_cpu(buf->InformationBufferOffset)
871 + 8 + (u8 *) buf,
872 le32_to_cpu(buf->InformationBufferLength),
873 r)) {
871 /* OID not supported */ 874 /* OID not supported */
872 resp->Status = __constant_cpu_to_le32 ( 875 resp->Status = __constant_cpu_to_le32 (
873 RNDIS_STATUS_NOT_SUPPORTED); 876 RNDIS_STATUS_NOT_SUPPORTED);
877 resp->MessageLength = __constant_cpu_to_le32 (sizeof *resp);
874 resp->InformationBufferLength = __constant_cpu_to_le32 (0); 878 resp->InformationBufferLength = __constant_cpu_to_le32 (0);
875 resp->InformationBufferOffset = __constant_cpu_to_le32 (0); 879 resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
876 } else 880 } else
@@ -889,10 +893,9 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
889 rndis_resp_t *r; 893 rndis_resp_t *r;
890 894
891 r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); 895 r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
892 896 if (!r)
893 if (!r) return -ENOMEM; 897 return -ENOMEM;
894 resp = (rndis_set_cmplt_type *) r->buf; 898 resp = (rndis_set_cmplt_type *) r->buf;
895 if (!resp) return -ENOMEM;
896 899
897 BufLength = le32_to_cpu (buf->InformationBufferLength); 900 BufLength = le32_to_cpu (buf->InformationBufferLength);
898 BufOffset = le32_to_cpu (buf->InformationBufferOffset); 901 BufOffset = le32_to_cpu (buf->InformationBufferOffset);
@@ -930,10 +933,9 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
930 rndis_resp_t *r; 933 rndis_resp_t *r;
931 934
932 r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type)); 935 r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
933 936 if (!r)
934 if (!r) return -ENOMEM; 937 return -ENOMEM;
935 resp = (rndis_reset_cmplt_type *) r->buf; 938 resp = (rndis_reset_cmplt_type *) r->buf;
936 if (!resp) return -ENOMEM;
937 939
938 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); 940 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
939 resp->MessageLength = __constant_cpu_to_le32 (16); 941 resp->MessageLength = __constant_cpu_to_le32 (16);
@@ -957,8 +959,9 @@ static int rndis_keepalive_response (int configNr,
957 /* host "should" check only in RNDIS_DATA_INITIALIZED state */ 959 /* host "should" check only in RNDIS_DATA_INITIALIZED state */
958 960
959 r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type)); 961 r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
962 if (!r)
963 return -ENOMEM;
960 resp = (rndis_keepalive_cmplt_type *) r->buf; 964 resp = (rndis_keepalive_cmplt_type *) r->buf;
961 if (!resp) return -ENOMEM;
962 965
963 resp->MessageType = __constant_cpu_to_le32 ( 966 resp->MessageType = __constant_cpu_to_le32 (
964 REMOTE_NDIS_KEEPALIVE_CMPLT); 967 REMOTE_NDIS_KEEPALIVE_CMPLT);
@@ -987,10 +990,9 @@ static int rndis_indicate_status_msg (int configNr, u32 status)
987 990
988 r = rndis_add_response (configNr, 991 r = rndis_add_response (configNr,
989 sizeof (rndis_indicate_status_msg_type)); 992 sizeof (rndis_indicate_status_msg_type));
990 if (!r) return -ENOMEM; 993 if (!r)
991 994 return -ENOMEM;
992 resp = (rndis_indicate_status_msg_type *) r->buf; 995 resp = (rndis_indicate_status_msg_type *) r->buf;
993 if (!resp) return -ENOMEM;
994 996
995 resp->MessageType = __constant_cpu_to_le32 ( 997 resp->MessageType = __constant_cpu_to_le32 (
996 REMOTE_NDIS_INDICATE_STATUS_MSG); 998 REMOTE_NDIS_INDICATE_STATUS_MSG);
@@ -1021,6 +1023,15 @@ int rndis_signal_disconnect (int configNr)
1021 RNDIS_STATUS_MEDIA_DISCONNECT); 1023 RNDIS_STATUS_MEDIA_DISCONNECT);
1022} 1024}
1023 1025
1026void rndis_uninit (int configNr)
1027{
1028 if (configNr >= RNDIS_MAX_CONFIGS)
1029 return;
1030 rndis_per_dev_params [configNr].used = 0;
1031 rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;
1032 return;
1033}
1034
1024void rndis_set_host_mac (int configNr, const u8 *addr) 1035void rndis_set_host_mac (int configNr, const u8 *addr)
1025{ 1036{
1026 rndis_per_dev_params [configNr].host_mac = addr; 1037 rndis_per_dev_params [configNr].host_mac = addr;
@@ -1046,9 +1057,13 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
1046 return -ENOTSUPP; 1057 return -ENOTSUPP;
1047 params = &rndis_per_dev_params [configNr]; 1058 params = &rndis_per_dev_params [configNr];
1048 1059
1060 /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
1061 * rx/tx statistics and link status, in addition to KEEPALIVE traffic
1062 * and normal HC level polling to see if there's any IN traffic.
1063 */
1064
1049 /* For USB: responses may take up to 10 seconds */ 1065 /* For USB: responses may take up to 10 seconds */
1050 switch (MsgType) 1066 switch (MsgType) {
1051 {
1052 case REMOTE_NDIS_INITIALIZE_MSG: 1067 case REMOTE_NDIS_INITIALIZE_MSG:
1053 DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", 1068 DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
1054 __FUNCTION__ ); 1069 __FUNCTION__ );
@@ -1082,10 +1097,9 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
1082 1097
1083 case REMOTE_NDIS_KEEPALIVE_MSG: 1098 case REMOTE_NDIS_KEEPALIVE_MSG:
1084 /* For USB: host does this every 5 seconds */ 1099 /* For USB: host does this every 5 seconds */
1085#ifdef VERBOSE 1100 if (rndis_debug > 1)
1086 DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", 1101 DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
1087 __FUNCTION__ ); 1102 __FUNCTION__ );
1088#endif
1089 return rndis_keepalive_response (configNr, 1103 return rndis_keepalive_response (configNr,
1090 (rndis_keepalive_msg_type *) 1104 (rndis_keepalive_msg_type *)
1091 buf); 1105 buf);
@@ -1152,7 +1166,8 @@ void rndis_deregister (int configNr)
1152} 1166}
1153 1167
1154int rndis_set_param_dev (u8 configNr, struct net_device *dev, 1168int rndis_set_param_dev (u8 configNr, struct net_device *dev,
1155 struct net_device_stats *stats) 1169 struct net_device_stats *stats,
1170 u16 *cdc_filter)
1156{ 1171{
1157 DEBUG("%s:\n", __FUNCTION__ ); 1172 DEBUG("%s:\n", __FUNCTION__ );
1158 if (!dev || !stats) return -1; 1173 if (!dev || !stats) return -1;
@@ -1160,6 +1175,7 @@ int rndis_set_param_dev (u8 configNr, struct net_device *dev,
1160 1175
1161 rndis_per_dev_params [configNr].dev = dev; 1176 rndis_per_dev_params [configNr].dev = dev;
1162 rndis_per_dev_params [configNr].stats = stats; 1177 rndis_per_dev_params [configNr].stats = stats;
1178 rndis_per_dev_params [configNr].filter = cdc_filter;
1163 1179
1164 return 0; 1180 return 0;
1165} 1181}
@@ -1178,7 +1194,7 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
1178 1194
1179int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed) 1195int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
1180{ 1196{
1181 DEBUG("%s:\n", __FUNCTION__ ); 1197 DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed);
1182 if (configNr >= RNDIS_MAX_CONFIGS) return -1; 1198 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1183 1199
1184 rndis_per_dev_params [configNr].medium = medium; 1200 rndis_per_dev_params [configNr].medium = medium;
@@ -1242,6 +1258,7 @@ static rndis_resp_t *rndis_add_response (int configNr, u32 length)
1242{ 1258{
1243 rndis_resp_t *r; 1259 rndis_resp_t *r;
1244 1260
1261 /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */
1245 r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC); 1262 r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);
1246 if (!r) return NULL; 1263 if (!r) return NULL;
1247 1264