Commit 7e99eeddb35cdaafb820676a57517b5e58685e4c

Authored by Thomas Backlund
Committed by Jeff Garzik
1 parent 7a2f53ee0b

rndis_host: support WM6 devices as modems

This patch allows Windows Mobile 6 devices to be used for
tethering -- that is, used as modems.  It was requested by
AdamW in kernel bugzilla:

  http://bugzilla.kernel.org/show_bug.cgi?id=11119

and Mandriva kernel-discuss list.  It is tested and confirmed
to work by Peterl:

  http://forum.eeeuser.com/viewtopic.php?pid=323543#p323543

This patch is based on the patch in the above kernel bugzilla,
which is from the usb-rndis-lite tree.

[ dbrownell@users.sourceforge.net: misc fixes ]
Signed-off-by: Thomas Backlund <tmb@mandriva.org>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

Showing 2 changed files with 14 additions and 1 deletions Inline Diff

drivers/net/usb/cdc_ether.c
1 /* 1 /*
2 * CDC Ethernet based networking peripherals 2 * CDC Ethernet based networking peripherals
3 * Copyright (C) 2003-2005 by David Brownell 3 * Copyright (C) 2003-2005 by David Brownell
4 * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync) 4 * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync)
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21 // #define DEBUG // error path messages, extra info 21 // #define DEBUG // error path messages, extra info
22 // #define VERBOSE // more; success messages 22 // #define VERBOSE // more; success messages
23 23
24 #include <linux/module.h> 24 #include <linux/module.h>
25 #include <linux/init.h> 25 #include <linux/init.h>
26 #include <linux/netdevice.h> 26 #include <linux/netdevice.h>
27 #include <linux/etherdevice.h> 27 #include <linux/etherdevice.h>
28 #include <linux/ctype.h> 28 #include <linux/ctype.h>
29 #include <linux/ethtool.h> 29 #include <linux/ethtool.h>
30 #include <linux/workqueue.h> 30 #include <linux/workqueue.h>
31 #include <linux/mii.h> 31 #include <linux/mii.h>
32 #include <linux/usb.h> 32 #include <linux/usb.h>
33 #include <linux/usb/cdc.h> 33 #include <linux/usb/cdc.h>
34 #include <linux/usb/usbnet.h> 34 #include <linux/usb/usbnet.h>
35 35
36 36
37 #if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) 37 #if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE)
38 38
39 static int is_rndis(struct usb_interface_descriptor *desc) 39 static int is_rndis(struct usb_interface_descriptor *desc)
40 { 40 {
41 return desc->bInterfaceClass == USB_CLASS_COMM 41 return desc->bInterfaceClass == USB_CLASS_COMM
42 && desc->bInterfaceSubClass == 2 42 && desc->bInterfaceSubClass == 2
43 && desc->bInterfaceProtocol == 0xff; 43 && desc->bInterfaceProtocol == 0xff;
44 } 44 }
45 45
46 static int is_activesync(struct usb_interface_descriptor *desc) 46 static int is_activesync(struct usb_interface_descriptor *desc)
47 { 47 {
48 return desc->bInterfaceClass == USB_CLASS_MISC 48 return desc->bInterfaceClass == USB_CLASS_MISC
49 && desc->bInterfaceSubClass == 1 49 && desc->bInterfaceSubClass == 1
50 && desc->bInterfaceProtocol == 1; 50 && desc->bInterfaceProtocol == 1;
51 } 51 }
52 52
53 static int is_wireless_rndis(struct usb_interface_descriptor *desc)
54 {
55 return desc->bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER
56 && desc->bInterfaceSubClass == 1
57 && desc->bInterfaceProtocol == 3;
58 }
59
53 #else 60 #else
54 61
55 #define is_rndis(desc) 0 62 #define is_rndis(desc) 0
56 #define is_activesync(desc) 0 63 #define is_activesync(desc) 0
64 #define is_wireless_rndis(desc) 0
57 65
58 #endif 66 #endif
59 67
60 /* 68 /*
61 * probes control interface, claims data interface, collects the bulk 69 * probes control interface, claims data interface, collects the bulk
62 * endpoints, activates data interface (if needed), maybe sets MTU. 70 * endpoints, activates data interface (if needed), maybe sets MTU.
63 * all pure cdc, except for certain firmware workarounds, and knowing 71 * all pure cdc, except for certain firmware workarounds, and knowing
64 * that rndis uses one different rule. 72 * that rndis uses one different rule.
65 */ 73 */
66 int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) 74 int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
67 { 75 {
68 u8 *buf = intf->cur_altsetting->extra; 76 u8 *buf = intf->cur_altsetting->extra;
69 int len = intf->cur_altsetting->extralen; 77 int len = intf->cur_altsetting->extralen;
70 struct usb_interface_descriptor *d; 78 struct usb_interface_descriptor *d;
71 struct cdc_state *info = (void *) &dev->data; 79 struct cdc_state *info = (void *) &dev->data;
72 int status; 80 int status;
73 int rndis; 81 int rndis;
74 struct usb_driver *driver = driver_of(intf); 82 struct usb_driver *driver = driver_of(intf);
75 83
76 if (sizeof dev->data < sizeof *info) 84 if (sizeof dev->data < sizeof *info)
77 return -EDOM; 85 return -EDOM;
78 86
79 /* expect strict spec conformance for the descriptors, but 87 /* expect strict spec conformance for the descriptors, but
80 * cope with firmware which stores them in the wrong place 88 * cope with firmware which stores them in the wrong place
81 */ 89 */
82 if (len == 0 && dev->udev->actconfig->extralen) { 90 if (len == 0 && dev->udev->actconfig->extralen) {
83 /* Motorola SB4100 (and others: Brad Hards says it's 91 /* Motorola SB4100 (and others: Brad Hards says it's
84 * from a Broadcom design) put CDC descriptors here 92 * from a Broadcom design) put CDC descriptors here
85 */ 93 */
86 buf = dev->udev->actconfig->extra; 94 buf = dev->udev->actconfig->extra;
87 len = dev->udev->actconfig->extralen; 95 len = dev->udev->actconfig->extralen;
88 if (len) 96 if (len)
89 dev_dbg(&intf->dev, 97 dev_dbg(&intf->dev,
90 "CDC descriptors on config\n"); 98 "CDC descriptors on config\n");
91 } 99 }
92 100
93 /* Maybe CDC descriptors are after the endpoint? This bug has 101 /* Maybe CDC descriptors are after the endpoint? This bug has
94 * been seen on some 2Wire Inc RNDIS-ish products. 102 * been seen on some 2Wire Inc RNDIS-ish products.
95 */ 103 */
96 if (len == 0) { 104 if (len == 0) {
97 struct usb_host_endpoint *hep; 105 struct usb_host_endpoint *hep;
98 106
99 hep = intf->cur_altsetting->endpoint; 107 hep = intf->cur_altsetting->endpoint;
100 if (hep) { 108 if (hep) {
101 buf = hep->extra; 109 buf = hep->extra;
102 len = hep->extralen; 110 len = hep->extralen;
103 } 111 }
104 if (len) 112 if (len)
105 dev_dbg(&intf->dev, 113 dev_dbg(&intf->dev,
106 "CDC descriptors on endpoint\n"); 114 "CDC descriptors on endpoint\n");
107 } 115 }
108 116
109 /* this assumes that if there's a non-RNDIS vendor variant 117 /* this assumes that if there's a non-RNDIS vendor variant
110 * of cdc-acm, it'll fail RNDIS requests cleanly. 118 * of cdc-acm, it'll fail RNDIS requests cleanly.
111 */ 119 */
112 rndis = is_rndis(&intf->cur_altsetting->desc) 120 rndis = is_rndis(&intf->cur_altsetting->desc)
113 || is_activesync(&intf->cur_altsetting->desc); 121 || is_activesync(&intf->cur_altsetting->desc)
122 || is_wireless_rndis(&intf->cur_altsetting->desc);
114 123
115 memset(info, 0, sizeof *info); 124 memset(info, 0, sizeof *info);
116 info->control = intf; 125 info->control = intf;
117 while (len > 3) { 126 while (len > 3) {
118 if (buf [1] != USB_DT_CS_INTERFACE) 127 if (buf [1] != USB_DT_CS_INTERFACE)
119 goto next_desc; 128 goto next_desc;
120 129
121 /* use bDescriptorSubType to identify the CDC descriptors. 130 /* use bDescriptorSubType to identify the CDC descriptors.
122 * We expect devices with CDC header and union descriptors. 131 * We expect devices with CDC header and union descriptors.
123 * For CDC Ethernet we need the ethernet descriptor. 132 * For CDC Ethernet we need the ethernet descriptor.
124 * For RNDIS, ignore two (pointless) CDC modem descriptors 133 * For RNDIS, ignore two (pointless) CDC modem descriptors
125 * in favor of a complicated OID-based RPC scheme doing what 134 * in favor of a complicated OID-based RPC scheme doing what
126 * CDC Ethernet achieves with a simple descriptor. 135 * CDC Ethernet achieves with a simple descriptor.
127 */ 136 */
128 switch (buf [2]) { 137 switch (buf [2]) {
129 case USB_CDC_HEADER_TYPE: 138 case USB_CDC_HEADER_TYPE:
130 if (info->header) { 139 if (info->header) {
131 dev_dbg(&intf->dev, "extra CDC header\n"); 140 dev_dbg(&intf->dev, "extra CDC header\n");
132 goto bad_desc; 141 goto bad_desc;
133 } 142 }
134 info->header = (void *) buf; 143 info->header = (void *) buf;
135 if (info->header->bLength != sizeof *info->header) { 144 if (info->header->bLength != sizeof *info->header) {
136 dev_dbg(&intf->dev, "CDC header len %u\n", 145 dev_dbg(&intf->dev, "CDC header len %u\n",
137 info->header->bLength); 146 info->header->bLength);
138 goto bad_desc; 147 goto bad_desc;
139 } 148 }
140 break; 149 break;
141 case USB_CDC_ACM_TYPE: 150 case USB_CDC_ACM_TYPE:
142 /* paranoia: disambiguate a "real" vendor-specific 151 /* paranoia: disambiguate a "real" vendor-specific
143 * modem interface from an RNDIS non-modem. 152 * modem interface from an RNDIS non-modem.
144 */ 153 */
145 if (rndis) { 154 if (rndis) {
146 struct usb_cdc_acm_descriptor *acm; 155 struct usb_cdc_acm_descriptor *acm;
147 156
148 acm = (void *) buf; 157 acm = (void *) buf;
149 if (acm->bmCapabilities) { 158 if (acm->bmCapabilities) {
150 dev_dbg(&intf->dev, 159 dev_dbg(&intf->dev,
151 "ACM capabilities %02x, " 160 "ACM capabilities %02x, "
152 "not really RNDIS?\n", 161 "not really RNDIS?\n",
153 acm->bmCapabilities); 162 acm->bmCapabilities);
154 goto bad_desc; 163 goto bad_desc;
155 } 164 }
156 } 165 }
157 break; 166 break;
158 case USB_CDC_UNION_TYPE: 167 case USB_CDC_UNION_TYPE:
159 if (info->u) { 168 if (info->u) {
160 dev_dbg(&intf->dev, "extra CDC union\n"); 169 dev_dbg(&intf->dev, "extra CDC union\n");
161 goto bad_desc; 170 goto bad_desc;
162 } 171 }
163 info->u = (void *) buf; 172 info->u = (void *) buf;
164 if (info->u->bLength != sizeof *info->u) { 173 if (info->u->bLength != sizeof *info->u) {
165 dev_dbg(&intf->dev, "CDC union len %u\n", 174 dev_dbg(&intf->dev, "CDC union len %u\n",
166 info->u->bLength); 175 info->u->bLength);
167 goto bad_desc; 176 goto bad_desc;
168 } 177 }
169 178
170 /* we need a master/control interface (what we're 179 /* we need a master/control interface (what we're
171 * probed with) and a slave/data interface; union 180 * probed with) and a slave/data interface; union
172 * descriptors sort this all out. 181 * descriptors sort this all out.
173 */ 182 */
174 info->control = usb_ifnum_to_if(dev->udev, 183 info->control = usb_ifnum_to_if(dev->udev,
175 info->u->bMasterInterface0); 184 info->u->bMasterInterface0);
176 info->data = usb_ifnum_to_if(dev->udev, 185 info->data = usb_ifnum_to_if(dev->udev,
177 info->u->bSlaveInterface0); 186 info->u->bSlaveInterface0);
178 if (!info->control || !info->data) { 187 if (!info->control || !info->data) {
179 dev_dbg(&intf->dev, 188 dev_dbg(&intf->dev,
180 "master #%u/%p slave #%u/%p\n", 189 "master #%u/%p slave #%u/%p\n",
181 info->u->bMasterInterface0, 190 info->u->bMasterInterface0,
182 info->control, 191 info->control,
183 info->u->bSlaveInterface0, 192 info->u->bSlaveInterface0,
184 info->data); 193 info->data);
185 goto bad_desc; 194 goto bad_desc;
186 } 195 }
187 if (info->control != intf) { 196 if (info->control != intf) {
188 dev_dbg(&intf->dev, "bogus CDC Union\n"); 197 dev_dbg(&intf->dev, "bogus CDC Union\n");
189 /* Ambit USB Cable Modem (and maybe others) 198 /* Ambit USB Cable Modem (and maybe others)
190 * interchanges master and slave interface. 199 * interchanges master and slave interface.
191 */ 200 */
192 if (info->data == intf) { 201 if (info->data == intf) {
193 info->data = info->control; 202 info->data = info->control;
194 info->control = intf; 203 info->control = intf;
195 } else 204 } else
196 goto bad_desc; 205 goto bad_desc;
197 } 206 }
198 207
199 /* a data interface altsetting does the real i/o */ 208 /* a data interface altsetting does the real i/o */
200 d = &info->data->cur_altsetting->desc; 209 d = &info->data->cur_altsetting->desc;
201 if (d->bInterfaceClass != USB_CLASS_CDC_DATA) { 210 if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
202 dev_dbg(&intf->dev, "slave class %u\n", 211 dev_dbg(&intf->dev, "slave class %u\n",
203 d->bInterfaceClass); 212 d->bInterfaceClass);
204 goto bad_desc; 213 goto bad_desc;
205 } 214 }
206 break; 215 break;
207 case USB_CDC_ETHERNET_TYPE: 216 case USB_CDC_ETHERNET_TYPE:
208 if (info->ether) { 217 if (info->ether) {
209 dev_dbg(&intf->dev, "extra CDC ether\n"); 218 dev_dbg(&intf->dev, "extra CDC ether\n");
210 goto bad_desc; 219 goto bad_desc;
211 } 220 }
212 info->ether = (void *) buf; 221 info->ether = (void *) buf;
213 if (info->ether->bLength != sizeof *info->ether) { 222 if (info->ether->bLength != sizeof *info->ether) {
214 dev_dbg(&intf->dev, "CDC ether len %u\n", 223 dev_dbg(&intf->dev, "CDC ether len %u\n",
215 info->ether->bLength); 224 info->ether->bLength);
216 goto bad_desc; 225 goto bad_desc;
217 } 226 }
218 dev->hard_mtu = le16_to_cpu( 227 dev->hard_mtu = le16_to_cpu(
219 info->ether->wMaxSegmentSize); 228 info->ether->wMaxSegmentSize);
220 /* because of Zaurus, we may be ignoring the host 229 /* because of Zaurus, we may be ignoring the host
221 * side link address we were given. 230 * side link address we were given.
222 */ 231 */
223 break; 232 break;
224 } 233 }
225 next_desc: 234 next_desc:
226 len -= buf [0]; /* bLength */ 235 len -= buf [0]; /* bLength */
227 buf += buf [0]; 236 buf += buf [0];
228 } 237 }
229 238
230 /* Microsoft ActiveSync based and some regular RNDIS devices lack the 239 /* Microsoft ActiveSync based and some regular RNDIS devices lack the
231 * CDC descriptors, so we'll hard-wire the interfaces and not check 240 * CDC descriptors, so we'll hard-wire the interfaces and not check
232 * for descriptors. 241 * for descriptors.
233 */ 242 */
234 if (rndis && !info->u) { 243 if (rndis && !info->u) {
235 info->control = usb_ifnum_to_if(dev->udev, 0); 244 info->control = usb_ifnum_to_if(dev->udev, 0);
236 info->data = usb_ifnum_to_if(dev->udev, 1); 245 info->data = usb_ifnum_to_if(dev->udev, 1);
237 if (!info->control || !info->data) { 246 if (!info->control || !info->data) {
238 dev_dbg(&intf->dev, 247 dev_dbg(&intf->dev,
239 "rndis: master #0/%p slave #1/%p\n", 248 "rndis: master #0/%p slave #1/%p\n",
240 info->control, 249 info->control,
241 info->data); 250 info->data);
242 goto bad_desc; 251 goto bad_desc;
243 } 252 }
244 253
245 } else if (!info->header || !info->u || (!rndis && !info->ether)) { 254 } else if (!info->header || !info->u || (!rndis && !info->ether)) {
246 dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n", 255 dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n",
247 info->header ? "" : "header ", 256 info->header ? "" : "header ",
248 info->u ? "" : "union ", 257 info->u ? "" : "union ",
249 info->ether ? "" : "ether "); 258 info->ether ? "" : "ether ");
250 goto bad_desc; 259 goto bad_desc;
251 } 260 }
252 261
253 /* claim data interface and set it up ... with side effects. 262 /* claim data interface and set it up ... with side effects.
254 * network traffic can't flow until an altsetting is enabled. 263 * network traffic can't flow until an altsetting is enabled.
255 */ 264 */
256 status = usb_driver_claim_interface(driver, info->data, dev); 265 status = usb_driver_claim_interface(driver, info->data, dev);
257 if (status < 0) 266 if (status < 0)
258 return status; 267 return status;
259 status = usbnet_get_endpoints(dev, info->data); 268 status = usbnet_get_endpoints(dev, info->data);
260 if (status < 0) { 269 if (status < 0) {
261 /* ensure immediate exit from usbnet_disconnect */ 270 /* ensure immediate exit from usbnet_disconnect */
262 usb_set_intfdata(info->data, NULL); 271 usb_set_intfdata(info->data, NULL);
263 usb_driver_release_interface(driver, info->data); 272 usb_driver_release_interface(driver, info->data);
264 return status; 273 return status;
265 } 274 }
266 275
267 /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */ 276 /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
268 dev->status = NULL; 277 dev->status = NULL;
269 if (info->control->cur_altsetting->desc.bNumEndpoints == 1) { 278 if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
270 struct usb_endpoint_descriptor *desc; 279 struct usb_endpoint_descriptor *desc;
271 280
272 dev->status = &info->control->cur_altsetting->endpoint [0]; 281 dev->status = &info->control->cur_altsetting->endpoint [0];
273 desc = &dev->status->desc; 282 desc = &dev->status->desc;
274 if (!usb_endpoint_is_int_in(desc) 283 if (!usb_endpoint_is_int_in(desc)
275 || (le16_to_cpu(desc->wMaxPacketSize) 284 || (le16_to_cpu(desc->wMaxPacketSize)
276 < sizeof(struct usb_cdc_notification)) 285 < sizeof(struct usb_cdc_notification))
277 || !desc->bInterval) { 286 || !desc->bInterval) {
278 dev_dbg(&intf->dev, "bad notification endpoint\n"); 287 dev_dbg(&intf->dev, "bad notification endpoint\n");
279 dev->status = NULL; 288 dev->status = NULL;
280 } 289 }
281 } 290 }
282 if (rndis && !dev->status) { 291 if (rndis && !dev->status) {
283 dev_dbg(&intf->dev, "missing RNDIS status endpoint\n"); 292 dev_dbg(&intf->dev, "missing RNDIS status endpoint\n");
284 usb_set_intfdata(info->data, NULL); 293 usb_set_intfdata(info->data, NULL);
285 usb_driver_release_interface(driver, info->data); 294 usb_driver_release_interface(driver, info->data);
286 return -ENODEV; 295 return -ENODEV;
287 } 296 }
288 return 0; 297 return 0;
289 298
290 bad_desc: 299 bad_desc:
291 dev_info(&dev->udev->dev, "bad CDC descriptors\n"); 300 dev_info(&dev->udev->dev, "bad CDC descriptors\n");
292 return -ENODEV; 301 return -ENODEV;
293 } 302 }
294 EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind); 303 EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind);
295 304
296 void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf) 305 void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
297 { 306 {
298 struct cdc_state *info = (void *) &dev->data; 307 struct cdc_state *info = (void *) &dev->data;
299 struct usb_driver *driver = driver_of(intf); 308 struct usb_driver *driver = driver_of(intf);
300 309
301 /* disconnect master --> disconnect slave */ 310 /* disconnect master --> disconnect slave */
302 if (intf == info->control && info->data) { 311 if (intf == info->control && info->data) {
303 /* ensure immediate exit from usbnet_disconnect */ 312 /* ensure immediate exit from usbnet_disconnect */
304 usb_set_intfdata(info->data, NULL); 313 usb_set_intfdata(info->data, NULL);
305 usb_driver_release_interface(driver, info->data); 314 usb_driver_release_interface(driver, info->data);
306 info->data = NULL; 315 info->data = NULL;
307 } 316 }
308 317
309 /* and vice versa (just in case) */ 318 /* and vice versa (just in case) */
310 else if (intf == info->data && info->control) { 319 else if (intf == info->data && info->control) {
311 /* ensure immediate exit from usbnet_disconnect */ 320 /* ensure immediate exit from usbnet_disconnect */
312 usb_set_intfdata(info->control, NULL); 321 usb_set_intfdata(info->control, NULL);
313 usb_driver_release_interface(driver, info->control); 322 usb_driver_release_interface(driver, info->control);
314 info->control = NULL; 323 info->control = NULL;
315 } 324 }
316 } 325 }
317 EXPORT_SYMBOL_GPL(usbnet_cdc_unbind); 326 EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
318 327
319 /*------------------------------------------------------------------------- 328 /*-------------------------------------------------------------------------
320 * 329 *
321 * Communications Device Class, Ethernet Control model 330 * Communications Device Class, Ethernet Control model
322 * 331 *
323 * Takes two interfaces. The DATA interface is inactive till an altsetting 332 * Takes two interfaces. The DATA interface is inactive till an altsetting
324 * is selected. Configuration data includes class descriptors. There's 333 * is selected. Configuration data includes class descriptors. There's
325 * an optional status endpoint on the control interface. 334 * an optional status endpoint on the control interface.
326 * 335 *
327 * This should interop with whatever the 2.4 "CDCEther.c" driver 336 * This should interop with whatever the 2.4 "CDCEther.c" driver
328 * (by Brad Hards) talked with, with more functionality. 337 * (by Brad Hards) talked with, with more functionality.
329 * 338 *
330 *-------------------------------------------------------------------------*/ 339 *-------------------------------------------------------------------------*/
331 340
332 static void dumpspeed(struct usbnet *dev, __le32 *speeds) 341 static void dumpspeed(struct usbnet *dev, __le32 *speeds)
333 { 342 {
334 if (netif_msg_timer(dev)) 343 if (netif_msg_timer(dev))
335 devinfo(dev, "link speeds: %u kbps up, %u kbps down", 344 devinfo(dev, "link speeds: %u kbps up, %u kbps down",
336 __le32_to_cpu(speeds[0]) / 1000, 345 __le32_to_cpu(speeds[0]) / 1000,
337 __le32_to_cpu(speeds[1]) / 1000); 346 __le32_to_cpu(speeds[1]) / 1000);
338 } 347 }
339 348
340 static void cdc_status(struct usbnet *dev, struct urb *urb) 349 static void cdc_status(struct usbnet *dev, struct urb *urb)
341 { 350 {
342 struct usb_cdc_notification *event; 351 struct usb_cdc_notification *event;
343 352
344 if (urb->actual_length < sizeof *event) 353 if (urb->actual_length < sizeof *event)
345 return; 354 return;
346 355
347 /* SPEED_CHANGE can get split into two 8-byte packets */ 356 /* SPEED_CHANGE can get split into two 8-byte packets */
348 if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) { 357 if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
349 dumpspeed(dev, (__le32 *) urb->transfer_buffer); 358 dumpspeed(dev, (__le32 *) urb->transfer_buffer);
350 return; 359 return;
351 } 360 }
352 361
353 event = urb->transfer_buffer; 362 event = urb->transfer_buffer;
354 switch (event->bNotificationType) { 363 switch (event->bNotificationType) {
355 case USB_CDC_NOTIFY_NETWORK_CONNECTION: 364 case USB_CDC_NOTIFY_NETWORK_CONNECTION:
356 if (netif_msg_timer(dev)) 365 if (netif_msg_timer(dev))
357 devdbg(dev, "CDC: carrier %s", 366 devdbg(dev, "CDC: carrier %s",
358 event->wValue ? "on" : "off"); 367 event->wValue ? "on" : "off");
359 if (event->wValue) 368 if (event->wValue)
360 netif_carrier_on(dev->net); 369 netif_carrier_on(dev->net);
361 else 370 else
362 netif_carrier_off(dev->net); 371 netif_carrier_off(dev->net);
363 break; 372 break;
364 case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */ 373 case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
365 if (netif_msg_timer(dev)) 374 if (netif_msg_timer(dev))
366 devdbg(dev, "CDC: speed change (len %d)", 375 devdbg(dev, "CDC: speed change (len %d)",
367 urb->actual_length); 376 urb->actual_length);
368 if (urb->actual_length != (sizeof *event + 8)) 377 if (urb->actual_length != (sizeof *event + 8))
369 set_bit(EVENT_STS_SPLIT, &dev->flags); 378 set_bit(EVENT_STS_SPLIT, &dev->flags);
370 else 379 else
371 dumpspeed(dev, (__le32 *) &event[1]); 380 dumpspeed(dev, (__le32 *) &event[1]);
372 break; 381 break;
373 /* USB_CDC_NOTIFY_RESPONSE_AVAILABLE can happen too (e.g. RNDIS), 382 /* USB_CDC_NOTIFY_RESPONSE_AVAILABLE can happen too (e.g. RNDIS),
374 * but there are no standard formats for the response data. 383 * but there are no standard formats for the response data.
375 */ 384 */
376 default: 385 default:
377 deverr(dev, "CDC: unexpected notification %02x!", 386 deverr(dev, "CDC: unexpected notification %02x!",
378 event->bNotificationType); 387 event->bNotificationType);
379 break; 388 break;
380 } 389 }
381 } 390 }
382 391
383 static u8 nibble(unsigned char c) 392 static u8 nibble(unsigned char c)
384 { 393 {
385 if (likely(isdigit(c))) 394 if (likely(isdigit(c)))
386 return c - '0'; 395 return c - '0';
387 c = toupper(c); 396 c = toupper(c);
388 if (likely(isxdigit(c))) 397 if (likely(isxdigit(c)))
389 return 10 + c - 'A'; 398 return 10 + c - 'A';
390 return 0; 399 return 0;
391 } 400 }
392 401
393 static inline int 402 static inline int
394 get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e) 403 get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e)
395 { 404 {
396 int tmp, i; 405 int tmp, i;
397 unsigned char buf [13]; 406 unsigned char buf [13];
398 407
399 tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf); 408 tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf);
400 if (tmp != 12) { 409 if (tmp != 12) {
401 dev_dbg(&dev->udev->dev, 410 dev_dbg(&dev->udev->dev,
402 "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp); 411 "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
403 if (tmp >= 0) 412 if (tmp >= 0)
404 tmp = -EINVAL; 413 tmp = -EINVAL;
405 return tmp; 414 return tmp;
406 } 415 }
407 for (i = tmp = 0; i < 6; i++, tmp += 2) 416 for (i = tmp = 0; i < 6; i++, tmp += 2)
408 dev->net->dev_addr [i] = 417 dev->net->dev_addr [i] =
409 (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]); 418 (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
410 return 0; 419 return 0;
411 } 420 }
412 421
413 static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) 422 static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
414 { 423 {
415 int status; 424 int status;
416 struct cdc_state *info = (void *) &dev->data; 425 struct cdc_state *info = (void *) &dev->data;
417 426
418 status = usbnet_generic_cdc_bind(dev, intf); 427 status = usbnet_generic_cdc_bind(dev, intf);
419 if (status < 0) 428 if (status < 0)
420 return status; 429 return status;
421 430
422 status = get_ethernet_addr(dev, info->ether); 431 status = get_ethernet_addr(dev, info->ether);
423 if (status < 0) { 432 if (status < 0) {
424 usb_set_intfdata(info->data, NULL); 433 usb_set_intfdata(info->data, NULL);
425 usb_driver_release_interface(driver_of(intf), info->data); 434 usb_driver_release_interface(driver_of(intf), info->data);
426 return status; 435 return status;
427 } 436 }
428 437
429 /* FIXME cdc-ether has some multicast code too, though it complains 438 /* FIXME cdc-ether has some multicast code too, though it complains
430 * in routine cases. info->ether describes the multicast support. 439 * in routine cases. info->ether describes the multicast support.
431 * Implement that here, manipulating the cdc filter as needed. 440 * Implement that here, manipulating the cdc filter as needed.
432 */ 441 */
433 return 0; 442 return 0;
434 } 443 }
435 444
436 static const struct driver_info cdc_info = { 445 static const struct driver_info cdc_info = {
437 .description = "CDC Ethernet Device", 446 .description = "CDC Ethernet Device",
438 .flags = FLAG_ETHER, 447 .flags = FLAG_ETHER,
439 // .check_connect = cdc_check_connect, 448 // .check_connect = cdc_check_connect,
440 .bind = cdc_bind, 449 .bind = cdc_bind,
441 .unbind = usbnet_cdc_unbind, 450 .unbind = usbnet_cdc_unbind,
442 .status = cdc_status, 451 .status = cdc_status,
443 }; 452 };
444 453
445 /*-------------------------------------------------------------------------*/ 454 /*-------------------------------------------------------------------------*/
446 455
447 456
448 static const struct usb_device_id products [] = { 457 static const struct usb_device_id products [] = {
449 /* 458 /*
450 * BLACKLIST !! 459 * BLACKLIST !!
451 * 460 *
452 * First blacklist any products that are egregiously nonconformant 461 * First blacklist any products that are egregiously nonconformant
453 * with the CDC Ethernet specs. Minor braindamage we cope with; when 462 * with the CDC Ethernet specs. Minor braindamage we cope with; when
454 * they're not even trying, needing a separate driver is only the first 463 * they're not even trying, needing a separate driver is only the first
455 * of the differences to show up. 464 * of the differences to show up.
456 */ 465 */
457 466
458 #define ZAURUS_MASTER_INTERFACE \ 467 #define ZAURUS_MASTER_INTERFACE \
459 .bInterfaceClass = USB_CLASS_COMM, \ 468 .bInterfaceClass = USB_CLASS_COMM, \
460 .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ 469 .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
461 .bInterfaceProtocol = USB_CDC_PROTO_NONE 470 .bInterfaceProtocol = USB_CDC_PROTO_NONE
462 471
463 /* SA-1100 based Sharp Zaurus ("collie"), or compatible; 472 /* SA-1100 based Sharp Zaurus ("collie"), or compatible;
464 * wire-incompatible with true CDC Ethernet implementations. 473 * wire-incompatible with true CDC Ethernet implementations.
465 * (And, it seems, needlessly so...) 474 * (And, it seems, needlessly so...)
466 */ 475 */
467 { 476 {
468 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 477 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
469 | USB_DEVICE_ID_MATCH_DEVICE, 478 | USB_DEVICE_ID_MATCH_DEVICE,
470 .idVendor = 0x04DD, 479 .idVendor = 0x04DD,
471 .idProduct = 0x8004, 480 .idProduct = 0x8004,
472 ZAURUS_MASTER_INTERFACE, 481 ZAURUS_MASTER_INTERFACE,
473 .driver_info = 0, 482 .driver_info = 0,
474 }, 483 },
475 484
476 /* PXA-25x based Sharp Zaurii. Note that it seems some of these 485 /* PXA-25x based Sharp Zaurii. Note that it seems some of these
477 * (later models especially) may have shipped only with firmware 486 * (later models especially) may have shipped only with firmware
478 * advertising false "CDC MDLM" compatibility ... but we're not 487 * advertising false "CDC MDLM" compatibility ... but we're not
479 * clear which models did that, so for now let's assume the worst. 488 * clear which models did that, so for now let's assume the worst.
480 */ 489 */
481 { 490 {
482 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 491 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
483 | USB_DEVICE_ID_MATCH_DEVICE, 492 | USB_DEVICE_ID_MATCH_DEVICE,
484 .idVendor = 0x04DD, 493 .idVendor = 0x04DD,
485 .idProduct = 0x8005, /* A-300 */ 494 .idProduct = 0x8005, /* A-300 */
486 ZAURUS_MASTER_INTERFACE, 495 ZAURUS_MASTER_INTERFACE,
487 .driver_info = 0, 496 .driver_info = 0,
488 }, { 497 }, {
489 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 498 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
490 | USB_DEVICE_ID_MATCH_DEVICE, 499 | USB_DEVICE_ID_MATCH_DEVICE,
491 .idVendor = 0x04DD, 500 .idVendor = 0x04DD,
492 .idProduct = 0x8006, /* B-500/SL-5600 */ 501 .idProduct = 0x8006, /* B-500/SL-5600 */
493 ZAURUS_MASTER_INTERFACE, 502 ZAURUS_MASTER_INTERFACE,
494 .driver_info = 0, 503 .driver_info = 0,
495 }, { 504 }, {
496 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 505 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
497 | USB_DEVICE_ID_MATCH_DEVICE, 506 | USB_DEVICE_ID_MATCH_DEVICE,
498 .idVendor = 0x04DD, 507 .idVendor = 0x04DD,
499 .idProduct = 0x8007, /* C-700 */ 508 .idProduct = 0x8007, /* C-700 */
500 ZAURUS_MASTER_INTERFACE, 509 ZAURUS_MASTER_INTERFACE,
501 .driver_info = 0, 510 .driver_info = 0,
502 }, { 511 }, {
503 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 512 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
504 | USB_DEVICE_ID_MATCH_DEVICE, 513 | USB_DEVICE_ID_MATCH_DEVICE,
505 .idVendor = 0x04DD, 514 .idVendor = 0x04DD,
506 .idProduct = 0x9031, /* C-750 C-760 */ 515 .idProduct = 0x9031, /* C-750 C-760 */
507 ZAURUS_MASTER_INTERFACE, 516 ZAURUS_MASTER_INTERFACE,
508 .driver_info = 0, 517 .driver_info = 0,
509 }, { 518 }, {
510 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 519 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
511 | USB_DEVICE_ID_MATCH_DEVICE, 520 | USB_DEVICE_ID_MATCH_DEVICE,
512 .idVendor = 0x04DD, 521 .idVendor = 0x04DD,
513 .idProduct = 0x9032, /* SL-6000 */ 522 .idProduct = 0x9032, /* SL-6000 */
514 ZAURUS_MASTER_INTERFACE, 523 ZAURUS_MASTER_INTERFACE,
515 .driver_info = 0, 524 .driver_info = 0,
516 }, { 525 }, {
517 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 526 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
518 | USB_DEVICE_ID_MATCH_DEVICE, 527 | USB_DEVICE_ID_MATCH_DEVICE,
519 .idVendor = 0x04DD, 528 .idVendor = 0x04DD,
520 /* reported with some C860 units */ 529 /* reported with some C860 units */
521 .idProduct = 0x9050, /* C-860 */ 530 .idProduct = 0x9050, /* C-860 */
522 ZAURUS_MASTER_INTERFACE, 531 ZAURUS_MASTER_INTERFACE,
523 .driver_info = 0, 532 .driver_info = 0,
524 }, 533 },
525 534
526 /* Olympus has some models with a Zaurus-compatible option. 535 /* Olympus has some models with a Zaurus-compatible option.
527 * R-1000 uses a FreeScale i.MXL cpu (ARMv4T) 536 * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
528 */ 537 */
529 { 538 {
530 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 539 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
531 | USB_DEVICE_ID_MATCH_DEVICE, 540 | USB_DEVICE_ID_MATCH_DEVICE,
532 .idVendor = 0x07B4, 541 .idVendor = 0x07B4,
533 .idProduct = 0x0F02, /* R-1000 */ 542 .idProduct = 0x0F02, /* R-1000 */
534 ZAURUS_MASTER_INTERFACE, 543 ZAURUS_MASTER_INTERFACE,
535 .driver_info = 0, 544 .driver_info = 0,
536 }, 545 },
537 546
538 /* 547 /*
539 * WHITELIST!!! 548 * WHITELIST!!!
540 * 549 *
541 * CDC Ether uses two interfaces, not necessarily consecutive. 550 * CDC Ether uses two interfaces, not necessarily consecutive.
542 * We match the main interface, ignoring the optional device 551 * We match the main interface, ignoring the optional device
543 * class so we could handle devices that aren't exclusively 552 * class so we could handle devices that aren't exclusively
544 * CDC ether. 553 * CDC ether.
545 * 554 *
546 * NOTE: this match must come AFTER entries blacklisting devices 555 * NOTE: this match must come AFTER entries blacklisting devices
547 * because of bugs/quirks in a given product (like Zaurus, above). 556 * because of bugs/quirks in a given product (like Zaurus, above).
548 */ 557 */
549 { 558 {
550 USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, 559 USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
551 USB_CDC_PROTO_NONE), 560 USB_CDC_PROTO_NONE),
552 .driver_info = (unsigned long) &cdc_info, 561 .driver_info = (unsigned long) &cdc_info,
553 }, 562 },
554 { }, // END 563 { }, // END
555 }; 564 };
556 MODULE_DEVICE_TABLE(usb, products); 565 MODULE_DEVICE_TABLE(usb, products);
557 566
558 static struct usb_driver cdc_driver = { 567 static struct usb_driver cdc_driver = {
559 .name = "cdc_ether", 568 .name = "cdc_ether",
560 .id_table = products, 569 .id_table = products,
561 .probe = usbnet_probe, 570 .probe = usbnet_probe,
562 .disconnect = usbnet_disconnect, 571 .disconnect = usbnet_disconnect,
563 .suspend = usbnet_suspend, 572 .suspend = usbnet_suspend,
564 .resume = usbnet_resume, 573 .resume = usbnet_resume,
565 }; 574 };
566 575
567 576
568 static int __init cdc_init(void) 577 static int __init cdc_init(void)
569 { 578 {
570 BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) 579 BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data)
571 < sizeof(struct cdc_state))); 580 < sizeof(struct cdc_state)));
572 581
573 return usb_register(&cdc_driver); 582 return usb_register(&cdc_driver);
574 } 583 }
575 module_init(cdc_init); 584 module_init(cdc_init);
576 585
577 static void __exit cdc_exit(void) 586 static void __exit cdc_exit(void)
578 { 587 {
579 usb_deregister(&cdc_driver); 588 usb_deregister(&cdc_driver);
580 } 589 }
581 module_exit(cdc_exit); 590 module_exit(cdc_exit);
582 591
583 MODULE_AUTHOR("David Brownell"); 592 MODULE_AUTHOR("David Brownell");
584 MODULE_DESCRIPTION("USB CDC Ethernet devices"); 593 MODULE_DESCRIPTION("USB CDC Ethernet devices");
585 MODULE_LICENSE("GPL"); 594 MODULE_LICENSE("GPL");
586 595
drivers/net/usb/rndis_host.c
1 /* 1 /*
2 * Host Side support for RNDIS Networking Links 2 * Host Side support for RNDIS Networking Links
3 * Copyright (C) 2005 by David Brownell 3 * Copyright (C) 2005 by David Brownell
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 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 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 7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version. 8 * (at your option) any later version.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 #include <linux/module.h> 19 #include <linux/module.h>
20 #include <linux/init.h> 20 #include <linux/init.h>
21 #include <linux/netdevice.h> 21 #include <linux/netdevice.h>
22 #include <linux/etherdevice.h> 22 #include <linux/etherdevice.h>
23 #include <linux/ethtool.h> 23 #include <linux/ethtool.h>
24 #include <linux/workqueue.h> 24 #include <linux/workqueue.h>
25 #include <linux/mii.h> 25 #include <linux/mii.h>
26 #include <linux/usb.h> 26 #include <linux/usb.h>
27 #include <linux/usb/cdc.h> 27 #include <linux/usb/cdc.h>
28 #include <linux/usb/usbnet.h> 28 #include <linux/usb/usbnet.h>
29 #include <linux/usb/rndis_host.h> 29 #include <linux/usb/rndis_host.h>
30 30
31 31
32 /* 32 /*
33 * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of 33 * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of
34 * course ACM was intended for modems, not Ethernet links! USB's standard 34 * course ACM was intended for modems, not Ethernet links! USB's standard
35 * for Ethernet links is "CDC Ethernet", which is significantly simpler. 35 * for Ethernet links is "CDC Ethernet", which is significantly simpler.
36 * 36 *
37 * NOTE that Microsoft's "RNDIS 1.0" specification is incomplete. Issues 37 * NOTE that Microsoft's "RNDIS 1.0" specification is incomplete. Issues
38 * include: 38 * include:
39 * - Power management in particular relies on information that's scattered 39 * - Power management in particular relies on information that's scattered
40 * through other documentation, and which is incomplete or incorrect even 40 * through other documentation, and which is incomplete or incorrect even
41 * there. 41 * there.
42 * - There are various undocumented protocol requirements, such as the 42 * - There are various undocumented protocol requirements, such as the
43 * need to send unused garbage in control-OUT messages. 43 * need to send unused garbage in control-OUT messages.
44 * - In some cases, MS-Windows will emit undocumented requests; this 44 * - In some cases, MS-Windows will emit undocumented requests; this
45 * matters more to peripheral implementations than host ones. 45 * matters more to peripheral implementations than host ones.
46 * 46 *
47 * Moreover there's a no-open-specs variant of RNDIS called "ActiveSync". 47 * Moreover there's a no-open-specs variant of RNDIS called "ActiveSync".
48 * 48 *
49 * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in 49 * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in
50 * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and 50 * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and
51 * currently rare) "Ethernet Emulation Model" (EEM). 51 * currently rare) "Ethernet Emulation Model" (EEM).
52 */ 52 */
53 53
54 /* 54 /*
55 * RNDIS notifications from device: command completion; "reverse" 55 * RNDIS notifications from device: command completion; "reverse"
56 * keepalives; etc 56 * keepalives; etc
57 */ 57 */
58 void rndis_status(struct usbnet *dev, struct urb *urb) 58 void rndis_status(struct usbnet *dev, struct urb *urb)
59 { 59 {
60 devdbg(dev, "rndis status urb, len %d stat %d", 60 devdbg(dev, "rndis status urb, len %d stat %d",
61 urb->actual_length, urb->status); 61 urb->actual_length, urb->status);
62 // FIXME for keepalives, respond immediately (asynchronously) 62 // FIXME for keepalives, respond immediately (asynchronously)
63 // if not an RNDIS status, do like cdc_status(dev,urb) does 63 // if not an RNDIS status, do like cdc_status(dev,urb) does
64 } 64 }
65 EXPORT_SYMBOL_GPL(rndis_status); 65 EXPORT_SYMBOL_GPL(rndis_status);
66 66
67 /* 67 /*
68 * RPC done RNDIS-style. Caller guarantees: 68 * RPC done RNDIS-style. Caller guarantees:
69 * - message is properly byteswapped 69 * - message is properly byteswapped
70 * - there's no other request pending 70 * - there's no other request pending
71 * - buf can hold up to 1KB response (required by RNDIS spec) 71 * - buf can hold up to 1KB response (required by RNDIS spec)
72 * On return, the first few entries are already byteswapped. 72 * On return, the first few entries are already byteswapped.
73 * 73 *
74 * Call context is likely probe(), before interface name is known, 74 * Call context is likely probe(), before interface name is known,
75 * which is why we won't try to use it in the diagnostics. 75 * which is why we won't try to use it in the diagnostics.
76 */ 76 */
77 int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) 77 int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
78 { 78 {
79 struct cdc_state *info = (void *) &dev->data; 79 struct cdc_state *info = (void *) &dev->data;
80 int master_ifnum; 80 int master_ifnum;
81 int retval; 81 int retval;
82 unsigned count; 82 unsigned count;
83 __le32 rsp; 83 __le32 rsp;
84 u32 xid = 0, msg_len, request_id; 84 u32 xid = 0, msg_len, request_id;
85 85
86 /* REVISIT when this gets called from contexts other than probe() or 86 /* REVISIT when this gets called from contexts other than probe() or
87 * disconnect(): either serialize, or dispatch responses on xid 87 * disconnect(): either serialize, or dispatch responses on xid
88 */ 88 */
89 89
90 /* Issue the request; xid is unique, don't bother byteswapping it */ 90 /* Issue the request; xid is unique, don't bother byteswapping it */
91 if (likely(buf->msg_type != RNDIS_MSG_HALT 91 if (likely(buf->msg_type != RNDIS_MSG_HALT
92 && buf->msg_type != RNDIS_MSG_RESET)) { 92 && buf->msg_type != RNDIS_MSG_RESET)) {
93 xid = dev->xid++; 93 xid = dev->xid++;
94 if (!xid) 94 if (!xid)
95 xid = dev->xid++; 95 xid = dev->xid++;
96 buf->request_id = (__force __le32) xid; 96 buf->request_id = (__force __le32) xid;
97 } 97 }
98 master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber; 98 master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber;
99 retval = usb_control_msg(dev->udev, 99 retval = usb_control_msg(dev->udev,
100 usb_sndctrlpipe(dev->udev, 0), 100 usb_sndctrlpipe(dev->udev, 0),
101 USB_CDC_SEND_ENCAPSULATED_COMMAND, 101 USB_CDC_SEND_ENCAPSULATED_COMMAND,
102 USB_TYPE_CLASS | USB_RECIP_INTERFACE, 102 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
103 0, master_ifnum, 103 0, master_ifnum,
104 buf, le32_to_cpu(buf->msg_len), 104 buf, le32_to_cpu(buf->msg_len),
105 RNDIS_CONTROL_TIMEOUT_MS); 105 RNDIS_CONTROL_TIMEOUT_MS);
106 if (unlikely(retval < 0 || xid == 0)) 106 if (unlikely(retval < 0 || xid == 0))
107 return retval; 107 return retval;
108 108
109 // FIXME Seems like some devices discard responses when 109 // FIXME Seems like some devices discard responses when
110 // we time out and cancel our "get response" requests... 110 // we time out and cancel our "get response" requests...
111 // so, this is fragile. Probably need to poll for status. 111 // so, this is fragile. Probably need to poll for status.
112 112
113 /* ignore status endpoint, just poll the control channel; 113 /* ignore status endpoint, just poll the control channel;
114 * the request probably completed immediately 114 * the request probably completed immediately
115 */ 115 */
116 rsp = buf->msg_type | RNDIS_MSG_COMPLETION; 116 rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
117 for (count = 0; count < 10; count++) { 117 for (count = 0; count < 10; count++) {
118 memset(buf, 0, CONTROL_BUFFER_SIZE); 118 memset(buf, 0, CONTROL_BUFFER_SIZE);
119 retval = usb_control_msg(dev->udev, 119 retval = usb_control_msg(dev->udev,
120 usb_rcvctrlpipe(dev->udev, 0), 120 usb_rcvctrlpipe(dev->udev, 0),
121 USB_CDC_GET_ENCAPSULATED_RESPONSE, 121 USB_CDC_GET_ENCAPSULATED_RESPONSE,
122 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 122 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
123 0, master_ifnum, 123 0, master_ifnum,
124 buf, buflen, 124 buf, buflen,
125 RNDIS_CONTROL_TIMEOUT_MS); 125 RNDIS_CONTROL_TIMEOUT_MS);
126 if (likely(retval >= 8)) { 126 if (likely(retval >= 8)) {
127 msg_len = le32_to_cpu(buf->msg_len); 127 msg_len = le32_to_cpu(buf->msg_len);
128 request_id = (__force u32) buf->request_id; 128 request_id = (__force u32) buf->request_id;
129 if (likely(buf->msg_type == rsp)) { 129 if (likely(buf->msg_type == rsp)) {
130 if (likely(request_id == xid)) { 130 if (likely(request_id == xid)) {
131 if (unlikely(rsp == RNDIS_MSG_RESET_C)) 131 if (unlikely(rsp == RNDIS_MSG_RESET_C))
132 return 0; 132 return 0;
133 if (likely(RNDIS_STATUS_SUCCESS 133 if (likely(RNDIS_STATUS_SUCCESS
134 == buf->status)) 134 == buf->status))
135 return 0; 135 return 0;
136 dev_dbg(&info->control->dev, 136 dev_dbg(&info->control->dev,
137 "rndis reply status %08x\n", 137 "rndis reply status %08x\n",
138 le32_to_cpu(buf->status)); 138 le32_to_cpu(buf->status));
139 return -EL3RST; 139 return -EL3RST;
140 } 140 }
141 dev_dbg(&info->control->dev, 141 dev_dbg(&info->control->dev,
142 "rndis reply id %d expected %d\n", 142 "rndis reply id %d expected %d\n",
143 request_id, xid); 143 request_id, xid);
144 /* then likely retry */ 144 /* then likely retry */
145 } else switch (buf->msg_type) { 145 } else switch (buf->msg_type) {
146 case RNDIS_MSG_INDICATE: { /* fault/event */ 146 case RNDIS_MSG_INDICATE: { /* fault/event */
147 struct rndis_indicate *msg = (void *)buf; 147 struct rndis_indicate *msg = (void *)buf;
148 int state = 0; 148 int state = 0;
149 149
150 switch (msg->status) { 150 switch (msg->status) {
151 case RNDIS_STATUS_MEDIA_CONNECT: 151 case RNDIS_STATUS_MEDIA_CONNECT:
152 state = 1; 152 state = 1;
153 case RNDIS_STATUS_MEDIA_DISCONNECT: 153 case RNDIS_STATUS_MEDIA_DISCONNECT:
154 dev_info(&info->control->dev, 154 dev_info(&info->control->dev,
155 "rndis media %sconnect\n", 155 "rndis media %sconnect\n",
156 !state?"dis":""); 156 !state?"dis":"");
157 if (dev->driver_info->link_change) 157 if (dev->driver_info->link_change)
158 dev->driver_info->link_change( 158 dev->driver_info->link_change(
159 dev, state); 159 dev, state);
160 break; 160 break;
161 default: 161 default:
162 dev_info(&info->control->dev, 162 dev_info(&info->control->dev,
163 "rndis indication: 0x%08x\n", 163 "rndis indication: 0x%08x\n",
164 le32_to_cpu(msg->status)); 164 le32_to_cpu(msg->status));
165 } 165 }
166 } 166 }
167 break; 167 break;
168 case RNDIS_MSG_KEEPALIVE: { /* ping */ 168 case RNDIS_MSG_KEEPALIVE: { /* ping */
169 struct rndis_keepalive_c *msg = (void *)buf; 169 struct rndis_keepalive_c *msg = (void *)buf;
170 170
171 msg->msg_type = RNDIS_MSG_KEEPALIVE_C; 171 msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
172 msg->msg_len = ccpu2(sizeof *msg); 172 msg->msg_len = ccpu2(sizeof *msg);
173 msg->status = RNDIS_STATUS_SUCCESS; 173 msg->status = RNDIS_STATUS_SUCCESS;
174 retval = usb_control_msg(dev->udev, 174 retval = usb_control_msg(dev->udev,
175 usb_sndctrlpipe(dev->udev, 0), 175 usb_sndctrlpipe(dev->udev, 0),
176 USB_CDC_SEND_ENCAPSULATED_COMMAND, 176 USB_CDC_SEND_ENCAPSULATED_COMMAND,
177 USB_TYPE_CLASS | USB_RECIP_INTERFACE, 177 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
178 0, master_ifnum, 178 0, master_ifnum,
179 msg, sizeof *msg, 179 msg, sizeof *msg,
180 RNDIS_CONTROL_TIMEOUT_MS); 180 RNDIS_CONTROL_TIMEOUT_MS);
181 if (unlikely(retval < 0)) 181 if (unlikely(retval < 0))
182 dev_dbg(&info->control->dev, 182 dev_dbg(&info->control->dev,
183 "rndis keepalive err %d\n", 183 "rndis keepalive err %d\n",
184 retval); 184 retval);
185 } 185 }
186 break; 186 break;
187 default: 187 default:
188 dev_dbg(&info->control->dev, 188 dev_dbg(&info->control->dev,
189 "unexpected rndis msg %08x len %d\n", 189 "unexpected rndis msg %08x len %d\n",
190 le32_to_cpu(buf->msg_type), msg_len); 190 le32_to_cpu(buf->msg_type), msg_len);
191 } 191 }
192 } else { 192 } else {
193 /* device probably issued a protocol stall; ignore */ 193 /* device probably issued a protocol stall; ignore */
194 dev_dbg(&info->control->dev, 194 dev_dbg(&info->control->dev,
195 "rndis response error, code %d\n", retval); 195 "rndis response error, code %d\n", retval);
196 } 196 }
197 msleep(20); 197 msleep(20);
198 } 198 }
199 dev_dbg(&info->control->dev, "rndis response timeout\n"); 199 dev_dbg(&info->control->dev, "rndis response timeout\n");
200 return -ETIMEDOUT; 200 return -ETIMEDOUT;
201 } 201 }
202 EXPORT_SYMBOL_GPL(rndis_command); 202 EXPORT_SYMBOL_GPL(rndis_command);
203 203
204 /* 204 /*
205 * rndis_query: 205 * rndis_query:
206 * 206 *
207 * Performs a query for @oid along with 0 or more bytes of payload as 207 * Performs a query for @oid along with 0 or more bytes of payload as
208 * specified by @in_len. If @reply_len is not set to -1 then the reply 208 * specified by @in_len. If @reply_len is not set to -1 then the reply
209 * length is checked against this value, resulting in an error if it 209 * length is checked against this value, resulting in an error if it
210 * doesn't match. 210 * doesn't match.
211 * 211 *
212 * NOTE: Adding a payload exactly or greater than the size of the expected 212 * NOTE: Adding a payload exactly or greater than the size of the expected
213 * response payload is an evident requirement MSFT added for ActiveSync. 213 * response payload is an evident requirement MSFT added for ActiveSync.
214 * 214 *
215 * The only exception is for OIDs that return a variably sized response, 215 * The only exception is for OIDs that return a variably sized response,
216 * in which case no payload should be added. This undocumented (and 216 * in which case no payload should be added. This undocumented (and
217 * nonsensical!) issue was found by sniffing protocol requests from the 217 * nonsensical!) issue was found by sniffing protocol requests from the
218 * ActiveSync 4.1 Windows driver. 218 * ActiveSync 4.1 Windows driver.
219 */ 219 */
220 static int rndis_query(struct usbnet *dev, struct usb_interface *intf, 220 static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
221 void *buf, __le32 oid, u32 in_len, 221 void *buf, __le32 oid, u32 in_len,
222 void **reply, int *reply_len) 222 void **reply, int *reply_len)
223 { 223 {
224 int retval; 224 int retval;
225 union { 225 union {
226 void *buf; 226 void *buf;
227 struct rndis_msg_hdr *header; 227 struct rndis_msg_hdr *header;
228 struct rndis_query *get; 228 struct rndis_query *get;
229 struct rndis_query_c *get_c; 229 struct rndis_query_c *get_c;
230 } u; 230 } u;
231 u32 off, len; 231 u32 off, len;
232 232
233 u.buf = buf; 233 u.buf = buf;
234 234
235 memset(u.get, 0, sizeof *u.get + in_len); 235 memset(u.get, 0, sizeof *u.get + in_len);
236 u.get->msg_type = RNDIS_MSG_QUERY; 236 u.get->msg_type = RNDIS_MSG_QUERY;
237 u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len); 237 u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len);
238 u.get->oid = oid; 238 u.get->oid = oid;
239 u.get->len = cpu_to_le32(in_len); 239 u.get->len = cpu_to_le32(in_len);
240 u.get->offset = ccpu2(20); 240 u.get->offset = ccpu2(20);
241 241
242 retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE); 242 retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
243 if (unlikely(retval < 0)) { 243 if (unlikely(retval < 0)) {
244 dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) failed, %d\n", 244 dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) failed, %d\n",
245 oid, retval); 245 oid, retval);
246 return retval; 246 return retval;
247 } 247 }
248 248
249 off = le32_to_cpu(u.get_c->offset); 249 off = le32_to_cpu(u.get_c->offset);
250 len = le32_to_cpu(u.get_c->len); 250 len = le32_to_cpu(u.get_c->len);
251 if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE)) 251 if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
252 goto response_error; 252 goto response_error;
253 253
254 if (*reply_len != -1 && len != *reply_len) 254 if (*reply_len != -1 && len != *reply_len)
255 goto response_error; 255 goto response_error;
256 256
257 *reply = (unsigned char *) &u.get_c->request_id + off; 257 *reply = (unsigned char *) &u.get_c->request_id + off;
258 *reply_len = len; 258 *reply_len = len;
259 259
260 return retval; 260 return retval;
261 261
262 response_error: 262 response_error:
263 dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) " 263 dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) "
264 "invalid response - off %d len %d\n", 264 "invalid response - off %d len %d\n",
265 oid, off, len); 265 oid, off, len);
266 return -EDOM; 266 return -EDOM;
267 } 267 }
268 268
269 int 269 int
270 generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) 270 generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
271 { 271 {
272 int retval; 272 int retval;
273 struct net_device *net = dev->net; 273 struct net_device *net = dev->net;
274 struct cdc_state *info = (void *) &dev->data; 274 struct cdc_state *info = (void *) &dev->data;
275 union { 275 union {
276 void *buf; 276 void *buf;
277 struct rndis_msg_hdr *header; 277 struct rndis_msg_hdr *header;
278 struct rndis_init *init; 278 struct rndis_init *init;
279 struct rndis_init_c *init_c; 279 struct rndis_init_c *init_c;
280 struct rndis_query *get; 280 struct rndis_query *get;
281 struct rndis_query_c *get_c; 281 struct rndis_query_c *get_c;
282 struct rndis_set *set; 282 struct rndis_set *set;
283 struct rndis_set_c *set_c; 283 struct rndis_set_c *set_c;
284 struct rndis_halt *halt; 284 struct rndis_halt *halt;
285 } u; 285 } u;
286 u32 tmp; 286 u32 tmp;
287 __le32 phym_unspec, *phym; 287 __le32 phym_unspec, *phym;
288 int reply_len; 288 int reply_len;
289 unsigned char *bp; 289 unsigned char *bp;
290 290
291 /* we can't rely on i/o from stack working, or stack allocation */ 291 /* we can't rely on i/o from stack working, or stack allocation */
292 u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); 292 u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
293 if (!u.buf) 293 if (!u.buf)
294 return -ENOMEM; 294 return -ENOMEM;
295 retval = usbnet_generic_cdc_bind(dev, intf); 295 retval = usbnet_generic_cdc_bind(dev, intf);
296 if (retval < 0) 296 if (retval < 0)
297 goto fail; 297 goto fail;
298 298
299 u.init->msg_type = RNDIS_MSG_INIT; 299 u.init->msg_type = RNDIS_MSG_INIT;
300 u.init->msg_len = ccpu2(sizeof *u.init); 300 u.init->msg_len = ccpu2(sizeof *u.init);
301 u.init->major_version = ccpu2(1); 301 u.init->major_version = ccpu2(1);
302 u.init->minor_version = ccpu2(0); 302 u.init->minor_version = ccpu2(0);
303 303
304 /* max transfer (in spec) is 0x4000 at full speed, but for 304 /* max transfer (in spec) is 0x4000 at full speed, but for
305 * TX we'll stick to one Ethernet packet plus RNDIS framing. 305 * TX we'll stick to one Ethernet packet plus RNDIS framing.
306 * For RX we handle drivers that zero-pad to end-of-packet. 306 * For RX we handle drivers that zero-pad to end-of-packet.
307 * Don't let userspace change these settings. 307 * Don't let userspace change these settings.
308 * 308 *
309 * NOTE: there still seems to be wierdness here, as if we need 309 * NOTE: there still seems to be wierdness here, as if we need
310 * to do some more things to make sure WinCE targets accept this. 310 * to do some more things to make sure WinCE targets accept this.
311 * They default to jumbograms of 8KB or 16KB, which is absurd 311 * They default to jumbograms of 8KB or 16KB, which is absurd
312 * for such low data rates and which is also more than Linux 312 * for such low data rates and which is also more than Linux
313 * can usually expect to allocate for SKB data... 313 * can usually expect to allocate for SKB data...
314 */ 314 */
315 net->hard_header_len += sizeof (struct rndis_data_hdr); 315 net->hard_header_len += sizeof (struct rndis_data_hdr);
316 dev->hard_mtu = net->mtu + net->hard_header_len; 316 dev->hard_mtu = net->mtu + net->hard_header_len;
317 317
318 dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1); 318 dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1);
319 if (dev->maxpacket == 0) { 319 if (dev->maxpacket == 0) {
320 if (netif_msg_probe(dev)) 320 if (netif_msg_probe(dev))
321 dev_dbg(&intf->dev, "dev->maxpacket can't be 0\n"); 321 dev_dbg(&intf->dev, "dev->maxpacket can't be 0\n");
322 retval = -EINVAL; 322 retval = -EINVAL;
323 goto fail_and_release; 323 goto fail_and_release;
324 } 324 }
325 325
326 dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1); 326 dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1);
327 dev->rx_urb_size &= ~(dev->maxpacket - 1); 327 dev->rx_urb_size &= ~(dev->maxpacket - 1);
328 u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size); 328 u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
329 329
330 net->change_mtu = NULL; 330 net->change_mtu = NULL;
331 retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE); 331 retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
332 if (unlikely(retval < 0)) { 332 if (unlikely(retval < 0)) {
333 /* it might not even be an RNDIS device!! */ 333 /* it might not even be an RNDIS device!! */
334 dev_err(&intf->dev, "RNDIS init failed, %d\n", retval); 334 dev_err(&intf->dev, "RNDIS init failed, %d\n", retval);
335 goto fail_and_release; 335 goto fail_and_release;
336 } 336 }
337 tmp = le32_to_cpu(u.init_c->max_transfer_size); 337 tmp = le32_to_cpu(u.init_c->max_transfer_size);
338 if (tmp < dev->hard_mtu) { 338 if (tmp < dev->hard_mtu) {
339 if (tmp <= net->hard_header_len) { 339 if (tmp <= net->hard_header_len) {
340 dev_err(&intf->dev, 340 dev_err(&intf->dev,
341 "dev can't take %u byte packets (max %u)\n", 341 "dev can't take %u byte packets (max %u)\n",
342 dev->hard_mtu, tmp); 342 dev->hard_mtu, tmp);
343 retval = -EINVAL; 343 retval = -EINVAL;
344 goto halt_fail_and_release; 344 goto halt_fail_and_release;
345 } 345 }
346 dev->hard_mtu = tmp; 346 dev->hard_mtu = tmp;
347 net->mtu = dev->hard_mtu - net->hard_header_len; 347 net->mtu = dev->hard_mtu - net->hard_header_len;
348 dev_warn(&intf->dev, 348 dev_warn(&intf->dev,
349 "dev can't take %u byte packets (max %u), " 349 "dev can't take %u byte packets (max %u), "
350 "adjusting MTU to %u\n", 350 "adjusting MTU to %u\n",
351 dev->hard_mtu, tmp, net->mtu); 351 dev->hard_mtu, tmp, net->mtu);
352 } 352 }
353 353
354 /* REVISIT: peripheral "alignment" request is ignored ... */ 354 /* REVISIT: peripheral "alignment" request is ignored ... */
355 dev_dbg(&intf->dev, 355 dev_dbg(&intf->dev,
356 "hard mtu %u (%u from dev), rx buflen %Zu, align %d\n", 356 "hard mtu %u (%u from dev), rx buflen %Zu, align %d\n",
357 dev->hard_mtu, tmp, dev->rx_urb_size, 357 dev->hard_mtu, tmp, dev->rx_urb_size,
358 1 << le32_to_cpu(u.init_c->packet_alignment)); 358 1 << le32_to_cpu(u.init_c->packet_alignment));
359 359
360 /* module has some device initialization code needs to be done right 360 /* module has some device initialization code needs to be done right
361 * after RNDIS_INIT */ 361 * after RNDIS_INIT */
362 if (dev->driver_info->early_init && 362 if (dev->driver_info->early_init &&
363 dev->driver_info->early_init(dev) != 0) 363 dev->driver_info->early_init(dev) != 0)
364 goto halt_fail_and_release; 364 goto halt_fail_and_release;
365 365
366 /* Check physical medium */ 366 /* Check physical medium */
367 phym = NULL; 367 phym = NULL;
368 reply_len = sizeof *phym; 368 reply_len = sizeof *phym;
369 retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, 369 retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM,
370 0, (void **) &phym, &reply_len); 370 0, (void **) &phym, &reply_len);
371 if (retval != 0 || !phym) { 371 if (retval != 0 || !phym) {
372 /* OID is optional so don't fail here. */ 372 /* OID is optional so don't fail here. */
373 phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; 373 phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED;
374 phym = &phym_unspec; 374 phym = &phym_unspec;
375 } 375 }
376 if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && 376 if ((flags & FLAG_RNDIS_PHYM_WIRELESS) &&
377 *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { 377 *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
378 if (netif_msg_probe(dev)) 378 if (netif_msg_probe(dev))
379 dev_dbg(&intf->dev, "driver requires wireless " 379 dev_dbg(&intf->dev, "driver requires wireless "
380 "physical medium, but device is not.\n"); 380 "physical medium, but device is not.\n");
381 retval = -ENODEV; 381 retval = -ENODEV;
382 goto halt_fail_and_release; 382 goto halt_fail_and_release;
383 } 383 }
384 if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) && 384 if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
385 *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { 385 *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
386 if (netif_msg_probe(dev)) 386 if (netif_msg_probe(dev))
387 dev_dbg(&intf->dev, "driver requires non-wireless " 387 dev_dbg(&intf->dev, "driver requires non-wireless "
388 "physical medium, but device is wireless.\n"); 388 "physical medium, but device is wireless.\n");
389 retval = -ENODEV; 389 retval = -ENODEV;
390 goto halt_fail_and_release; 390 goto halt_fail_and_release;
391 } 391 }
392 392
393 /* Get designated host ethernet address */ 393 /* Get designated host ethernet address */
394 reply_len = ETH_ALEN; 394 reply_len = ETH_ALEN;
395 retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS, 395 retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS,
396 48, (void **) &bp, &reply_len); 396 48, (void **) &bp, &reply_len);
397 if (unlikely(retval< 0)) { 397 if (unlikely(retval< 0)) {
398 dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval); 398 dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
399 goto halt_fail_and_release; 399 goto halt_fail_and_release;
400 } 400 }
401 memcpy(net->dev_addr, bp, ETH_ALEN); 401 memcpy(net->dev_addr, bp, ETH_ALEN);
402 402
403 /* set a nonzero filter to enable data transfers */ 403 /* set a nonzero filter to enable data transfers */
404 memset(u.set, 0, sizeof *u.set); 404 memset(u.set, 0, sizeof *u.set);
405 u.set->msg_type = RNDIS_MSG_SET; 405 u.set->msg_type = RNDIS_MSG_SET;
406 u.set->msg_len = ccpu2(4 + sizeof *u.set); 406 u.set->msg_len = ccpu2(4 + sizeof *u.set);
407 u.set->oid = OID_GEN_CURRENT_PACKET_FILTER; 407 u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
408 u.set->len = ccpu2(4); 408 u.set->len = ccpu2(4);
409 u.set->offset = ccpu2((sizeof *u.set) - 8); 409 u.set->offset = ccpu2((sizeof *u.set) - 8);
410 *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER; 410 *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
411 411
412 retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE); 412 retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
413 if (unlikely(retval < 0)) { 413 if (unlikely(retval < 0)) {
414 dev_err(&intf->dev, "rndis set packet filter, %d\n", retval); 414 dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
415 goto halt_fail_and_release; 415 goto halt_fail_and_release;
416 } 416 }
417 417
418 retval = 0; 418 retval = 0;
419 419
420 kfree(u.buf); 420 kfree(u.buf);
421 return retval; 421 return retval;
422 422
423 halt_fail_and_release: 423 halt_fail_and_release:
424 memset(u.halt, 0, sizeof *u.halt); 424 memset(u.halt, 0, sizeof *u.halt);
425 u.halt->msg_type = RNDIS_MSG_HALT; 425 u.halt->msg_type = RNDIS_MSG_HALT;
426 u.halt->msg_len = ccpu2(sizeof *u.halt); 426 u.halt->msg_len = ccpu2(sizeof *u.halt);
427 (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE); 427 (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE);
428 fail_and_release: 428 fail_and_release:
429 usb_set_intfdata(info->data, NULL); 429 usb_set_intfdata(info->data, NULL);
430 usb_driver_release_interface(driver_of(intf), info->data); 430 usb_driver_release_interface(driver_of(intf), info->data);
431 info->data = NULL; 431 info->data = NULL;
432 fail: 432 fail:
433 kfree(u.buf); 433 kfree(u.buf);
434 return retval; 434 return retval;
435 } 435 }
436 EXPORT_SYMBOL_GPL(generic_rndis_bind); 436 EXPORT_SYMBOL_GPL(generic_rndis_bind);
437 437
438 static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) 438 static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
439 { 439 {
440 return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS); 440 return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS);
441 } 441 }
442 442
443 void rndis_unbind(struct usbnet *dev, struct usb_interface *intf) 443 void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
444 { 444 {
445 struct rndis_halt *halt; 445 struct rndis_halt *halt;
446 446
447 /* try to clear any rndis state/activity (no i/o from stack!) */ 447 /* try to clear any rndis state/activity (no i/o from stack!) */
448 halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); 448 halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
449 if (halt) { 449 if (halt) {
450 halt->msg_type = RNDIS_MSG_HALT; 450 halt->msg_type = RNDIS_MSG_HALT;
451 halt->msg_len = ccpu2(sizeof *halt); 451 halt->msg_len = ccpu2(sizeof *halt);
452 (void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE); 452 (void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE);
453 kfree(halt); 453 kfree(halt);
454 } 454 }
455 455
456 usbnet_cdc_unbind(dev, intf); 456 usbnet_cdc_unbind(dev, intf);
457 } 457 }
458 EXPORT_SYMBOL_GPL(rndis_unbind); 458 EXPORT_SYMBOL_GPL(rndis_unbind);
459 459
460 /* 460 /*
461 * DATA -- host must not write zlps 461 * DATA -- host must not write zlps
462 */ 462 */
463 int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) 463 int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
464 { 464 {
465 /* peripheral may have batched packets to us... */ 465 /* peripheral may have batched packets to us... */
466 while (likely(skb->len)) { 466 while (likely(skb->len)) {
467 struct rndis_data_hdr *hdr = (void *)skb->data; 467 struct rndis_data_hdr *hdr = (void *)skb->data;
468 struct sk_buff *skb2; 468 struct sk_buff *skb2;
469 u32 msg_len, data_offset, data_len; 469 u32 msg_len, data_offset, data_len;
470 470
471 msg_len = le32_to_cpu(hdr->msg_len); 471 msg_len = le32_to_cpu(hdr->msg_len);
472 data_offset = le32_to_cpu(hdr->data_offset); 472 data_offset = le32_to_cpu(hdr->data_offset);
473 data_len = le32_to_cpu(hdr->data_len); 473 data_len = le32_to_cpu(hdr->data_len);
474 474
475 /* don't choke if we see oob, per-packet data, etc */ 475 /* don't choke if we see oob, per-packet data, etc */
476 if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET 476 if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET
477 || skb->len < msg_len 477 || skb->len < msg_len
478 || (data_offset + data_len + 8) > msg_len)) { 478 || (data_offset + data_len + 8) > msg_len)) {
479 dev->stats.rx_frame_errors++; 479 dev->stats.rx_frame_errors++;
480 devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d", 480 devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d",
481 le32_to_cpu(hdr->msg_type), 481 le32_to_cpu(hdr->msg_type),
482 msg_len, data_offset, data_len, skb->len); 482 msg_len, data_offset, data_len, skb->len);
483 return 0; 483 return 0;
484 } 484 }
485 skb_pull(skb, 8 + data_offset); 485 skb_pull(skb, 8 + data_offset);
486 486
487 /* at most one packet left? */ 487 /* at most one packet left? */
488 if (likely((data_len - skb->len) <= sizeof *hdr)) { 488 if (likely((data_len - skb->len) <= sizeof *hdr)) {
489 skb_trim(skb, data_len); 489 skb_trim(skb, data_len);
490 break; 490 break;
491 } 491 }
492 492
493 /* try to return all the packets in the batch */ 493 /* try to return all the packets in the batch */
494 skb2 = skb_clone(skb, GFP_ATOMIC); 494 skb2 = skb_clone(skb, GFP_ATOMIC);
495 if (unlikely(!skb2)) 495 if (unlikely(!skb2))
496 break; 496 break;
497 skb_pull(skb, msg_len - sizeof *hdr); 497 skb_pull(skb, msg_len - sizeof *hdr);
498 skb_trim(skb2, data_len); 498 skb_trim(skb2, data_len);
499 usbnet_skb_return(dev, skb2); 499 usbnet_skb_return(dev, skb2);
500 } 500 }
501 501
502 /* caller will usbnet_skb_return the remaining packet */ 502 /* caller will usbnet_skb_return the remaining packet */
503 return 1; 503 return 1;
504 } 504 }
505 EXPORT_SYMBOL_GPL(rndis_rx_fixup); 505 EXPORT_SYMBOL_GPL(rndis_rx_fixup);
506 506
507 struct sk_buff * 507 struct sk_buff *
508 rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) 508 rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
509 { 509 {
510 struct rndis_data_hdr *hdr; 510 struct rndis_data_hdr *hdr;
511 struct sk_buff *skb2; 511 struct sk_buff *skb2;
512 unsigned len = skb->len; 512 unsigned len = skb->len;
513 513
514 if (likely(!skb_cloned(skb))) { 514 if (likely(!skb_cloned(skb))) {
515 int room = skb_headroom(skb); 515 int room = skb_headroom(skb);
516 516
517 /* enough head room as-is? */ 517 /* enough head room as-is? */
518 if (unlikely((sizeof *hdr) <= room)) 518 if (unlikely((sizeof *hdr) <= room))
519 goto fill; 519 goto fill;
520 520
521 /* enough room, but needs to be readjusted? */ 521 /* enough room, but needs to be readjusted? */
522 room += skb_tailroom(skb); 522 room += skb_tailroom(skb);
523 if (likely((sizeof *hdr) <= room)) { 523 if (likely((sizeof *hdr) <= room)) {
524 skb->data = memmove(skb->head + sizeof *hdr, 524 skb->data = memmove(skb->head + sizeof *hdr,
525 skb->data, len); 525 skb->data, len);
526 skb_set_tail_pointer(skb, len); 526 skb_set_tail_pointer(skb, len);
527 goto fill; 527 goto fill;
528 } 528 }
529 } 529 }
530 530
531 /* create a new skb, with the correct size (and tailpad) */ 531 /* create a new skb, with the correct size (and tailpad) */
532 skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags); 532 skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
533 dev_kfree_skb_any(skb); 533 dev_kfree_skb_any(skb);
534 if (unlikely(!skb2)) 534 if (unlikely(!skb2))
535 return skb2; 535 return skb2;
536 skb = skb2; 536 skb = skb2;
537 537
538 /* fill out the RNDIS header. we won't bother trying to batch 538 /* fill out the RNDIS header. we won't bother trying to batch
539 * packets; Linux minimizes wasted bandwidth through tx queues. 539 * packets; Linux minimizes wasted bandwidth through tx queues.
540 */ 540 */
541 fill: 541 fill:
542 hdr = (void *) __skb_push(skb, sizeof *hdr); 542 hdr = (void *) __skb_push(skb, sizeof *hdr);
543 memset(hdr, 0, sizeof *hdr); 543 memset(hdr, 0, sizeof *hdr);
544 hdr->msg_type = RNDIS_MSG_PACKET; 544 hdr->msg_type = RNDIS_MSG_PACKET;
545 hdr->msg_len = cpu_to_le32(skb->len); 545 hdr->msg_len = cpu_to_le32(skb->len);
546 hdr->data_offset = ccpu2(sizeof(*hdr) - 8); 546 hdr->data_offset = ccpu2(sizeof(*hdr) - 8);
547 hdr->data_len = cpu_to_le32(len); 547 hdr->data_len = cpu_to_le32(len);
548 548
549 /* FIXME make the last packet always be short ... */ 549 /* FIXME make the last packet always be short ... */
550 return skb; 550 return skb;
551 } 551 }
552 EXPORT_SYMBOL_GPL(rndis_tx_fixup); 552 EXPORT_SYMBOL_GPL(rndis_tx_fixup);
553 553
554 554
555 static const struct driver_info rndis_info = { 555 static const struct driver_info rndis_info = {
556 .description = "RNDIS device", 556 .description = "RNDIS device",
557 .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, 557 .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT,
558 .bind = rndis_bind, 558 .bind = rndis_bind,
559 .unbind = rndis_unbind, 559 .unbind = rndis_unbind,
560 .status = rndis_status, 560 .status = rndis_status,
561 .rx_fixup = rndis_rx_fixup, 561 .rx_fixup = rndis_rx_fixup,
562 .tx_fixup = rndis_tx_fixup, 562 .tx_fixup = rndis_tx_fixup,
563 }; 563 };
564 564
565 #undef ccpu2 565 #undef ccpu2
566 566
567 567
568 /*-------------------------------------------------------------------------*/ 568 /*-------------------------------------------------------------------------*/
569 569
570 static const struct usb_device_id products [] = { 570 static const struct usb_device_id products [] = {
571 { 571 {
572 /* RNDIS is MSFT's un-official variant of CDC ACM */ 572 /* RNDIS is MSFT's un-official variant of CDC ACM */
573 USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), 573 USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
574 .driver_info = (unsigned long) &rndis_info, 574 .driver_info = (unsigned long) &rndis_info,
575 }, { 575 }, {
576 /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ 576 /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
577 USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), 577 USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
578 .driver_info = (unsigned long) &rndis_info, 578 .driver_info = (unsigned long) &rndis_info,
579 }, {
580 /* RNDIS for tethering */
581 USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
582 .driver_info = (unsigned long) &rndis_info,
579 }, 583 },
580 { }, // END 584 { }, // END
581 }; 585 };
582 MODULE_DEVICE_TABLE(usb, products); 586 MODULE_DEVICE_TABLE(usb, products);
583 587
584 static struct usb_driver rndis_driver = { 588 static struct usb_driver rndis_driver = {
585 .name = "rndis_host", 589 .name = "rndis_host",
586 .id_table = products, 590 .id_table = products,
587 .probe = usbnet_probe, 591 .probe = usbnet_probe,
588 .disconnect = usbnet_disconnect, 592 .disconnect = usbnet_disconnect,
589 .suspend = usbnet_suspend, 593 .suspend = usbnet_suspend,
590 .resume = usbnet_resume, 594 .resume = usbnet_resume,
591 }; 595 };
592 596
593 static int __init rndis_init(void) 597 static int __init rndis_init(void)
594 { 598 {
595 return usb_register(&rndis_driver); 599 return usb_register(&rndis_driver);
596 } 600 }
597 module_init(rndis_init); 601 module_init(rndis_init);
598 602
599 static void __exit rndis_exit(void) 603 static void __exit rndis_exit(void)
600 { 604 {
601 usb_deregister(&rndis_driver); 605 usb_deregister(&rndis_driver);
602 } 606 }
603 module_exit(rndis_exit); 607 module_exit(rndis_exit);
604 608
605 MODULE_AUTHOR("David Brownell"); 609 MODULE_AUTHOR("David Brownell");
606 MODULE_DESCRIPTION("USB Host side RNDIS driver"); 610 MODULE_DESCRIPTION("USB Host side RNDIS driver");
607 MODULE_LICENSE("GPL"); 611 MODULE_LICENSE("GPL");
608 612