source: bootcd/isolinux/syslinux-6.03/gpxe/src/drivers/net/legacy.c @ e16e8f2

Last change on this file since e16e8f2 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 3.7 KB
Line 
1#include <stdint.h>
2#include <stdio.h>
3#include <errno.h>
4#include <gpxe/if_ether.h>
5#include <gpxe/netdevice.h>
6#include <gpxe/ethernet.h>
7#include <gpxe/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
20FILE_LICENCE ( GPL2_OR_LATER );
21
22struct nic nic;
23
24static int legacy_registered = 0;
25
26static 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
41static 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
59static int legacy_open ( struct net_device *netdev __unused ) {
60        /* Nothing to do */
61        return 0;
62}
63
64static void legacy_close ( struct net_device *netdev __unused ) {
65        /* Nothing to do */
66}
67
68static 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
74static 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
82int 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        /* Mark as link up; legacy devices don't handle link state */
118        netdev_link_up ( netdev );
119
120        if ( ( rc = register_netdev ( netdev ) ) != 0 )
121                goto err_register;
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
138void 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
151int dummy_connect ( struct nic *nic __unused ) {
152        return 1;
153}
154
155void dummy_irq ( struct nic *nic __unused, irq_action_t irq_action __unused ) {
156        return;
157}
Note: See TracBrowser for help on using the repository browser.