• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision89d48367edbc878f86db3008a4107331ef07f578 (tree)
Time2011-02-20 04:32:36
AuthorSimon Glass <sjg@chro...>
CommiterRemy Bohmer

Log Message

Add USB host ethernet adapter support

This adds support for using USB Ethernet dongles in host mode. This is just
the framework - drivers will come later. A new config option called
CONFIG_USB_HOST_ETHER can be defined in board config files to switch this
on.

The was originally written by NVIDIA and was cleaned up for release by the
Chromium authors.

Signed-off-by: Simon Glass <sjg@chromium.org>

Change Summary

Incremental Difference

--- a/Makefile
+++ b/Makefile
@@ -235,6 +235,7 @@ endif
235235 LIBS += drivers/rtc/librtc.o
236236 LIBS += drivers/serial/libserial.o
237237 LIBS += drivers/twserial/libtws.o
238+LIBS += drivers/usb/eth/libusb_eth.a
238239 LIBS += drivers/usb/gadget/libusb_gadget.o
239240 LIBS += drivers/usb/host/libusb_host.o
240241 LIBS += drivers/usb/musb/libusb_musb.o
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -34,6 +34,9 @@
3434 #ifdef CONFIG_USB_STORAGE
3535 static int usb_stor_curr_dev = -1; /* current device */
3636 #endif
37+#ifdef CONFIG_USB_HOST_ETHER
38+static int usb_ether_curr_dev = -1; /* current ethernet device */
39+#endif
3740
3841 /* some display routines (info command) */
3942 char *usb_get_class_desc(unsigned char dclass)
@@ -522,11 +525,16 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
522525 usb_stop();
523526 printf("(Re)start USB...\n");
524527 i = usb_init();
528+ if (i >= 0) {
525529 #ifdef CONFIG_USB_STORAGE
526- /* try to recognize storage devices immediately */
527- if (i >= 0)
530+ /* try to recognize storage devices immediately */
528531 usb_stor_curr_dev = usb_stor_scan(1);
529532 #endif
533+#ifdef CONFIG_USB_HOST_ETHER
534+ /* try to recognize ethernet devices immediately */
535+ usb_ether_curr_dev = usb_host_eth_scan(1);
536+#endif
537+ }
530538 return 0;
531539 }
532540 if (strncmp(argv[1], "stop", 4) == 0) {
--- a/common/usb.c
+++ b/common/usb.c
@@ -145,10 +145,14 @@ int usb_stop(void)
145145 /*
146146 * disables the asynch behaviour of the control message. This is used for data
147147 * transfers that uses the exclusiv access to the control and bulk messages.
148+ * Returns the old value so it can be restored later.
148149 */
149-void usb_disable_asynch(int disable)
150+int usb_disable_asynch(int disable)
150151 {
152+ int old_value = asynch_allowed;
153+
151154 asynch_allowed = !disable;
155+ return old_value;
152156 }
153157
154158
--- a/doc/README.usb
+++ b/doc/README.usb
@@ -28,7 +28,8 @@ USB Support for PIP405 and MIP405 (UHCI)
2828 The USB support is implemented on the base of the UHCI Host
2929 controller.
3030
31-Currently supported are USB Hubs, USB Keyboards and USB Floppys.
31+Currently supported are USB Hubs, USB Keyboards, USB Floppys, USB
32+flash sticks and USB network adaptors.
3233 Tested with a TEAC Floppy TEAC FD-05PUB and Chicony KU-8933 Keyboard.
3334
3435 How it works:
@@ -78,3 +79,4 @@ CONFIG_USB_UHCI defines the lowlevel part.A lowlevel part must be defined
7879 if using CONFIG_CMD_USB
7980 CONFIG_USB_KEYBOARD enables the USB Keyboard
8081 CONFIG_USB_STORAGE enables the USB storage devices
82+CONFIG_USB_HOST_ETHER enables USB ethernet dongle support
--- /dev/null
+++ b/drivers/usb/eth/Makefile
@@ -0,0 +1,45 @@
1+#
2+# Copyright (c) 2011 The Chromium OS Authors.
3+# See file CREDITS for list of people who contributed to this
4+# project.
5+#
6+# This program is free software; you can redistribute it and/or
7+# modify it under the terms of the GNU General Public License as
8+# published by the Free Software Foundation; either version 2 of
9+# the License, or (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
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
18+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19+# MA 02111-1307 USA
20+#
21+
22+include $(TOPDIR)/config.mk
23+
24+LIB := $(obj)libusb_eth.a
25+
26+# new USB host ethernet layer dependencies
27+COBJS-$(CONFIG_USB_HOST_ETHER) += usb_ether.o
28+
29+COBJS := $(COBJS-y)
30+SRCS := $(COBJS:.o=.c)
31+OBJS := $(addprefix $(obj),$(COBJS))
32+
33+all: $(LIB)
34+
35+$(LIB): $(obj).depend $(OBJS)
36+ $(AR) $(ARFLAGS) $@ $(OBJS)
37+
38+#########################################################################
39+
40+# defines $(obj).depend target
41+include $(SRCTREE)/rules.mk
42+
43+sinclude $(obj).depend
44+
45+#########################################################################
--- /dev/null
+++ b/drivers/usb/eth/usb_ether.c
@@ -0,0 +1,143 @@
1+/*
2+ * Copyright (c) 2011 The Chromium OS Authors.
3+ * See file CREDITS for list of people who contributed to this
4+ * project.
5+ *
6+ * This program is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU General Public License as
8+ * published by the Free Software Foundation; either version 2 of
9+ * the License, or (at your option) any later version.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
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
18+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19+ * MA 02111-1307 USA
20+ */
21+
22+#include <common.h>
23+#include <usb.h>
24+
25+#include "usb_ether.h"
26+
27+typedef void (*usb_eth_before_probe)(void);
28+typedef int (*usb_eth_probe)(struct usb_device *dev, unsigned int ifnum,
29+ struct ueth_data *ss);
30+typedef int (*usb_eth_get_info)(struct usb_device *dev, struct ueth_data *ss,
31+ struct eth_device *dev_desc);
32+
33+struct usb_eth_prob_dev {
34+ usb_eth_before_probe before_probe; /* optional */
35+ usb_eth_probe probe;
36+ usb_eth_get_info get_info;
37+};
38+
39+/* driver functions go here, each bracketed by #ifdef CONFIG_USB_ETHER_xxx */
40+static const struct usb_eth_prob_dev prob_dev[] = {
41+ { }, /* END */
42+};
43+
44+static int usb_max_eth_dev; /* number of highest available usb eth device */
45+static struct ueth_data usb_eth[USB_MAX_ETH_DEV];
46+
47+/*******************************************************************************
48+ * tell if current ethernet device is a usb dongle
49+ */
50+int is_eth_dev_on_usb_host(void)
51+{
52+ int i;
53+ struct eth_device *dev = eth_get_dev();
54+
55+ if (dev) {
56+ for (i = 0; i < usb_max_eth_dev; i++)
57+ if (&usb_eth[i].eth_dev == dev)
58+ return 1;
59+ }
60+ return 0;
61+}
62+
63+/*
64+ * Given a USB device, ask each driver if it can support it, and attach it
65+ * to the first driver that says 'yes'
66+ */
67+static void probe_valid_drivers(struct usb_device *dev)
68+{
69+ int j;
70+
71+ for (j = 0; prob_dev[j].probe && prob_dev[j].get_info; j++) {
72+ if (!prob_dev[j].probe(dev, 0, &usb_eth[usb_max_eth_dev]))
73+ continue;
74+ /*
75+ * ok, it is a supported eth device. Get info and fill it in
76+ */
77+ if (prob_dev[j].get_info(dev,
78+ &usb_eth[usb_max_eth_dev],
79+ &usb_eth[usb_max_eth_dev].eth_dev)) {
80+ /* found proper driver */
81+ /* register with networking stack */
82+ usb_max_eth_dev++;
83+
84+ /*
85+ * usb_max_eth_dev must be incremented prior to this
86+ * call since eth_current_changed (internally called)
87+ * relies on it
88+ */
89+ eth_register(&usb_eth[usb_max_eth_dev - 1].eth_dev);
90+ break;
91+ }
92+ }
93+ }
94+
95+/*******************************************************************************
96+ * scan the usb and reports device info
97+ * to the user if mode = 1
98+ * returns current device or -1 if no
99+ */
100+int usb_host_eth_scan(int mode)
101+{
102+ int i, old_async;
103+ struct usb_device *dev;
104+
105+
106+ if (mode == 1)
107+ printf(" scanning bus for ethernet devices... ");
108+
109+ old_async = usb_disable_asynch(1); /* asynch transfer not allowed */
110+
111+ for (i = 0; i < USB_MAX_ETH_DEV; i++)
112+ memset(&usb_eth[i], 0, sizeof(usb_eth[i]));
113+
114+ for (i = 0; prob_dev[i].probe; i++) {
115+ if (prob_dev[i].before_probe)
116+ prob_dev[i].before_probe();
117+ }
118+
119+ usb_max_eth_dev = 0;
120+ for (i = 0; i < USB_MAX_DEVICE; i++) {
121+ dev = usb_get_dev_index(i); /* get device */
122+ debug("i=%d\n", i);
123+ if (dev == NULL)
124+ break; /* no more devices avaiable */
125+
126+ /* find valid usb_ether driver for this device, if any */
127+ probe_valid_drivers(dev);
128+
129+ /* check limit */
130+ if (usb_max_eth_dev == USB_MAX_ETH_DEV) {
131+ printf("max USB Ethernet Device reached: %d stopping\n",
132+ usb_max_eth_dev);
133+ break;
134+ }
135+ } /* for */
136+
137+ usb_disable_asynch(old_async); /* restore asynch value */
138+ printf("%d Ethernet Device(s) found\n", usb_max_eth_dev);
139+ if (usb_max_eth_dev > 0)
140+ return 0;
141+ return -1;
142+}
143+
--- a/include/usb.h
+++ b/include/usb.h
@@ -168,6 +168,13 @@ int usb_stor_info(void);
168168
169169 #endif
170170
171+#ifdef CONFIG_USB_HOST_ETHER
172+
173+#define USB_MAX_ETH_DEV 5
174+int usb_host_eth_scan(int mode);
175+
176+#endif
177+
171178 #ifdef CONFIG_USB_KEYBOARD
172179
173180 int drv_usb_kbd_init(void);
@@ -191,7 +198,7 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
191198 void *data, int len, int *actual_length, int timeout);
192199 int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,
193200 void *buffer, int transfer_len, int interval);
194-void usb_disable_asynch(int disable);
201+int usb_disable_asynch(int disable);
195202 int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
196203 inline void wait_ms(unsigned long ms);
197204 int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer,
--- /dev/null
+++ b/include/usb_ether.h
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright (c) 2011 The Chromium OS Authors.
3+ * See file CREDITS for list of people who contributed to this
4+ * project.
5+ *
6+ * This program is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU General Public License as
8+ * published by the Free Software Foundation; either version 2 of
9+ * the License, or (at your option) any later version.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
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
18+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19+ * MA 02111-1307 USA
20+ */
21+
22+#ifndef __USB_ETHER_H__
23+#define __USB_ETHER_H__
24+
25+#include <net.h>
26+
27+/*
28+ * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
29+ * and FCS/CRC (frame check sequence).
30+ */
31+#define ETH_ALEN 6 /* Octets in one ethernet addr */
32+#define ETH_HLEN 14 /* Total octets in header. */
33+#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
34+#define ETH_DATA_LEN 1500 /* Max. octets in payload */
35+#define ETH_FRAME_LEN PKTSIZE_ALIGN /* Max. octets in frame sans FCS */
36+#define ETH_FCS_LEN 4 /* Octets in the FCS */
37+
38+struct ueth_data {
39+ /* eth info */
40+ struct eth_device eth_dev; /* used with eth_register */
41+ int phy_id; /* mii phy id */
42+
43+ /* usb info */
44+ struct usb_device *pusb_dev; /* this usb_device */
45+ unsigned char ifnum; /* interface number */
46+ unsigned char ep_in; /* in endpoint */
47+ unsigned char ep_out; /* out ....... */
48+ unsigned char ep_int; /* interrupt . */
49+ unsigned char subclass; /* as in overview */
50+ unsigned char protocol; /* .............. */
51+ unsigned char irqinterval; /* Intervall for IRQ Pipe */
52+
53+ /* private fields for each driver can go here if needed */
54+};
55+
56+/*
57+ * Function definitions for each USB ethernet driver go here, bracketed by
58+ * #ifdef CONFIG_USB_ETHER_xxx...#endif
59+ */
60+
61+#endif /* __USB_ETHER_H__ */
--- a/net/eth.c
+++ b/net/eth.c
@@ -166,20 +166,33 @@ int eth_get_dev_index (void)
166166 return (0);
167167 }
168168
169-int eth_register(struct eth_device* dev)
169+static void eth_current_changed(void)
170170 {
171- struct eth_device *d;
172-
173- if (!eth_devices) {
174- eth_current = eth_devices = dev;
175171 #ifdef CONFIG_NET_MULTI
172+ {
173+ char *act = getenv("ethact");
176174 /* update current ethernet name */
175+ if (eth_current)
177176 {
178- char *act = getenv("ethact");
179177 if (act == NULL || strcmp(act, eth_current->name) != 0)
180178 setenv("ethact", eth_current->name);
181179 }
180+ /*
181+ * remove the variable completely if there is no active
182+ * interface
183+ */
184+ else if (act != NULL)
185+ setenv("ethact", NULL);
186+ }
182187 #endif
188+}
189+
190+int eth_register(struct eth_device *dev)
191+{
192+ struct eth_device *d;
193+ if (!eth_devices) {
194+ eth_current = eth_devices = dev;
195+ eth_current_changed();
183196 } else {
184197 for (d=eth_devices; d->next!=eth_devices; d=d->next)
185198 ;
@@ -271,14 +284,7 @@ int eth_initialize(bd_t *bis)
271284 dev = dev->next;
272285 } while(dev != eth_devices);
273286
274- /* update current ethernet name */
275- if (eth_current) {
276- char *act = getenv("ethact");
277- if (act == NULL || strcmp(act, eth_current->name) != 0)
278- setenv("ethact", eth_current->name);
279- } else
280- setenv("ethact", NULL);
281-
287+ eth_current_changed();
282288 putc ('\n');
283289 }
284290
@@ -466,10 +472,7 @@ void eth_try_another(int first_restart)
466472
467473 eth_current = eth_current->next;
468474
469- /* update current ethernet name */
470- act = getenv("ethact");
471- if (act == NULL || strcmp(act, eth_current->name) != 0)
472- setenv("ethact", eth_current->name);
475+ eth_current_changed();
473476
474477 if (first_failed == eth_current) {
475478 NetRestartWrap = 1;
@@ -500,7 +503,7 @@ void eth_set_current(void)
500503 } while (old_current != eth_current);
501504 }
502505
503- setenv("ethact", eth_current->name);
506+ eth_current_changed();
504507 }
505508
506509 char *eth_get_name (void)