|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.