Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / legacy.c
1 #include <stdint.h>
2 #include <stdio.h>
3 #include <errno.h>
4 #include <ipxe/if_ether.h>
5 #include <ipxe/netdevice.h>
6 #include <ipxe/ethernet.h>
7 #include <ipxe/iobuf.h>
8 #include <nic.h>
9
10 /*
11  * Quick and dirty compatibility layer
12  *
13  * This should allow old-API PCI drivers to at least function until
14  * they are updated.  It will not help non-PCI drivers.
15  *
16  * No drivers should rely on this code.  It will be removed asap.
17  *
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 struct nic nic;
23
24 static int legacy_registered = 0;
25
26 static int legacy_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
27         struct nic *nic = netdev->priv;
28         struct ethhdr *ethhdr;
29
30         DBG ( "Transmitting %zd bytes\n", iob_len ( iobuf ) );
31         iob_pad ( iobuf, ETH_ZLEN );
32         ethhdr = iobuf->data;
33         iob_pull ( iobuf, sizeof ( *ethhdr ) );
34         nic->nic_op->transmit ( nic, ( const char * ) ethhdr->h_dest,
35                                 ntohs ( ethhdr->h_protocol ),
36                                 iob_len ( iobuf ), iobuf->data );
37         netdev_tx_complete ( netdev, iobuf );
38         return 0;
39 }
40
41 static void legacy_poll ( struct net_device *netdev ) {
42         struct nic *nic = netdev->priv;
43         struct io_buffer *iobuf;
44
45         iobuf = alloc_iob ( ETH_FRAME_LEN );
46         if ( ! iobuf )
47                 return;
48
49         nic->packet = iobuf->data;
50         if ( nic->nic_op->poll ( nic, 1 ) ) {
51                 DBG ( "Received %d bytes\n", nic->packetlen );
52                 iob_put ( iobuf, nic->packetlen );
53                 netdev_rx ( netdev, iobuf );
54         } else {
55                 free_iob ( iobuf );
56         }
57 }
58
59 static int legacy_open ( struct net_device *netdev __unused ) {
60         /* Nothing to do */
61         return 0;
62 }
63
64 static void legacy_close ( struct net_device *netdev __unused ) {
65         /* Nothing to do */
66 }
67
68 static void legacy_irq ( struct net_device *netdev __unused, int enable ) {
69         struct nic *nic = netdev->priv;
70
71         nic->nic_op->irq ( nic, ( enable ? ENABLE : DISABLE ) );
72 }
73
74 static struct net_device_operations legacy_operations = {
75         .open           = legacy_open,
76         .close          = legacy_close,
77         .transmit       = legacy_transmit,
78         .poll           = legacy_poll,
79         .irq            = legacy_irq,
80 };
81
82 int legacy_probe ( void *hwdev,
83                    void ( * set_drvdata ) ( void *hwdev, void *priv ),
84                    struct device *dev,
85                    int ( * probe ) ( struct nic *nic, void *hwdev ),
86                    void ( * disable ) ( struct nic *nic, void *hwdev ) ) {
87         struct net_device *netdev;
88         int rc;
89
90         if ( legacy_registered )
91                 return -EBUSY;
92         
93         netdev = alloc_etherdev ( 0 );
94         if ( ! netdev )
95                 return -ENOMEM;
96         netdev_init ( netdev, &legacy_operations );
97         netdev->priv = &nic;
98         memset ( &nic, 0, sizeof ( nic ) );
99         set_drvdata ( hwdev, netdev );
100         netdev->dev = dev;
101
102         nic.node_addr = netdev->hw_addr;
103         nic.irqno = dev->desc.irq;
104
105         if ( ! probe ( &nic, hwdev ) ) {
106                 rc = -ENODEV;
107                 goto err_probe;
108         }
109
110         /* Overwrite the IRQ number.  Some legacy devices set
111          * nic->irqno to 0 in the probe routine to indicate that they
112          * don't support interrupts; doing this allows the timer
113          * interrupt to be used instead.
114          */
115         dev->desc.irq = nic.irqno;
116
117         if ( ( rc = register_netdev ( netdev ) ) != 0 )
118                 goto err_register;
119
120         /* Mark as link up; legacy devices don't handle link state */
121         netdev_link_up ( netdev );
122
123         /* Do not remove this message */
124         printf ( "WARNING: Using legacy NIC wrapper on %s\n",
125                  netdev->ll_protocol->ntoa ( nic.node_addr ) );
126
127         legacy_registered = 1;
128         return 0;
129
130  err_register:
131         disable ( &nic, hwdev );
132  err_probe:
133         netdev_nullify ( netdev );
134         netdev_put ( netdev );
135         return rc;
136 }
137
138 void legacy_remove ( void *hwdev,
139                      void * ( * get_drvdata ) ( void *hwdev ),
140                      void ( * disable ) ( struct nic *nic, void *hwdev ) ) {
141         struct net_device *netdev = get_drvdata ( hwdev );
142         struct nic *nic = netdev->priv;
143
144         unregister_netdev ( netdev );
145         disable ( nic, hwdev );
146         netdev_nullify ( netdev );
147         netdev_put ( netdev );
148         legacy_registered = 0;
149 }
150
151 int dummy_connect ( struct nic *nic __unused ) {
152         return 1;
153 }
154
155 void dummy_irq ( struct nic *nic __unused, irq_action_t irq_action __unused ) {
156         return;
157 }