LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
dev_usb_rtek.c
Go to the documentation of this file.
1/* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * USB Ethernet File: dev_usb_rtek.c
5 *
6 * Driver for USB Ethernet devices using Realtek RTL8150 chip.
7 *
8 *********************************************************************
9 *
10 * Copyright 2000,2001,2002,2003,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
22 * as 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. The "Broadcom Corporation"
26 * name may not be used to endorse or promote products derived
27 * from this software without the prior written permission of
28 * Broadcom Corporation.
29 *
30 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
32 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
33 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
34 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
35 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
36 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
38 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
40 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
41 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
42 * THE POSSIBILITY OF SUCH DAMAGE.
43 ********************************************************************* */
44
45/* *********************************************************************
46 * USB-Ethernet driver - CFE Network Layer Interfaces
47 ********************************************************************* */
48
49#include "cfe.h"
50
51#include "usbd.h"
52#include "usbeth.h"
53
54#if 0
55#define USBETH_TRACE( x, y ... ) xprintf( x, ##y )
56#else
57#define USBETH_TRACE( x, y ... ) ((void)0)
58#endif
59
60#define FAIL -1
61
62#define CACHE_ALIGN 32 /* XXX place holder, big enough to now. */
63#define ALIGN(n,align) (((n)+((align)-1)) & ~((align)-1))
64
65#define usb_dma_alloc(n) (KMALLOC(ALIGN((n),CACHE_ALIGN),CACHE_ALIGN))
66#define usb_dma_free(p) (KFREE(p))
67
68/******************************************************************************
69 Debug functions
70******************************************************************************/
71
72#ifndef USBETH_DEBUG
73#define USBETH_DEBUG 0
74#endif
75
76#if USBETH_DEBUG
77static void hexdump( unsigned char *src, int srclen, int rowlen, int rows )
78{
79 unsigned char *rowptr;
80 unsigned char *srcstp;
81 unsigned char *byteptr;
82
83 srcstp = src + srclen;
84
85 for( rowptr = src; rowptr < src + rowlen * rows; rowptr += rowlen ) {
86 for( byteptr = rowptr; byteptr < rowptr + rowlen && byteptr < srcstp; byteptr++ ) {
87 xprintf( "%2X ", *byteptr );
88 }
89 xprintf( "\n" );
90 }
91 xprintf( "\n" );
92}
93#else
94#define hexdump(src,srclen,rowlen,rows) ((void)0)
95#endif
96
97
98/* *********************************************************************
99 * Interface functions for USB-Ethernet adapters
100 ********************************************************************* */
101
103static const char *VENDOR_NAMES[] = {
104 "?", "Linksys-100M", "Yikes!"
105};
106
107static const int ID_TBL[] = {
108 0x0BDA, 0x8150, LINKSYS_100M,
109 -1
110};
111
112typedef struct rtek_softc_s {
119 uint8_t rxbuf[1600]; /* arbitrary but enough for ethernet packet */
121
122
123/* **************************************
124 * REALTEK RTL8150 I/F Functions.
125 ************************************** */
126
127static int rtek_send_eth_frame( void *ctx, hsaddr_t buf, int len );
128static int rtek_get_eth_frame( void *ctx, hsaddr_t buf );
129static int rtek_data_rx( void *ctx );
130static int rtek_get_dev_addr( void *ctx, hsaddr_t mac_addr );
131
132static usbeth_disp_t usbeth_rtek = {
133 rtek_get_eth_frame,
134 rtek_data_rx,
135 rtek_send_eth_frame,
136 rtek_get_dev_addr
137};
138
139
140static int rtek_get_reg( usbdev_t *dev, int16_t reg, uint8_t *val, int16_t len )
141{
143 RTEK_REG_ACCESS, reg, 0, val, len );
144}
145
146static int rtek_set_reg( usbdev_t *dev, int16_t reg, int8_t val )
147{
148 uint8_t data[1];
149
150 data[0] = val;
152 RTEK_REG_ACCESS, reg, 0, data, 1 );
153}
154
155static int rtek_get_mac_addr( usbdev_t *dev, uint8_t *mac_addr )
156{
157 return rtek_get_reg( dev, R_RTEK_MAC, mac_addr, 6 );
158}
159
160static int rtek_init_device( rtek_softc_t *softc )
161{
162 usb_device_descr_t dev_desc;
163 uint16_t vendor_id, product_id;
164 const int *ptr=ID_TBL;
165 int i;
166 usbdev_t *dev = softc->dev;
167 uint8_t val;
168
169 /* find out which device is connected */
170 usb_get_device_descriptor( softc->dev, &dev_desc, 0 );
171 vendor_id = (dev_desc.idVendorHigh << 8) + dev_desc.idVendorLow;
172 product_id = (dev_desc.idProductHigh << 8) + dev_desc.idProductLow;
173
174 while( *ptr != -1 ) {
175 if( (vendor_id == ptr[0]) && (product_id == ptr[1]) ) {
176 softc->ven_code = ptr[2];
177 break;
178 }
179 ptr += 3;
180 }
181 if( *ptr == -1 ) {
182 xprintf( "Unrecognized Realtek USB-Ethernet device\n" );
183 return -1;
184 }
185
186 /* Reset the adapter */
187 rtek_set_reg( dev, R_RTEK_CMD, RTEK_RESET );
188 for( i = 0; i < 10; ++i ) {
189 rtek_get_reg( dev, R_RTEK_CMD, &val, 1 );
190 if( !(val & RTEK_RESET) )
191 break;
192 usb_delay_ms( NULL, 1 );
193 }
194
195 /* Autoload the internal registers */
196 rtek_set_reg( dev, R_RTEK_CMD, RTEK_AUTOLOAD );
197 for( i = 0; i < 50; ++i ) {
198 rtek_get_reg( dev, R_RTEK_CMD, &val, 1 );
199 if( !(val & RTEK_AUTOLOAD) )
200 break;
201 usb_delay_ms( NULL, 1 );
202 }
203
204 /* Read the adapter's MAC addr */
205 rtek_get_mac_addr( 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 rtek_get_dev_addr( void *ctx, hsaddr_t mac_addr )
215{
216 rtek_softc_t *softc = (rtek_softc_t *) ctx;
217 hs_memcpy_to_hs( mac_addr, softc->mac_addr, 6 );
218 return 0;
219}
220
221static void rtek_queue_rx( rtek_softc_t *softc )
222{
223 softc->rx_ur = usb_make_request(softc->dev, softc->bulk_inpipe,
224 softc->rxbuf, sizeof(softc->rxbuf),
226 usb_queue_request(softc->rx_ur);
227}
228
229static int rtek_data_rx( void *ctx )
230{
231 rtek_softc_t *softc = (rtek_softc_t *) ctx;
232 usb_poll(softc->dev->ud_bus);
233 return( !softc->rx_ur->ur_inprogress );
234}
235
236static int rtek_get_eth_frame( void *ctx, hsaddr_t buf )
237{
238 int len = 0;
239 rtek_softc_t *softc = (rtek_softc_t *) ctx;
240 uint8_t *rxbuf;
241
242 if( !softc->rx_ur->ur_inprogress ) {
243 rxbuf = softc->rxbuf;
244 len = softc->rx_ur->ur_xferred;
245 if (len > 0) {
246#if USBETH_DEBUG
247 xprintf( "Incoming packet :\n" );
248 hexdump( rxbuf, len, 16, len / 16 + 1 );
249#endif
250 hs_memcpy_to_hs( buf, rxbuf, len );
251 }
252 usb_free_request(softc->rx_ur);
253 rtek_queue_rx( softc );
254 }
255 else
256 xprintf( "Bulk data is not available yet!\n" );
257
258 return( len );
259}
260
261static int rtek_send_eth_frame( void *ctx, hsaddr_t buf, int len )
262{
263 rtek_softc_t *softc = (rtek_softc_t *) ctx;
264 usbreq_t *ur;
265 int txlen = len;
266 unsigned char *txbuf;
267
268 /* First some Realtek chip workarounds */
269 if( txlen < 60 ) /* some strange limitation */
270 txlen = 60;
271 else if( !(txlen % 64) ) /* to handle module 64 packets */
272 ++txlen;
273
274 txbuf = usb_dma_alloc(txlen);
275 hs_memcpy_from_hs( txbuf, buf, txlen );
276
277#if USBETH_DEBUG
278 xprintf( "Outgoing packet :\n" );
279 hexdump( txbuf, txlen, 16, txlen / 16 + 1 );
280#endif
281 ur = usb_make_request(softc->dev, softc->bulk_outpipe,
282 txbuf, txlen, UR_FLAG_OUT);
285 usb_dma_free(txbuf);
286
287 return( len );
288}
289
290static void rtek_open_device( rtek_softc_t *softc )
291{
292 /* Accept broadcast & own packets */
293 rtek_set_reg( softc->dev, R_RTEK_RXCFG, RTEK_MACADDR | RTEK_BCASTADDR );
294
295 /* Enable adapter to receive and transmit packets */
296 rtek_set_reg( softc->dev, R_RTEK_CMD, RTEK_RXENABLE | RTEK_TXENABLE );
297
298 /* kick start the receive */
299 rtek_queue_rx( softc );
300}
301
302
303static void rtek_close_device( rtek_softc_t *softc )
304{
305 usbdev_t *dev = softc->dev;
306
307 /* Disable adapter from receiving or transmitting packets */
308 rtek_set_reg( dev, R_RTEK_CMD, 0 );
309}
310
311
312/* *********************************************************************
313 * CFE-USB interfaces
314 ********************************************************************* */
315
316/* *********************************************************************
317 * rtek_attach(dev,drv)
318 *
319 * This routine is called when the bus scan stuff finds a usb-ethernet
320 * device. We finish up the initialization by configuring the
321 * device and allocating our softc here.
322 *
323 * Input parameters:
324 * dev - usb device, in the "addressed" state.
325 * drv - the driver table entry that matched
326 *
327 * Return value:
328 * 0
329 ********************************************************************* */
330
331const cfe_driver_t usbrtekdrv; /* forward declaration */
332
333static int rtek_attach(usbdev_t *dev, usb_driver_t *drv)
334{
335 usb_config_descr_t *cfgdscr = dev->ud_cfgdescr;
336 usb_endpoint_descr_t *epdscr;
337 usb_endpoint_descr_t *indscr = NULL;
338 usb_endpoint_descr_t *outdscr = NULL;
339 usb_interface_descr_t *ifdscr;
340 rtek_softc_t *softc;
341 int idx;
342
343 dev->ud_drv = drv;
344
345 softc = (rtek_softc_t *) KMALLOC( sizeof(rtek_softc_t), 0 );
346 if( softc == NULL ) {
347 xprintf( "Failed to allocate softc memory.\n" );
348 return -1;
349 }
350 memset( softc, 0, sizeof(rtek_softc_t) );
351 dev->ud_private = softc;
352 softc->dev = dev;
353
355 if (ifdscr == NULL) {
356 xprintf("USBETH: ERROR...no interace descriptor\n");
357 return -1;
358 }
359
360 for (idx = 0; idx < 2; idx++) {
363 outdscr = epdscr;
364 else
365 indscr = epdscr;
366 }
367
368 if (!indscr || !outdscr) {
369 /*
370 * Could not get descriptors, something is very wrong.
371 * Leave device addressed but not configured.
372 */
373 xprintf("USBETH: ERROR...no endpoint descriptors\n");
374 return -1;
375 }
376
377 /* Choose the standard configuration. */
379
380 /* Quit if not able to initialize the device */
381 if (rtek_init_device(softc) < 0)
382 return -1;
383
384 /* Open the pipes. */
385 softc->bulk_inpipe = usb_open_pipe(dev,indscr);
386 softc->bulk_outpipe = usb_open_pipe(dev,outdscr);
387
388 /* Register the device */
389 usbeth_register(&usbeth_rtek,softc);
390
391 /* Open the device */
392 rtek_open_device( softc );
393
394 return 0;
395}
396
397/* *********************************************************************
398 * rtek_detach(dev)
399 *
400 * This routine is called when the bus scanner notices that
401 * this device has been removed from the system. We should
402 * do any cleanup that is required. The pending requests
403 * will be cancelled automagically.
404 *
405 * Input parameters:
406 * dev - usb device
407 *
408 * Return value:
409 * 0
410 ********************************************************************* */
411
412static int rtek_detach(usbdev_t *dev)
413{
414 rtek_softc_t *softc = (rtek_softc_t *) dev->ud_private;
415
416 if (softc != NULL) {
417 usbeth_unregister( softc );
418 rtek_close_device( softc );
419 dev->ud_private = NULL;
420 softc->dev = NULL;
421 KFREE(softc);
422 }
423
424 return 0;
425}
426
427/* CFE USB device interface structure */
429{
430 "Ethernet Device",
431 rtek_attach,
432 rtek_detach
433};
434
435
436
437
void * hsaddr_t
Definition: cfe.h:11
#define NULL
Definition: def.h:47
#define hexdump(src, srclen, rowlen, rows)
Definition: dev_usb_rtek.c:94
#define usb_dma_free(p)
Definition: dev_usb_rtek.c:66
struct rtek_softc_s rtek_softc_t
#define usb_dma_alloc(n)
Definition: dev_usb_rtek.c:65
usb_driver_t usbrtek_driver
Definition: dev_usb_rtek.c:428
const cfe_driver_t usbrtekdrv
Definition: dev_usb_rtek.c:331
@ LINKSYS_100M
Definition: dev_usb_rtek.c:102
@ VEN_NONE
Definition: dev_usb_rtek.c:102
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
s8 int8_t
Definition: libfdt_env.h:14
s16 int16_t
Definition: libfdt_env.h:15
u16 uint16_t
Definition: libfdt_env.h:10
u8 uint8_t
Definition: libfdt_env.h:9
uint8_t rxbuf[1600]
Definition: dev_usb_rtek.c:119
usbreq_t * rx_ur
Definition: dev_usb_rtek.c:118
uint8_t mac_addr[6]
Definition: dev_usb_rtek.c:117
usbdev_t * dev
Definition: dev_usb_rtek.c:113
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 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_INTERFACE_DESCRIPTOR_TYPE
Definition: usbchap9.h:65
#define USBREQ_DIR_IN
Definition: usbchap9.h:362
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
void usb_delay_ms(usbbus_t *bus, int ms)
Definition: usbd.c:482
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
#define RTEK_AUTOLOAD
Definition: usbeth.h:125
#define R_RTEK_MAC
Definition: usbeth.h:117
#define RTEK_RXENABLE
Definition: usbeth.h:127
#define RTEK_RESET
Definition: usbeth.h:128
#define RTEK_TXENABLE
Definition: usbeth.h:126
#define RTEK_MACADDR
Definition: usbeth.h:131
#define R_RTEK_RXCFG
Definition: usbeth.h:120
#define RTEK_BCASTADDR
Definition: usbeth.h:132
#define RTEK_REG_ACCESS
Definition: usbeth.h:115
#define R_RTEK_CMD
Definition: usbeth.h:118
int xprintf(char *str)
Definition: usbhack.c:404
union @15 data