LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
dev_usb_asix.c
Go to the documentation of this file.
1/* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * USB Ethernet File: dev_usb_asix.c
5 *
6 * Driver for USB Ethernet devices using the ASIX AX8817 chip.
7 *
8 *********************************************************************
9 *
10 * Copyright 2000,2001,2005
11 * Broadcom Corporation. All rights reserved.
12 *
13 * This software is furnished under license and may be used and
14 * copied only in accordance with the following terms and
15 * conditions. Subject to these conditions, you may download,
16 * copy, install, use, modify and distribute modified or unmodified
17 * copies of this software in source and/or binary form. No title
18 * or ownership is transferred hereby.
19 *
20 * 1) Any source code used, modified or distributed must reproduce
21 * and retain this copyright notice and list of conditions as
22 * they appear in the source file.
23 *
24 * 2) No right is granted to use any trade name, trademark, or
25 * logo of Broadcom Corporation. Neither the "Broadcom
26 * Corporation" name nor any trademark or logo of Broadcom
27 * Corporation may be used to endorse or promote products
28 * derived from this software without the prior written
29 * permission of Broadcom Corporation.
30 *
31 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
32 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
33 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
34 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
35 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
36 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
37 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
39 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
40 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
41 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
42 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
43 * THE POSSIBILITY OF SUCH DAMAGE.
44 ********************************************************************* */
45
46/* *********************************************************************
47 * USB-Ethernet driver - CFE Network Layer Interfaces
48 ********************************************************************* */
49
50#include "cfe.h"
51
52#include "usbd.h"
53#include "usbeth.h"
54
55/* XXX Move to usbeth.h */
56/* **************************************
57 * ASIX AX8817 adapter
58 ************************************** */
59
60#define ASIX_MII_SWOP_CMD 0x06
61#define ASIX_MII_READ_CMD 0x07
62#define ASIX_MII_WRITE_CMD 0x08
63#define ASIX_MII_HWOP_CMD 0x0a
64#define ASIX_RXCTL_CMD 0x10
65#define ASIX_IPG1_CMD 0x12
66#define ASIX_IPG2_CMD 0x13
67#define ASIX_IPG3_CMD 0x14
68#define ASIX_MAC_ADDR_CMD 0x17
69#define ASIX_PHYID_CMD 0x19
70#define ASIX_MED_WRITE_CMD 0x1b
71#define ASIX_GPIO_WRITE_CMD 0x1f
72
73
74#if 0
75#define USBETH_TRACE( x, y ... ) xprintf( x, ##y )
76#else
77#define USBETH_TRACE( x, y ... )
78#endif
79
80#define FAIL -1
81
82#define USB_MALLOC_VALUE 32
83
84
85/******************************************************************************
86 Debug functions
87******************************************************************************/
88
89#ifndef USBETH_DEBUG
90#define USBETH_DEBUG 0
91#endif
92
93
94#if USBETH_DEBUG
95static void hexdump( unsigned char *src, int srclen, int rowlen, int rows )
96{
97 unsigned char *rowptr;
98 unsigned char *srcstp;
99 unsigned char *byteptr;
100
101 srcstp = src + srclen;
102
103 for( rowptr = src; rowptr < src + rowlen * rows; rowptr += rowlen ) {
104 for( byteptr = rowptr; byteptr < rowptr + rowlen && byteptr < srcstp; byteptr++ ) {
105 xprintf( "%2X ", *byteptr );
106 }
107 xprintf( "\n" );
108 }
109 xprintf( "\n" );
110}
111#else
112#define hexdump(src,srclen,rowlen,rows) ((void)0)
113#endif
114
115
116/* *********************************************************************
117 * Interface functions for USB-Ethernet adapters
118 ********************************************************************* */
119
121static char *VENDOR_NAMES[] = {
122 "?", "Hawking", "Netgear", "Yikes!"
123};
124
125static const int ID_TBL[] = {
126 0x0846, 0x1040, NETGEAR, /* Netgear FA120 */
127 0x07b8, 0x420a, HAWKING, /* Hawking UF200 */
128 -1
129};
130
131typedef struct asix_softc_s
132{
140 uint8_t rxbuf[1600]; /* artbitrary but enough for ethernet packet */
142
143
144/* **************************************
145 * ASIX AX8817x I/F Functions
146 ************************************** */
147
148static int asix_send_eth_frame( void *ctx, hsaddr_t buf, int len );
149static int asix_get_eth_frame( void *ctx, hsaddr_t buf );
150static int asix_data_rx( void *ctx );
151static int asix_get_dev_addr( void *ctx, hsaddr_t mac_addr );
152
153static usbeth_disp_t usbeth_asix = {
154 asix_get_eth_frame,
155 asix_data_rx,
156 asix_send_eth_frame,
157 asix_get_dev_addr
158};
159
160
161static int asix_get_reg( usbdev_t *dev, uint8_t cmd, int16_t val, int16_t index, uint8_t *buf, int16_t len )
162{
164 cmd, val, index, buf, len );
165}
166
167static int asix_set_reg( usbdev_t *dev, uint8_t cmd, int16_t val, int16_t index, uint8_t *buf, int16_t len )
168{
170 cmd, val, index, buf, len );
171}
172
173static int asix_get_mac_addr( usbdev_t *dev, uint8_t *mac_addr )
174{
175 return asix_get_reg( dev, ASIX_MAC_ADDR_CMD, 0, 0, mac_addr, 6 );
176}
177
178static int asix_init_device( asix_softc_t *softc )
179{
180 usb_device_descr_t dev_desc;
181 uint16_t vendor_id, device_id;
182 const int *ptr=ID_TBL;
183
184 /* find out which device is connected */
185 usb_get_device_descriptor( softc->dev, &dev_desc, 0 );
186 vendor_id = (dev_desc.idVendorHigh << 8) + dev_desc.idVendorLow;
187 device_id = (dev_desc.idProductHigh << 8) + dev_desc.idProductLow;
188 xprintf( "USB device: vendor id %04x, device id %04x\n",
189 vendor_id, device_id );
190
191 while( *ptr != -1 ) {
192 if( (vendor_id == ptr[0]) && (device_id == ptr[1]) ) {
193 softc->dev_id = ptr[2];
194 softc->ven_code = ptr[3];
195 break;
196 }
197 ptr += 4;
198 }
199 if( *ptr == -1 ) {
200 xprintf( "Unrecognized USB-Ethernet device\n" );
201 return -1;
202 }
203
204 /* Read the adapter's MAC addr */
205 asix_get_mac_addr( softc->dev, softc->mac_addr );
206
207 /* display adapter info */
208 xprintf( "%s USB-Ethernet Adapter (%a)\n",
209 VENDOR_NAMES[softc->ven_code], softc->mac_addr);
210
211 return 0;
212}
213
214static int asix_get_dev_addr( void *ctx, hsaddr_t mac_addr )
215{
216 asix_softc_t *softc = (asix_softc_t *) ctx;
217
218 hs_memcpy_to_hs( mac_addr, softc->mac_addr, 6 );
219 return 0;
220}
221
222static void asix_queue_rx( asix_softc_t *softc )
223{
224 softc->rx_ur = usb_make_request(softc->dev, softc->bulk_inpipe,
225 softc->rxbuf, sizeof(softc->rxbuf),
227 usb_queue_request(softc->rx_ur);
228}
229
230static int asix_data_rx( void *ctx )
231{
232 asix_softc_t *softc = (asix_softc_t *) ctx;
233
234 usb_poll(softc->dev->ud_bus);
235 return( !softc->rx_ur->ur_inprogress );
236}
237
238static int asix_get_eth_frame( void *ctx, hsaddr_t buf )
239{
240 asix_softc_t *softc = (asix_softc_t *) ctx;
241 int len = 0;
242
243 if( !softc->rx_ur->ur_inprogress ) {
244 len = softc->rx_ur->ur_xferred;
245 hs_memcpy_to_hs( buf, softc->rxbuf, len );
246 usb_free_request(softc->rx_ur);
247 asix_queue_rx( softc );
248 }
249 else
250 xprintf( "Bulk data is not available yet!\n" );
251
252 return( len );
253}
254
255static int asix_send_eth_frame( void *ctx, hsaddr_t buf, int len )
256{
257 asix_softc_t *softc = (asix_softc_t *) ctx;
258 usbreq_t *ur;
259 int txlen = len;
260 unsigned char *txbuf;
261
262 txbuf = KMALLOC(txlen, USB_MALLOC_VALUE);
263 hs_memcpy_from_hs( txbuf, buf, txlen );
264 ur = usb_make_request(softc->dev, softc->bulk_outpipe,
265 txbuf, txlen, UR_FLAG_OUT);
268 KFREE(txbuf);
269
270 return( len );
271}
272
273static void asix_open_device( asix_softc_t *softc )
274{
275 usbdev_t *dev = softc->dev;
276 uint8_t data[2];
277 int16_t phyid;
278
279 asix_set_reg( dev, ASIX_MII_SWOP_CMD, 0, 0, NULL, 0 );
280 asix_get_reg( dev, ASIX_PHYID_CMD, 0, 0, data, 2 );
281
282 /* UF200 seems to need a GPIO settings */
283 asix_set_reg( dev, ASIX_GPIO_WRITE_CMD, 0x11, 0, NULL, 0 );
284 asix_set_reg( dev, ASIX_GPIO_WRITE_CMD, 0x13, 0, NULL, 0 );
285 asix_set_reg( dev, ASIX_GPIO_WRITE_CMD, 0x0c, 0, NULL, 0 );
286
287 phyid = data[1];
288 data[0] = 0; data[1] = 0;
289 asix_set_reg( dev, ASIX_MII_WRITE_CMD, phyid, 0, data, 2 );
290 data[1] = 0x80;
291 asix_set_reg( dev, ASIX_MII_WRITE_CMD, phyid, 0, data, 2 );
292 asix_set_reg( dev, ASIX_MED_WRITE_CMD, 6, 0, NULL, 0 );
293 asix_set_reg( dev, ASIX_IPG1_CMD, 0x15, 0, NULL, 0 );
294 asix_set_reg( dev, ASIX_IPG2_CMD, 0x0c, 0, NULL, 0 );
295 asix_set_reg( dev, ASIX_IPG3_CMD, 0x12, 0, NULL, 0 );
296 data[0] = 0x01; data[1] = 0x05;
297 asix_set_reg( dev, ASIX_MII_WRITE_CMD, phyid, 4, data, 2 );
298 data[0] = 0; data[1] = 0x12;
299 asix_set_reg( dev, ASIX_MII_WRITE_CMD, phyid, 0, data, 2 );
300 asix_set_reg( dev, ASIX_MII_HWOP_CMD, 0, 0, NULL, 0 );
301 asix_set_reg( dev, ASIX_RXCTL_CMD, 0x81, 0, NULL, 0 );
302
303 /* kick start the receive */
304 asix_queue_rx( softc );
305}
306
307static void asix_close_device( asix_softc_t *softc )
308{
309 /* disable adapter from receiving packets */
310 asix_set_reg( softc->dev, ASIX_RXCTL_CMD, 0, 0, NULL, 0 );
311}
312
313
314/* *********************************************************************
315 * CFE-USB interfaces
316 ********************************************************************* */
317
318/* *********************************************************************
319 * asix_attach(dev,drv)
320 *
321 * This routine is called when the bus scan stuff finds a usb-ethernet
322 * device. We finish up the initialization by configuring the
323 * device and allocating our softc here.
324 *
325 * Input parameters:
326 * dev - usb device, in the "addressed" state.
327 * drv - the driver table entry that matched
328 *
329 * Return value:
330 * 0
331 ********************************************************************* */
332
333const cfe_driver_t usbasix_driver; /* forward declaration */
334
335static int asix_attach(usbdev_t *dev,usb_driver_t *drv)
336{
337 usb_config_descr_t *cfgdscr = dev->ud_cfgdescr;
338 usb_endpoint_descr_t *epdscr;
339 usb_endpoint_descr_t *indscr = NULL;
340 usb_endpoint_descr_t *outdscr = NULL;
341 usb_interface_descr_t *ifdscr;
342 asix_softc_t *softc;
343 int idx;
344
345 dev->ud_drv = drv;
346
347 softc = (asix_softc_t *) KMALLOC( sizeof(asix_softc_t), USB_MALLOC_VALUE );
348 if( softc == NULL ) {
349 xprintf( "Failed to allocate softc memory.\n" );
350 return -1;
351 }
352 memset( softc, 0, sizeof(asix_softc_t) );
353 dev->ud_private = softc;
354 softc->dev = dev;
355
357 if (ifdscr == NULL) {
358 xprintf("USBETH: ERROR...no interace descriptor\n");
359 return -1;
360 }
361
362 for (idx = 0; idx < 3; idx++) {
366 outdscr = epdscr;
367 else
368 indscr = epdscr;
369 }
370 }
371
372 if (!indscr || !outdscr) {
373 /*
374 * Could not get descriptors, something is very wrong.
375 * Leave device addressed but not configured.
376 */
377 xprintf("USBETH: ERROR...bulk endpoint descriptor(s) missing\n");
378 return -1;
379 }
380
381 /* Choose the standard configuration. */
383
384 /* Quit if not able to initialize the device */
385 if (asix_init_device(softc) < 0)
386 return -1;
387
388 /* Open the pipes. */
389 softc->bulk_inpipe = usb_open_pipe(dev,indscr);
390 softc->bulk_outpipe = usb_open_pipe(dev,outdscr);
391
392 /* Register the device */
393 usbeth_register(&usbeth_asix, softc);
394
395 /* Open the device */
396 asix_open_device( softc );
397
398 return 0;
399}
400
401/* *********************************************************************
402 * asix_detach(dev)
403 *
404 * This routine is called when the bus scanner notices that
405 * this device has been removed from the system. We should
406 * do any cleanup that is required. The pending requests
407 * will be cancelled automagically.
408 *
409 * Input parameters:
410 * dev - usb device
411 *
412 * Return value:
413 * 0
414 ********************************************************************* */
415
416static int asix_detach(usbdev_t *dev)
417{
418 asix_softc_t *softc = (asix_softc_t *) dev->ud_private;
419
420 if (softc != NULL) {
421 usbeth_unregister( softc );
422 asix_close_device( softc );
423 dev->ud_private = NULL;
424 softc->dev = NULL;
425 KFREE(softc);
426 }
427
428 return 0;
429}
430
431/* CFE USB device interface structure */
433{
434 "Ethernet Device",
435 asix_attach,
436 asix_detach
437};
void * hsaddr_t
Definition: cfe.h:11
#define NULL
Definition: def.h:47
@ NETGEAR
Definition: dev_usb_asix.c:120
@ HAWKING
Definition: dev_usb_asix.c:120
@ VEN_NONE
Definition: dev_usb_asix.c:120
#define ASIX_IPG1_CMD
Definition: dev_usb_asix.c:65
const cfe_driver_t usbasix_driver
Definition: dev_usb_asix.c:333
#define ASIX_IPG3_CMD
Definition: dev_usb_asix.c:67
usb_driver_t usbeth_driver
Definition: dev_usb_asix.c:432
#define ASIX_MII_SWOP_CMD
Definition: dev_usb_asix.c:60
#define ASIX_MII_HWOP_CMD
Definition: dev_usb_asix.c:63
#define hexdump(src, srclen, rowlen, rows)
Definition: dev_usb_asix.c:112
#define ASIX_MII_WRITE_CMD
Definition: dev_usb_asix.c:62
#define ASIX_RXCTL_CMD
Definition: dev_usb_asix.c:64
#define ASIX_MAC_ADDR_CMD
Definition: dev_usb_asix.c:68
#define USB_MALLOC_VALUE
Definition: dev_usb_asix.c:82
#define ASIX_PHYID_CMD
Definition: dev_usb_asix.c:69
struct asix_softc_s asix_softc_t
#define ASIX_IPG2_CMD
Definition: dev_usb_asix.c:66
#define ASIX_MED_WRITE_CMD
Definition: dev_usb_asix.c:70
#define ASIX_GPIO_WRITE_CMD
Definition: dev_usb_asix.c:71
static uint32_t val
Definition: io.h:17
u32 ptr
Definition: iso9660.c:536
#define KMALLOC(size, align)
Definition: lib_malloc.h:92
#define KFREE(ptr)
Definition: lib_malloc.h:93
s16 int16_t
Definition: libfdt_env.h:15
u16 uint16_t
Definition: libfdt_env.h:10
u8 uint8_t
Definition: libfdt_env.h:9
usbdev_t * dev
Definition: dev_usb_asix.c:133
uint8_t rxbuf[1600]
Definition: dev_usb_asix.c:140
uint8_t mac_addr[6]
Definition: dev_usb_asix.c:138
usbreq_t * rx_ur
Definition: dev_usb_asix.c:139
uint8_t bConfigurationValue
Definition: usbchap9.h:216
uint8_t idVendorLow
Definition: usbchap9.h:184
uint8_t idProductLow
Definition: usbchap9.h:185
uint8_t idProductHigh
Definition: usbchap9.h:185
uint8_t idVendorHigh
Definition: usbchap9.h:184
uint8_t bmAttributes
Definition: usbchap9.h:197
uint8_t bEndpointAddress
Definition: usbchap9.h:196
Definition: usbd.h:141
usb_config_descr_t * ud_cfgdescr
Definition: usbd.h:150
usbbus_t * ud_bus
Definition: usbd.h:143
void * ud_private
Definition: usbd.h:148
usb_driver_t * ud_drv
Definition: usbd.h:142
Definition: usbd.h:171
int ur_inprogress
Definition: usbd.h:195
int ur_xferred
Definition: usbd.h:187
#define USBREQ_TYPE_VENDOR
Definition: usbchap9.h:366
#define USB_ENDPOINT_DESCRIPTOR_TYPE
Definition: usbchap9.h:66
#define USB_ENDPOINT_DIR_OUT(addr)
Definition: usbchap9.h:107
#define USBREQ_DIR_OUT
Definition: usbchap9.h:363
#define USB_ENDPOINT_TYPE_MASK
Definition: usbchap9.h:78
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usbchap9.h:65
#define USBREQ_DIR_IN
Definition: usbchap9.h:362
#define USB_ENDPOINT_TYPE_BULK
Definition: usbchap9.h:82
void * usb_find_cfg_descr(usbdev_t *dev, int dtype, int idx)
Definition: usbd.c:1237
int usb_std_request(usbdev_t *dev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *buffer, int length)
Definition: usbd.c:796
int usb_sync_request(usbreq_t *ur)
Definition: usbd.c:550
usbreq_t * usb_make_request(usbdev_t *dev, int epaddr, uint8_t *buf, int length, int flags)
Definition: usbd.c:353
void usb_free_request(usbreq_t *ur)
Definition: usbd.c:457
void usb_poll(usbbus_t *bus)
Definition: usbd.c:392
int usb_queue_request(usbreq_t *ur)
Definition: usbd.c:502
int usb_get_device_descriptor(usbdev_t *dev, usb_device_descr_t *dscr, int smallflg)
Definition: usbd.c:1006
int usb_set_configuration(usbdev_t *dev, int config)
Definition: usbd.c:619
int usb_open_pipe(usbdev_t *dev, usb_endpoint_descr_t *epdesc)
Definition: usbd.c:165
#define UR_FLAG_OUT
Definition: usbd.h:165
#define UR_FLAG_IN
Definition: usbd.h:164
#define UR_FLAG_SHORTOK
Definition: usbd.h:168
int usbeth_register(usbeth_disp_t *disp, void *softc)
Definition: usbeth.c:78
void usbeth_unregister(void *softc)
Definition: usbeth.c:97
int xprintf(char *str)
Definition: usbhack.c:404
union @15 data