Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : /*
3 : : * Simple "CDC Subset" USB Networking Links
4 : : * Copyright (C) 2000-2005 by David Brownell
5 : : */
6 : :
7 : : #include <linux/module.h>
8 : : #include <linux/kmod.h>
9 : : #include <linux/netdevice.h>
10 : : #include <linux/etherdevice.h>
11 : : #include <linux/ethtool.h>
12 : : #include <linux/workqueue.h>
13 : : #include <linux/mii.h>
14 : : #include <linux/usb.h>
15 : : #include <linux/usb/usbnet.h>
16 : :
17 : :
18 : : /*
19 : : * This supports simple USB network links that don't require any special
20 : : * framing or hardware control operations. The protocol used here is a
21 : : * strict subset of CDC Ethernet, with three basic differences reflecting
22 : : * the goal that almost any hardware should run it:
23 : : *
24 : : * - Minimal runtime control: one interface, no altsettings, and
25 : : * no vendor or class specific control requests. If a device is
26 : : * configured, it is allowed to exchange packets with the host.
27 : : * Fancier models would mean not working on some hardware.
28 : : *
29 : : * - Minimal manufacturing control: no IEEE "Organizationally
30 : : * Unique ID" required, or an EEPROMs to store one. Each host uses
31 : : * one random "locally assigned" Ethernet address instead, which can
32 : : * of course be overridden using standard tools like "ifconfig".
33 : : * (With 2^46 such addresses, same-net collisions are quite rare.)
34 : : *
35 : : * - There is no additional framing data for USB. Packets are written
36 : : * exactly as in CDC Ethernet, starting with an Ethernet header and
37 : : * terminated by a short packet. However, the host will never send a
38 : : * zero length packet; some systems can't handle those robustly.
39 : : *
40 : : * Anything that can transmit and receive USB bulk packets can implement
41 : : * this protocol. That includes both smart peripherals and quite a lot
42 : : * of "host-to-host" USB cables (which embed two devices back-to-back).
43 : : *
44 : : * Note that although Linux may use many of those host-to-host links
45 : : * with this "cdc_subset" framing, that doesn't mean there may not be a
46 : : * better approach. Handling the "other end unplugs/replugs" scenario
47 : : * well tends to require chip-specific vendor requests. Also, Windows
48 : : * peers at the other end of host-to-host cables may expect their own
49 : : * framing to be used rather than this "cdc_subset" model.
50 : : */
51 : :
52 : : #if defined(CONFIG_USB_EPSON2888) || defined(CONFIG_USB_ARMLINUX)
53 : : /* PDA style devices are always connected if present */
54 : 248 : static int always_connected (struct usbnet *dev)
55 : : {
56 : 248 : return 0;
57 : : }
58 : : #endif
59 : :
60 : : #ifdef CONFIG_USB_ALI_M5632
61 : : #define HAVE_HARDWARE
62 : :
63 : : /*-------------------------------------------------------------------------
64 : : *
65 : : * ALi M5632 driver ... does high speed
66 : : *
67 : : * NOTE that the MS-Windows drivers for this chip use some funky and
68 : : * (naturally) undocumented 7-byte prefix to each packet, so this is a
69 : : * case where we don't currently interoperate. Also, once you unplug
70 : : * one end of the cable, you need to replug the other end too ... since
71 : : * chip docs are unavailable, there's no way to reset the relevant state
72 : : * short of a power cycle.
73 : : *
74 : : *-------------------------------------------------------------------------*/
75 : :
76 : 0 : static void m5632_recover(struct usbnet *dev)
77 : : {
78 : 0 : struct usb_device *udev = dev->udev;
79 : 0 : struct usb_interface *intf = dev->intf;
80 : : int r;
81 : :
82 : 0 : r = usb_lock_device_for_reset(udev, intf);
83 [ # # ]: 0 : if (r < 0)
84 : 0 : return;
85 : :
86 : 0 : usb_reset_device(udev);
87 : : usb_unlock_device(udev);
88 : : }
89 : :
90 : : static const struct driver_info ali_m5632_info = {
91 : : .description = "ALi M5632",
92 : : .flags = FLAG_POINTTOPOINT,
93 : : .recover = m5632_recover,
94 : : };
95 : :
96 : : #endif
97 : :
98 : : #ifdef CONFIG_USB_AN2720
99 : : #define HAVE_HARDWARE
100 : :
101 : : /*-------------------------------------------------------------------------
102 : : *
103 : : * AnchorChips 2720 driver ... http://www.cypress.com
104 : : *
105 : : * This doesn't seem to have a way to detect whether the peer is
106 : : * connected, or need any reset handshaking. It's got pretty big
107 : : * internal buffers (handles most of a frame's worth of data).
108 : : * Chip data sheets don't describe any vendor control messages.
109 : : *
110 : : *-------------------------------------------------------------------------*/
111 : :
112 : : static const struct driver_info an2720_info = {
113 : : .description = "AnchorChips/Cypress 2720",
114 : : .flags = FLAG_POINTTOPOINT,
115 : : // no reset available!
116 : : // no check_connect available!
117 : :
118 : : .in = 2, .out = 2, // direction distinguishes these
119 : : };
120 : :
121 : : #endif /* CONFIG_USB_AN2720 */
122 : :
123 : :
124 : : #ifdef CONFIG_USB_BELKIN
125 : : #define HAVE_HARDWARE
126 : :
127 : : /*-------------------------------------------------------------------------
128 : : *
129 : : * Belkin F5U104 ... two NetChip 2280 devices + Atmel AVR microcontroller
130 : : *
131 : : * ... also two eTEK designs, including one sold as "Advance USBNET"
132 : : *
133 : : *-------------------------------------------------------------------------*/
134 : :
135 : : static const struct driver_info belkin_info = {
136 : : .description = "Belkin, eTEK, or compatible",
137 : : .flags = FLAG_POINTTOPOINT,
138 : : };
139 : :
140 : : #endif /* CONFIG_USB_BELKIN */
141 : :
142 : :
143 : :
144 : : #ifdef CONFIG_USB_EPSON2888
145 : : #define HAVE_HARDWARE
146 : :
147 : : /*-------------------------------------------------------------------------
148 : : *
149 : : * EPSON USB clients
150 : : *
151 : : * This is the same idea as Linux PDAs (below) except the firmware in the
152 : : * device might not be Tux-powered. Epson provides reference firmware that
153 : : * implements this interface. Product developers can reuse or modify that
154 : : * code, such as by using their own product and vendor codes.
155 : : *
156 : : * Support was from Juro Bystricky <bystricky.juro@erd.epson.com>
157 : : *
158 : : *-------------------------------------------------------------------------*/
159 : :
160 : : static const struct driver_info epson2888_info = {
161 : : .description = "Epson USB Device",
162 : : .check_connect = always_connected,
163 : : .flags = FLAG_POINTTOPOINT,
164 : :
165 : : .in = 4, .out = 3,
166 : : };
167 : :
168 : : #endif /* CONFIG_USB_EPSON2888 */
169 : :
170 : :
171 : : /*-------------------------------------------------------------------------
172 : : *
173 : : * info from Jonathan McDowell <noodles@earth.li>
174 : : *
175 : : *-------------------------------------------------------------------------*/
176 : : #ifdef CONFIG_USB_KC2190
177 : : #define HAVE_HARDWARE
178 : : static const struct driver_info kc2190_info = {
179 : : .description = "KC Technology KC-190",
180 : : .flags = FLAG_POINTTOPOINT,
181 : : };
182 : : #endif /* CONFIG_USB_KC2190 */
183 : :
184 : :
185 : : #ifdef CONFIG_USB_ARMLINUX
186 : : #define HAVE_HARDWARE
187 : :
188 : : /*-------------------------------------------------------------------------
189 : : *
190 : : * Intel's SA-1100 chip integrates basic USB support, and is used
191 : : * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more.
192 : : * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to
193 : : * network using minimal USB framing data.
194 : : *
195 : : * This describes the driver currently in standard ARM Linux kernels.
196 : : * The Zaurus uses a different driver (see later).
197 : : *
198 : : * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support
199 : : * and different USB endpoint numbering than the SA1100 devices. The
200 : : * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100
201 : : * so we rely on the endpoint descriptors.
202 : : *
203 : : *-------------------------------------------------------------------------*/
204 : :
205 : : static const struct driver_info linuxdev_info = {
206 : : .description = "Linux Device",
207 : : .check_connect = always_connected,
208 : : .flags = FLAG_POINTTOPOINT,
209 : : };
210 : :
211 : : static const struct driver_info yopy_info = {
212 : : .description = "Yopy",
213 : : .check_connect = always_connected,
214 : : .flags = FLAG_POINTTOPOINT,
215 : : };
216 : :
217 : : static const struct driver_info blob_info = {
218 : : .description = "Boot Loader OBject",
219 : : .check_connect = always_connected,
220 : : .flags = FLAG_POINTTOPOINT,
221 : : };
222 : :
223 : : #endif /* CONFIG_USB_ARMLINUX */
224 : :
225 : :
226 : : /*-------------------------------------------------------------------------*/
227 : :
228 : : #ifndef HAVE_HARDWARE
229 : : #warning You need to configure some hardware for this driver
230 : : #endif
231 : :
232 : : /*
233 : : * chip vendor names won't normally be on the cables, and
234 : : * may not be on the device.
235 : : */
236 : :
237 : : static const struct usb_device_id products [] = {
238 : :
239 : : #ifdef CONFIG_USB_ALI_M5632
240 : : {
241 : : USB_DEVICE (0x0402, 0x5632), // ALi defaults
242 : : .driver_info = (unsigned long) &ali_m5632_info,
243 : : },
244 : : {
245 : : USB_DEVICE (0x182d,0x207c), // SiteCom CN-124
246 : : .driver_info = (unsigned long) &ali_m5632_info,
247 : : },
248 : : #endif
249 : :
250 : : #ifdef CONFIG_USB_AN2720
251 : : {
252 : : USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults
253 : : .driver_info = (unsigned long) &an2720_info,
254 : : }, {
255 : : USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET
256 : : .driver_info = (unsigned long) &an2720_info,
257 : : },
258 : : #endif
259 : :
260 : : #ifdef CONFIG_USB_BELKIN
261 : : {
262 : : USB_DEVICE (0x050d, 0x0004), // Belkin
263 : : .driver_info = (unsigned long) &belkin_info,
264 : : }, {
265 : : USB_DEVICE (0x056c, 0x8100), // eTEK
266 : : .driver_info = (unsigned long) &belkin_info,
267 : : }, {
268 : : USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK)
269 : : .driver_info = (unsigned long) &belkin_info,
270 : : },
271 : : #endif
272 : :
273 : : #ifdef CONFIG_USB_EPSON2888
274 : : {
275 : : USB_DEVICE (0x0525, 0x2888), // EPSON USB client
276 : : .driver_info = (unsigned long) &epson2888_info,
277 : : },
278 : : #endif
279 : :
280 : : #ifdef CONFIG_USB_KC2190
281 : : {
282 : : USB_DEVICE (0x050f, 0x0190), // KC-190
283 : : .driver_info = (unsigned long) &kc2190_info,
284 : : },
285 : : #endif
286 : :
287 : : #ifdef CONFIG_USB_ARMLINUX
288 : : /*
289 : : * SA-1100 using standard ARM Linux kernels, or compatible.
290 : : * Often used when talking to Linux PDAs (iPaq, Yopy, etc).
291 : : * The sa-1100 "usb-eth" driver handles the basic framing.
292 : : *
293 : : * PXA25x or PXA210 ... these use a "usb-eth" driver much like
294 : : * the sa1100 one, but hardware uses different endpoint numbers.
295 : : *
296 : : * Or the Linux "Ethernet" gadget on hardware that can't talk
297 : : * CDC Ethernet (e.g., no altsettings), in either of two modes:
298 : : * - acting just like the old "usb-eth" firmware, though
299 : : * the implementation is different
300 : : * - supporting RNDIS as the first/default configuration for
301 : : * MS-Windows interop; Linux needs to use the other config
302 : : */
303 : : {
304 : : // 1183 = 0x049F, both used as hex values?
305 : : // Compaq "Itsy" vendor/product id
306 : : USB_DEVICE (0x049F, 0x505A), // usb-eth, or compatible
307 : : .driver_info = (unsigned long) &linuxdev_info,
308 : : }, {
309 : : USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy"
310 : : .driver_info = (unsigned long) &yopy_info,
311 : : }, {
312 : : USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader
313 : : .driver_info = (unsigned long) &blob_info,
314 : : }, {
315 : : USB_DEVICE (0x1286, 0x8001), // "blob" bootloader
316 : : .driver_info = (unsigned long) &blob_info,
317 : : }, {
318 : : // Linux Ethernet/RNDIS gadget, mostly on PXA, second config
319 : : // e.g. Gumstix, current OpenZaurus, ... or anything else
320 : : // that just enables this gadget option.
321 : : USB_DEVICE (0x0525, 0xa4a2),
322 : : .driver_info = (unsigned long) &linuxdev_info,
323 : : },
324 : : #endif
325 : :
326 : : { }, // END
327 : : };
328 : : MODULE_DEVICE_TABLE(usb, products);
329 : :
330 : : /*-------------------------------------------------------------------------*/
331 : 0 : static int dummy_prereset(struct usb_interface *intf)
332 : : {
333 : 0 : return 0;
334 : : }
335 : :
336 : 0 : static int dummy_postreset(struct usb_interface *intf)
337 : : {
338 : 0 : return 0;
339 : : }
340 : :
341 : : static struct usb_driver cdc_subset_driver = {
342 : : .name = "cdc_subset",
343 : : .probe = usbnet_probe,
344 : : .suspend = usbnet_suspend,
345 : : .resume = usbnet_resume,
346 : : .pre_reset = dummy_prereset,
347 : : .post_reset = dummy_postreset,
348 : : .disconnect = usbnet_disconnect,
349 : : .id_table = products,
350 : : .disable_hub_initiated_lpm = 1,
351 : : };
352 : :
353 : 404 : module_usb_driver(cdc_subset_driver);
354 : :
355 : : MODULE_AUTHOR("David Brownell");
356 : : MODULE_DESCRIPTION("Simple 'CDC Subset' USB networking links");
357 : : MODULE_LICENSE("GPL");
|