legacy.c
Go to the documentation of this file.00001 #include <stdint.h>
00002 #include <stdio.h>
00003 #include <errno.h>
00004 #include <gpxe/if_ether.h>
00005 #include <gpxe/netdevice.h>
00006 #include <gpxe/ethernet.h>
00007 #include <gpxe/iobuf.h>
00008 #include <nic.h>
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 FILE_LICENCE ( GPL2_OR_LATER );
00021
00022 struct nic nic;
00023
00024 static int legacy_registered = 0;
00025
00026 static int legacy_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
00027 struct nic *nic = netdev->priv;
00028 struct ethhdr *ethhdr;
00029
00030 DBG ( "Transmitting %zd bytes\n", iob_len ( iobuf ) );
00031 iob_pad ( iobuf, ETH_ZLEN );
00032 ethhdr = iobuf->data;
00033 iob_pull ( iobuf, sizeof ( *ethhdr ) );
00034 nic->nic_op->transmit ( nic, ( const char * ) ethhdr->h_dest,
00035 ntohs ( ethhdr->h_protocol ),
00036 iob_len ( iobuf ), iobuf->data );
00037 netdev_tx_complete ( netdev, iobuf );
00038 return 0;
00039 }
00040
00041 static void legacy_poll ( struct net_device *netdev ) {
00042 struct nic *nic = netdev->priv;
00043 struct io_buffer *iobuf;
00044
00045 iobuf = alloc_iob ( ETH_FRAME_LEN );
00046 if ( ! iobuf )
00047 return;
00048
00049 nic->packet = iobuf->data;
00050 if ( nic->nic_op->poll ( nic, 1 ) ) {
00051 DBG ( "Received %d bytes\n", nic->packetlen );
00052 iob_put ( iobuf, nic->packetlen );
00053 netdev_rx ( netdev, iobuf );
00054 } else {
00055 free_iob ( iobuf );
00056 }
00057 }
00058
00059 static int legacy_open ( struct net_device *netdev __unused ) {
00060
00061 return 0;
00062 }
00063
00064 static void legacy_close ( struct net_device *netdev __unused ) {
00065
00066 }
00067
00068 static void legacy_irq ( struct net_device *netdev __unused, int enable ) {
00069 struct nic *nic = netdev->priv;
00070
00071 nic->nic_op->irq ( nic, ( enable ? ENABLE : DISABLE ) );
00072 }
00073
00074 static struct net_device_operations legacy_operations = {
00075 .open = legacy_open,
00076 .close = legacy_close,
00077 .transmit = legacy_transmit,
00078 .poll = legacy_poll,
00079 .irq = legacy_irq,
00080 };
00081
00082 int legacy_probe ( void *hwdev,
00083 void ( * set_drvdata ) ( void *hwdev, void *priv ),
00084 struct device *dev,
00085 int ( * probe ) ( struct nic *nic, void *hwdev ),
00086 void ( * disable ) ( struct nic *nic, void *hwdev ) ) {
00087 struct net_device *netdev;
00088 int rc;
00089
00090 if ( legacy_registered )
00091 return -EBUSY;
00092
00093 netdev = alloc_etherdev ( 0 );
00094 if ( ! netdev )
00095 return -ENOMEM;
00096 netdev_init ( netdev, &legacy_operations );
00097 netdev->priv = &nic;
00098 memset ( &nic, 0, sizeof ( nic ) );
00099 set_drvdata ( hwdev, netdev );
00100 netdev->dev = dev;
00101
00102 nic.node_addr = netdev->hw_addr;
00103 nic.irqno = dev->desc.irq;
00104
00105 if ( ! probe ( &nic, hwdev ) ) {
00106 rc = -ENODEV;
00107 goto err_probe;
00108 }
00109
00110
00111
00112
00113
00114
00115 dev->desc.irq = nic.irqno;
00116
00117
00118 netdev_link_up ( netdev );
00119
00120 if ( ( rc = register_netdev ( netdev ) ) != 0 )
00121 goto err_register;
00122
00123
00124 printf ( "WARNING: Using legacy NIC wrapper on %s\n",
00125 netdev->ll_protocol->ntoa ( nic.node_addr ) );
00126
00127 legacy_registered = 1;
00128 return 0;
00129
00130 err_register:
00131 disable ( &nic, hwdev );
00132 err_probe:
00133 netdev_nullify ( netdev );
00134 netdev_put ( netdev );
00135 return rc;
00136 }
00137
00138 void legacy_remove ( void *hwdev,
00139 void * ( * get_drvdata ) ( void *hwdev ),
00140 void ( * disable ) ( struct nic *nic, void *hwdev ) ) {
00141 struct net_device *netdev = get_drvdata ( hwdev );
00142 struct nic *nic = netdev->priv;
00143
00144 unregister_netdev ( netdev );
00145 disable ( nic, hwdev );
00146 netdev_nullify ( netdev );
00147 netdev_put ( netdev );
00148 legacy_registered = 0;
00149 }
00150
00151 int dummy_connect ( struct nic *nic __unused ) {
00152 return 1;
00153 }
00154
00155 void dummy_irq ( struct nic *nic __unused, irq_action_t irq_action __unused ) {
00156 return;
00157 }