RT-AC66 3.0.0.4.374.130 core
[tomato.git] / release / src-rt-6.x / cfe / cfe / usb / usbeth.c
blob234708b0d525203f1834fa2bc9c599b4ea701245
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * USB Ethernet File: usbeth.c
5 *
6 * Driver for USB Ethernet devices.
7 *
8 *********************************************************************
10 * Copyright 2000,2001,2002,2003
11 * Broadcom Corporation. All rights reserved.
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.
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.
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.
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 ********************************************************************* */
45 /* *********************************************************************
46 * USB-Ethernet driver - CFE Network Layer Interfaces
47 * NOTE: Some of the device setup for the Admtek & Realtek devices
48 * was derived from reverse engineering! So these interfaces
49 * assume proper device operation.
50 ********************************************************************* */
52 #include "lib_types.h"
53 #include "lib_malloc.h"
54 #include "lib_string.h"
55 #include "lib_printf.h"
57 #include "cfe_iocb.h"
58 #include "cfe_ioctl.h"
59 #include "cfe_timer.h"
60 #include "cfe_device.h"
61 #include "cfe_devfuncs.h"
62 #include "cfe_error.h"
64 #include "usbd.h"
65 #include "usbeth.h"
67 #define USBETH_TRACE( x, y ... )
69 #define FAIL -1
71 static int Dev_cnt = 0;
74 /******************************************************************************
75 Debug functions
76 ******************************************************************************/
78 //#define DATA_DUMP
79 #ifdef DATA_DUMP
80 static void hexdump( unsigned char * src, int srclen, int rowlen, int rows )
82 unsigned char * rowptr;
83 unsigned char * srcstp;
84 unsigned char * byteptr;
86 srcstp = src + srclen;
88 for( rowptr = src; rowptr < src + rowlen * rows; rowptr += rowlen ) {
89 for( byteptr = rowptr; byteptr < rowptr + rowlen && byteptr < srcstp; byteptr++ ) {
90 xprintf( "%2X ", *byteptr );
92 xprintf( "\n" );
94 xprintf( "\n" );
96 #endif
99 /* *********************************************************************
100 * Interface functions for USB-Ethernet adapters
101 ********************************************************************* */
103 enum { PEGASUS, PEGASUS_II, NETMATE, REALTEK };
104 enum { VEN_NONE, _3_COM, LINKSYS, LINKSYS_10, LINKSYS_100,
105 CATC_NM, BELKIN_CATC, LINKSYS_100M };
106 static char * VENDOR_NAMES[] =
108 "?", "3-COM", "LinkSys", "LinkSys-10TX", "LinkSys-100TX",
109 "CATC-Netmate", "Belkin/CATC", "Linksys-100M", "Yikes!"
112 typedef struct usbeth_softc_s
114 usbdev_t *dev;
115 int bulk_inpipe;
116 int bulk_outpipe;
117 int dev_id;
118 int ven_code;
119 int embed_tx_len;
120 uint8_t mac_addr[6];
121 usbreq_t *rx_ur;
122 uint8_t rxbuf[1600]; //artbitrary but enough for ethernet packet
123 } usbeth_softc_t;
126 /* **************************************
127 * CATC I/F Functions
128 ************************************** */
131 static int catc_set_reg( usbdev_t *dev, int16_t reg, int16_t val )
133 return usb_std_request( dev, (USBREQ_TYPE_VENDOR | USBREQ_DIR_OUT),
134 CATC_SET_REG, val, reg, NULL, 0 );
137 static int catc_set_mem( usbdev_t *dev, int16_t addr,
138 uint8_t *data, int16_t len )
140 return usb_std_request( dev, (USBREQ_TYPE_VENDOR | USBREQ_DIR_OUT),
141 CATC_SET_MEM, 0, addr, data, len );
144 static int catc_get_mac_addr( usbdev_t *dev, uint8_t *mac_addr )
146 int status;
148 status = usb_std_request( dev, (USBREQ_TYPE_VENDOR | USBREQ_DIR_IN),
149 CATC_GET_MAC_ADDR, 0, 0, mac_addr, 6 );
150 return( status );
153 static void catc_init_device( usbeth_softc_t * softc )
155 usbdev_t *dev = softc->dev;
156 unsigned char *mcast_tbl;
158 usb_std_request( dev, (USBREQ_TYPE_STD | USBREQ_REC_INTERFACE),
159 USB_REQUEST_SET_INTERFACE,
160 1, //alt setting 1
161 0, NULL, 0 );
163 catc_set_reg(dev, CATC_TX_BUF_CNT_REG, 0x04 );
164 catc_set_reg(dev, CATC_RX_BUF_CNT_REG, 0x10 );
165 catc_set_reg(dev, CATC_ADV_OP_MODES_REG, 0x01 );
166 catc_set_reg(dev, CATC_LED_CTRL_REG, 0x08 );
168 /* Enable broadcast rx via bit in mutlicast table */
169 mcast_tbl = KMALLOC(64, 0);
170 memset( mcast_tbl, 0, 64 );
171 mcast_tbl[31] = 0x80; //i.e. broadcast bit
172 catc_set_mem( dev, CATC_MCAST_TBL_ADDR, mcast_tbl, 64 );
173 KFREE(mcast_tbl);
175 //Read the adapter's MAC addr
176 catc_get_mac_addr( dev, softc->mac_addr );
179 static void catc_close_device( usbdev_t *dev )
181 // Now disable adapter from receiving packets
182 catc_set_reg( dev, CATC_ETH_CTRL_REG, 0 );
185 static void catc_open_device( usbeth_softc_t * softc )
187 int i;
189 for(i = 0; i < 6; ++i)
190 catc_set_reg( softc->dev, (CATC_ETH_ADDR_0_REG - i), softc->mac_addr[i] );
192 // Now enable adapter to receive packets
193 catc_set_reg( softc->dev, CATC_ETH_CTRL_REG, 0x09 );
196 /* **************************************
197 * PEGASUS I/F Functions
198 ************************************** */
200 static int peg_get_reg( usbdev_t *dev, int16_t reg, uint8_t *val, int16_t len )
202 return usb_std_request( dev, (USBREQ_TYPE_VENDOR | USBREQ_DIR_IN),
203 PEG_GET_REG, 0, reg, val, len );
206 static int peg_set_reg( usbdev_t *dev, int16_t reg, int16_t val )
208 unsigned char data = (uint8_t) val & 0xff;
210 return usb_std_request( dev, (USBREQ_TYPE_VENDOR | USBREQ_DIR_OUT),
211 PEG_SET_REG, val, reg, &data, 1 );
214 static int peg_set_regs( usbdev_t *dev, int16_t reg, int8_t *vals, int16_t len )
216 return usb_std_request( dev, (USBREQ_TYPE_VENDOR | USBREQ_DIR_OUT),
217 PEG_SET_REG, 0, reg, vals, len );
220 static int peg_get_eep_word( usbdev_t *dev, int16_t ofs, uint8_t *val )
222 int status=0, tries=20;
223 uint8_t data[2];
225 if( peg_set_reg( dev, PEG_EEPROM_CTL_REG, 0 ) == FAIL )
226 return FAIL;
227 if( peg_set_reg( dev, PEG_EEPROM_OFS_REG, ofs ) == FAIL )
228 return FAIL;
229 if( peg_set_reg( dev, PEG_EEPROM_CTL_REG, 0x02 ) == FAIL ) //read
230 return FAIL;
231 while( --tries )
233 if( peg_get_reg( dev, PEG_EEPROM_CTL_REG, data, 1 ) == FAIL )
234 return FAIL;
235 if( data[0] & 0x04 )
236 break; //eeprom data ready
238 if( !tries )
240 xprintf( "Pegasus Eeprom read failed!\n" );
241 return FAIL;
243 if( peg_get_reg( dev, PEG_EEPROM_DATA_REG, data, 2 ) == FAIL )
244 return FAIL;
245 val[0] = data[0];
246 val[1] = data[1];
248 return( status );
251 static int peg_get_mac_addr( usbdev_t *dev, uint8_t *mac_addr )
253 int i, status;
255 for( i = 0; i < 3; ++i )
257 status = peg_get_eep_word( dev, i, &mac_addr[i*2] );
259 return( status );
262 static void peg_init_phy( usbdev_t *dev )
263 { //needed for earlier versions (before Rev B) of the USB-100TX adapters
264 static uint8_t phy_magic_wr[] = { 0, 4, 0, 0x1b };
265 static uint8_t read_status[] = { 0, 0, 0, 1 };
266 uint8_t data[4];
268 //reset the MAC ans set up GPIOs
269 peg_set_reg( dev, PEG_ETH_CTL1_REG, 0x08 );
270 peg_get_reg( dev, PEG_ETH_CTL1_REG, data, 1 );
272 //do following steps to enable link activitiy LED
273 peg_set_reg( dev, PEG_GPIO1_REG, 0x26 );
274 peg_set_reg( dev, PEG_GPIO0_REG, 0x24 );
275 peg_set_reg( dev, PEG_GPIO0_REG, 0x26 );
277 //do following set of steps to enable LINK LED
278 memcpy( data, phy_magic_wr, 4 );
279 peg_set_regs( dev, PEG_PHY_ADDR_REG, data, 4); //set up for magic word
280 peg_set_reg( dev, PEG_PHY_CTRL_REG, (0x1b|PHY_WRITE) );
281 peg_get_reg( dev, PEG_PHY_CTRL_REG, data, 1 ); //read status of write
282 memcpy( data, read_status, 4 );
283 peg_set_regs( dev, PEG_PHY_ADDR_REG, data, 4); //set up for phy status reg
284 peg_set_reg( dev, PEG_PHY_CTRL_REG, (1|PHY_READ) );
285 peg_get_reg( dev, PEG_PHY_CTRL_REG, data, 1 ); //read status of read
286 peg_get_reg( dev, PEG_PHY_DATA_REG, data, 2 ); //read status regs
289 static void peg_init_device( usbeth_softc_t * softc )
291 usbdev_t *dev = softc->dev;
293 if( softc->dev_id == PEGASUS_II )
294 peg_set_reg( dev, PEG_INT_PHY_REG, 0x02 ); //enable internal PHY
295 else
296 peg_init_phy( dev );
298 //Read the adapter's MAC addr
299 peg_get_mac_addr( dev, softc->mac_addr );
302 static void peg_close_device( usbdev_t *dev )
304 //Now disable adapter from receiving or transmitting packets
305 peg_set_reg( dev, PEG_ETH_CTL1_REG, 0 );
308 static void peg_open_device( usbeth_softc_t * softc )
310 usbdev_t *dev = softc->dev;
312 //Now setup adapter's receiver with MAC address
313 peg_set_regs( dev, PEG_MAC_ADDR_0_REG, softc->mac_addr, 6 );
315 //Now enable adapter to receive and transmit packets
316 peg_set_reg( dev, PEG_ETH_CTL0_REG, 0xc1 );
317 peg_set_reg( dev, PEG_ETH_CTL1_REG, 0x30 );
320 /* **************************************
321 * REALTEK I/F Functions
322 ************************************** */
325 // ********** NOT FULLY WORKING YET!!!!!!!!!! ***************
328 static int rtek_get_reg( usbdev_t *dev, int16_t reg, uint8_t *val, int16_t len )
330 return usb_std_request( dev, (USBREQ_TYPE_VENDOR | USBREQ_DIR_IN),
331 RTEK_REG_ACCESS, reg, 0, val, len );
334 static int rtek_set_reg( usbdev_t *dev, int16_t reg, int16_t val )
336 unsigned char data = (uint8_t) val & 0xff;
338 return usb_std_request( dev, (USBREQ_TYPE_VENDOR | USBREQ_DIR_OUT),
339 RTEK_REG_ACCESS, reg, 0, &data, 1 );
342 static int rtek_get_mac_addr( usbdev_t *dev, uint8_t *mac_addr )
344 int status;
346 status = rtek_get_reg( dev, RTEK_MAC_REG, mac_addr, 6 );
348 return( status );
351 static void rtek_init_device( usbeth_softc_t * softc )
353 int i;
354 usbdev_t *dev = softc->dev;
355 uint8_t val;
357 //Reset the adapter
358 rtek_set_reg( dev, RTEK_CMD_REG, RTEK_RESET );
359 for( i = 0; i < 10; ++i )
361 rtek_get_reg( dev, RTEK_CMD_REG, &val, 1 );
362 if( !(val & RTEK_RESET) )
363 break;
364 usb_delay_ms( NULL, 1 );
367 //autoload the internal registers
368 rtek_set_reg( dev, RTEK_CMD_REG, RTEK_AUTOLOAD );
369 for( i = 0; i < 50; ++i )
371 rtek_get_reg( dev, RTEK_CMD_REG, &val, 1 );
372 if( !(val & RTEK_AUTOLOAD) )
373 break;
374 usb_delay_ms( NULL, 1 );
377 //Read the adapter's MAC addr
378 rtek_get_mac_addr( dev, softc->mac_addr );
381 static void rtek_close_device( usbdev_t *dev )
383 //Now disable adapter from receiving or transmitting packets
384 rtek_set_reg( dev, RTEK_CMD_REG, 0 );
387 static void rtek_open_device( usbeth_softc_t * softc )
389 //accept broadcast & own packets
390 rtek_set_reg( softc->dev, RTEK_RXCFG_REG, 0x0c );
392 //Now enable adapter to receive and transmit packets
393 rtek_set_reg( softc->dev, RTEK_CMD_REG, 0x0c );
396 //*********************** USB-ETH I/F Functions ****************************
398 static const int ID_TBL[] =
400 0x0506, 0x4601, PEGASUS_II, _3_COM, //3-Com
401 0x066b, 0x2202, PEGASUS_II, LINKSYS_10, //LinkSys
402 0x066b, 0x2203, PEGASUS, LINKSYS_100,
403 0x066b, 0x2204, PEGASUS, LINKSYS_100,
404 0x066b, 0x2206, PEGASUS, LINKSYS,
405 0x066b, 0x400b, PEGASUS_II, LINKSYS_10,
406 0x066b, 0x200c, PEGASUS_II, LINKSYS_10,
407 0x0bda, 0x8150, REALTEK, LINKSYS_100M,
408 0x0423, 0x000a, NETMATE, CATC_NM, //CATC (Netmate I)
409 0x0423, 0x000c, NETMATE, BELKIN_CATC, //Belkin & CATC (Netmate II)
413 static int usbeth_init_device( usbeth_softc_t * softc )
415 int i;
416 usb_device_descr_t dev_desc;
417 uint16_t vendor_id, device_id;
418 const int *ptr=ID_TBL;
420 //find out which device is connected
421 usb_get_device_descriptor( softc->dev, &dev_desc, 0 );
422 vendor_id = (dev_desc.idVendorHigh << 8) + dev_desc.idVendorLow;
423 device_id = (dev_desc.idProductHigh << 8) + dev_desc.idProductLow;
424 xprintf( "USB device: vendor id %04x, device id %04x\n",
425 vendor_id, device_id );
427 while( *ptr != -1 )
429 if( (vendor_id == ptr[0]) && (device_id == ptr[1]) )
431 softc->dev_id = ptr[2];
432 softc->ven_code = ptr[3];
433 break;
435 ptr += 4;
437 if( *ptr == -1 )
439 xprintf( "Unrecognized USB-Ethernet device\n" );
440 return -1;
443 //init the adapter
444 if( softc->dev_id == NETMATE )
446 catc_init_device( softc );
447 softc->embed_tx_len = 1;
449 else
451 if( softc->dev_id == REALTEK )
453 rtek_init_device( softc );
454 softc->embed_tx_len = 0;
456 else
458 peg_init_device( softc );
459 softc->embed_tx_len = 1;
463 //display adapter info
464 xprintf( "%s USB-Ethernet Adapter (", VENDOR_NAMES[softc->ven_code] );
465 for( i = 0; i < 6; ++i )
466 xprintf( "%02x%s", softc->mac_addr[i], (i == 5) ? ")\n" : ":" );
468 return 0;
471 static int usbeth_get_dev_addr( usbeth_softc_t * softc, uint8_t *mac_addr )
473 memcpy( mac_addr, softc->mac_addr, 6 );
474 return 0;
477 static void usbeth_queue_rx( usbeth_softc_t * softc )
479 softc->rx_ur = usb_make_request(softc->dev, softc->bulk_inpipe,
480 softc->rxbuf, sizeof(softc->rxbuf),
481 (UR_FLAG_IN | UR_FLAG_SHORTOK));
482 usb_queue_request(softc->rx_ur);
485 static void usbeth_close_device( usbeth_softc_t * softc )
487 if( softc->dev_id == NETMATE )
488 catc_close_device( softc->dev );
489 else if( softc->dev_id == REALTEK )
490 rtek_close_device( softc->dev );
491 else
492 peg_close_device( softc->dev );
495 static void usbeth_open_device( usbeth_softc_t * softc )
497 if( softc->dev_id == NETMATE )
498 catc_open_device( softc );
499 else if( softc->dev_id == REALTEK )
500 rtek_open_device( softc );
501 else
502 peg_open_device( softc );
504 //kick start the receive
505 usbeth_queue_rx( softc );
508 static int usbeth_data_rx( usbeth_softc_t * softc )
510 usb_poll(softc->dev->ud_bus);
511 return( !softc->rx_ur->ur_inprogress );
514 static int usbeth_get_eth_frame( usbeth_softc_t * softc, unsigned char * buf )
516 int len = 0;
518 if( !softc->rx_ur->ur_inprogress )
520 len = softc->rx_ur->ur_xferred;
521 memcpy( buf, softc->rxbuf, len );
522 usb_free_request(softc->rx_ur);
523 usbeth_queue_rx( softc );
525 else
526 xprintf( "Bulk data is not available yet!\n" );
528 return( len );
531 static int usbeth_send_eth_frame( usbeth_softc_t * softc, unsigned char * buf, int len )
533 usbreq_t *ur;
534 int txlen = len;
535 unsigned char * txbuf;
537 if(softc->embed_tx_len)
539 txbuf = KMALLOC((len+2), 0);
540 txbuf[0] = txlen & 0xff;
541 txbuf[1] = (txlen >> 8) & 0xff; //1st two bytes...little endian
542 memcpy( &txbuf[2], buf, txlen );
543 txlen += 2;
545 else
547 if( softc->dev_id == REALTEK )
549 //Now for some Realtek chip workarounds
550 if( txlen < 60 ) //some strange limitation
551 txlen = 60;
552 else if( !(txlen % 64) ) //to handle module 64 packets
553 ++txlen;
555 txbuf = KMALLOC(txlen, 0);
556 memcpy( txbuf, buf, txlen );
558 ur = usb_make_request(softc->dev, softc->bulk_outpipe,
559 txbuf, txlen, UR_FLAG_OUT);
560 usb_sync_request(ur);
561 usb_free_request(ur);
562 KFREE(txbuf);
564 return( len );
568 /* *********************************************************************
569 * CFE-USB interfaces
570 ********************************************************************* */
572 /* *********************************************************************
573 * usbeth_attach(dev,drv)
575 * This routine is called when the bus scan stuff finds a usb-ethernet
576 * device. We finish up the initialization by configuring the
577 * device and allocating our softc here.
579 * Input parameters:
580 * dev - usb device, in the "addressed" state.
581 * drv - the driver table entry that matched
583 * Return value:
585 ********************************************************************* */
587 const cfe_driver_t usbethdrv; //forward declaration
589 static int usbeth_attach(usbdev_t *dev,usb_driver_t *drv)
591 usb_config_descr_t *cfgdscr = dev->ud_cfgdescr;
592 usb_endpoint_descr_t *epdscr;
593 usb_endpoint_descr_t *indscr = NULL;
594 usb_endpoint_descr_t *outdscr = NULL;
595 usb_interface_descr_t *ifdscr;
596 usbeth_softc_t *softc;
597 int idx;
599 dev->ud_drv = drv;
601 softc = (usbeth_softc_t *) KMALLOC( sizeof(usbeth_softc_t), 0 );
602 if( softc == NULL )
604 xprintf( "Failed to allocate softc memory.\n" );
605 return -1;
607 memset( softc, 0, sizeof(usbeth_softc_t) );
608 dev->ud_private = softc;
609 softc->dev = dev;
611 ifdscr = usb_find_cfg_descr(dev,USB_INTERFACE_DESCRIPTOR_TYPE,0);
612 if (ifdscr == NULL)
614 xprintf("USBETH: ERROR...no interace descriptor\n");
615 return -1;
619 for (idx = 0; idx < 2; idx++)
621 epdscr = usb_find_cfg_descr(dev,USB_ENDPOINT_DESCRIPTOR_TYPE,idx);
622 if (USB_ENDPOINT_DIR_OUT(epdscr->bEndpointAddress))
623 outdscr = epdscr;
624 else
625 indscr = epdscr;
628 if (!indscr || !outdscr)
631 * Could not get descriptors, something is very wrong.
632 * Leave device addressed but not configured.
634 xprintf("USBETH: ERROR...no endpoint descriptors\n");
635 return -1;
639 * Choose the standard configuration.
642 usb_set_configuration(dev,cfgdscr->bConfigurationValue);
644 // Quit if not able to initialize the device
645 if (usbeth_init_device(softc) < 0)
646 return -1;
649 * Open the pipes.
652 softc->bulk_inpipe = usb_open_pipe(dev,indscr);
653 softc->bulk_outpipe = usb_open_pipe(dev,outdscr);
655 //Now attach this device as a CFE Ethernet device
656 cfe_attach( (cfe_driver_t *) &usbethdrv, softc, NULL,
657 usbethdrv.drv_description );
659 ++Dev_cnt;
661 return 0;
664 /* *********************************************************************
665 * usbeth_detach(dev)
667 * This routine is called when the bus scanner notices that
668 * this device has been removed from the system. We should
669 * do any cleanup that is required. The pending requests
670 * will be cancelled automagically.
672 * Input parameters:
673 * dev - usb device
675 * Return value:
677 ********************************************************************* */
679 static int usbeth_detach(usbdev_t *dev)
681 usbeth_softc_t *softc = (usbeth_softc_t *) dev->ud_private;
683 --Dev_cnt;
684 KFREE(softc);
686 //*** SHOULD DETACH THE ETHERNET DEVICE TOO...LATER
688 return 0;
691 // CFE USB device interface structure
692 usb_driver_t usbeth_driver =
694 "Ethernet Device",
695 usbeth_attach,
696 usbeth_detach
701 /* *********************************************************************
702 * CFE-Ethernet device interfaces
703 ********************************************************************* */
706 static int usbeth_ether_open(cfe_devctx_t *ctx)
708 if( !Dev_cnt )
709 return CFE_ERR_NOTREADY;
711 USBETH_TRACE( "%s called.\n", __FUNCTION__ );
712 usbeth_open_device( (usbeth_softc_t *) ctx->dev_softc );
714 return 0;
717 static int usbeth_ether_read( cfe_devctx_t * ctx, iocb_buffer_t * buffer )
719 if( !Dev_cnt )
720 return CFE_ERR_NOTREADY;
722 buffer->buf_retlen = usbeth_get_eth_frame( (usbeth_softc_t *)ctx->dev_softc,
723 buffer->buf_ptr );
725 #ifdef DATA_DUMP
726 xprintf( "Incoming packet :\n" );
727 hexdump( buffer->buf_ptr, buffer->buf_retlen, 16,
728 buffer->buf_retlen / 16 + 1 );
729 #endif
731 return 0;
735 static int usbeth_ether_inpstat( cfe_devctx_t * ctx, iocb_inpstat_t * inpstat )
737 if( !Dev_cnt )
738 return CFE_ERR_NOTREADY;
740 inpstat->inp_status = usbeth_data_rx( (usbeth_softc_t *) ctx->dev_softc );
742 return 0;
746 static int usbeth_ether_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
748 if( !Dev_cnt )
749 return CFE_ERR_NOTREADY;
751 // Block until hw notifies you data is sent.
752 usbeth_send_eth_frame( (usbeth_softc_t *) ctx->dev_softc, buffer->buf_ptr,
753 buffer->buf_length );
755 return 0;
759 static int usbeth_ether_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
761 int retval = 0;
763 if( !Dev_cnt )
764 return CFE_ERR_NOTREADY;
766 switch( (int)buffer->buf_ioctlcmd ) {
767 case IOCTL_ETHER_GETHWADDR:
768 USBETH_TRACE( "IOCTL_ETHER_GETHWADDR called.\n" );
769 usbeth_get_dev_addr( (usbeth_softc_t *) ctx->dev_softc,
770 buffer->buf_ptr );
771 break;
772 case IOCTL_ETHER_SETHWADDR:
773 xprintf( "IOCTL_ETHER_SETHWADDR not implemented.\n" );
774 break;
775 default:
776 xprintf( "Invalid IOCTL to usbeth_ether_ioctl.\n" );
777 retval = -1;
780 return retval;
784 static int usbeth_ether_close(cfe_devctx_t *ctx)
786 if( !Dev_cnt )
787 return CFE_ERR_NOTREADY;
789 USBETH_TRACE( "%s called.\n", __FUNCTION__ );
790 usbeth_close_device( (usbeth_softc_t *) ctx->dev_softc );
792 return 0;
796 // CFE ethernet device interface structures
797 const static cfe_devdisp_t usbeth_ether_dispatch =
799 usbeth_ether_open,
800 usbeth_ether_read,
801 usbeth_ether_inpstat,
802 usbeth_ether_write,
803 usbeth_ether_ioctl,
804 usbeth_ether_close,
805 NULL,
806 NULL
809 const cfe_driver_t usbethdrv =
811 "USB-Ethernet Device",
812 "eth",
813 CFE_DEV_NETWORK,
814 &usbeth_ether_dispatch,
815 NULL, //probe...not needed