1b36c0def7e9749bc82d7a2547885fbaa9091aaa
[people/xl0/gpxe.git] / src / drivers / net / legacy.c
1 #include <stdint.h>
2 #include <errno.h>
3 #include <gpxe/if_ether.h>
4 #include <gpxe/netdevice.h>
5 #include <gpxe/ethernet.h>
6 #include <gpxe/pkbuff.h>
7 #include <nic.h>
8
9 /*
10  * Quick and dirty compatibility layer
11  *
12  * This should allow old-API PCI drivers to at least function until
13  * they are updated.  It will not help non-PCI drivers.
14  *
15  * No drivers should rely on this code.  It will be removed asap.
16  *
17  */
18
19 struct nic nic;
20
21 static int legacy_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
22         struct nic *nic = netdev->priv;
23         struct ethhdr *ethhdr = pkb->data;
24
25         pkb_pull ( pkb, sizeof ( *ethhdr ) );
26         nic->nic_op->transmit ( nic, ( const char * ) ethhdr->h_dest,
27                                 ntohs ( ethhdr->h_protocol ),
28                                 pkb_len ( pkb ), pkb->data );
29         free_pkb ( pkb );
30         return 0;
31 }
32
33 static void legacy_poll ( struct net_device *netdev ) {
34         struct nic *nic = netdev->priv;
35         struct pk_buff *pkb;
36
37         pkb = alloc_pkb ( ETH_FRAME_LEN );
38         if ( ! pkb )
39                 return;
40
41         nic->packet = pkb->data;
42         if ( nic->nic_op->poll ( nic, 1 ) ) {
43                 pkb_put ( pkb, nic->packetlen );
44                 netdev_rx ( netdev, pkb );
45         } else {
46                 free_pkb ( pkb );
47         }
48 }
49
50 int legacy_probe ( struct pci_device *pci,
51                    const struct pci_device_id *id __unused,
52                    int ( * probe ) ( struct nic *nic,
53                                      struct pci_device *pci ),
54                    void ( * disable ) ( struct nic *nic ) ) {
55         struct net_device *netdev;
56         int rc;
57         
58         netdev = alloc_etherdev ( 0 );
59         if ( ! netdev )
60                 return -ENOMEM;
61         netdev->priv = &nic;
62         memset ( &nic, 0, sizeof ( nic ) );
63         pci_set_drvdata ( pci, netdev );
64
65         netdev->transmit = legacy_transmit;
66         netdev->poll = legacy_poll;
67         nic.node_addr = netdev->ll_addr;
68
69         if ( ! probe ( &nic, pci ) ) {
70                 free_netdev ( netdev );
71                 return -ENODEV;
72         }
73
74         if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
75                 disable ( &nic );
76                 free_netdev ( netdev );
77                 return rc;
78         }
79
80         return 0;
81 }
82
83 void legacy_remove ( struct pci_device *pci,
84                      void ( * disable ) ( struct nic *nic ) ) {
85         struct net_device *netdev = pci_get_drvdata ( pci );
86         struct nic *nic = netdev->priv;
87
88         unregister_netdev ( netdev );
89         disable ( nic );
90         free_netdev ( netdev );
91 }
92
93 void pci_fill_nic ( struct nic *nic, struct pci_device *pci ) {
94         nic->ioaddr = pci->ioaddr;
95         nic->irqno = pci->irq;
96 }
97
98 int dummy_connect ( struct nic *nic __unused ) {
99         return 1;
100 }
101
102 void dummy_irq ( struct nic *nic __unused, irq_action_t irq_action __unused ) {
103         return;
104 }