iPXE
legacy.c
Go to the documentation of this file.
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
20FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
21
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,
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 + 4 /* possible VLAN */
46 + 4 /* possible CRC */ );
47 if ( ! iobuf )
48 return;
49
50 nic->packet = iobuf->data;
51 if ( nic->nic_op->poll ( nic, 1 ) ) {
52 DBG ( "Received %d bytes\n", nic->packetlen );
53 iob_put ( iobuf, nic->packetlen );
54 netdev_rx ( netdev, iobuf );
55 } else {
56 free_iob ( iobuf );
57 }
58}
59
60static int legacy_open ( struct net_device *netdev __unused ) {
61 /* Nothing to do */
62 return 0;
63}
64
65static void legacy_close ( struct net_device *netdev __unused ) {
66 /* Nothing to do */
67}
68
69static void legacy_irq ( struct net_device *netdev __unused, int enable ) {
70 struct nic *nic = netdev->priv;
71
72 nic->nic_op->irq ( nic, ( enable ? ENABLE : DISABLE ) );
73}
74
76 .open = legacy_open,
77 .close = legacy_close,
78 .transmit = legacy_transmit,
79 .poll = legacy_poll,
80 .irq = legacy_irq,
81};
82
83int legacy_probe ( void *hwdev,
84 void ( * set_drvdata ) ( void *hwdev, void *priv ),
85 struct device *dev,
86 int ( * probe ) ( struct nic *nic, void *hwdev ),
87 void ( * disable ) ( struct nic *nic, void *hwdev ),
88 size_t fake_bss_len ) {
89 struct net_device *netdev;
90 struct nic *nic;
91 int rc;
92
93 if ( legacy_registered ) {
94 rc = -EBUSY;
95 goto err_registered;
96 }
97
98 netdev = alloc_etherdev ( 0 );
99 if ( ! netdev ) {
100 rc = -ENOMEM;
101 goto err_alloc;
102 }
104 nic = &legacy_nic;
105 netdev->priv = nic;
106 memset ( nic, 0, sizeof ( *nic ) );
107 set_drvdata ( hwdev, netdev );
108 netdev->dev = dev;
109
110 nic->node_addr = netdev->hw_addr;
111 nic->irqno = dev->desc.irq;
112
113 if ( fake_bss_len ) {
115 if ( ! nic->fake_bss ) {
116 rc = -ENOMEM;
117 goto err_fake_bss;
118 }
119 }
121
122 if ( ! probe ( nic, hwdev ) ) {
123 rc = -ENODEV;
124 goto err_probe;
125 }
126
127 /* Overwrite the IRQ number. Some legacy devices set
128 * nic->irqno to 0 in the probe routine to indicate that they
129 * don't support interrupts; doing this allows the timer
130 * interrupt to be used instead.
131 */
132 dev->desc.irq = nic->irqno;
133
134 if ( ( rc = register_netdev ( netdev ) ) != 0 )
135 goto err_register;
136
137 /* Mark as link up; legacy devices don't handle link state */
139
140 /* Do not remove this message */
141 printf ( "WARNING: Using legacy NIC wrapper on %s\n",
142 netdev->ll_protocol->ntoa ( nic->node_addr ) );
143
145 return 0;
146
147 err_register:
148 disable ( nic, hwdev );
149 err_probe:
150 if ( fake_bss_len )
152 err_fake_bss:
154 netdev_put ( netdev );
155 err_alloc:
156 err_registered:
157 return rc;
158}
159
160void legacy_remove ( void *hwdev,
161 void * ( * get_drvdata ) ( void *hwdev ),
162 void ( * disable ) ( struct nic *nic, void *hwdev ) ) {
163 struct net_device *netdev = get_drvdata ( hwdev );
164 struct nic *nic = netdev->priv;
165
167 disable ( nic, hwdev );
168 if ( nic->fake_bss_len )
171 netdev_put ( netdev );
173}
174
175int dummy_connect ( struct nic *nic __unused ) {
176 return 1;
177}
178
179void dummy_irq ( struct nic *nic __unused, irq_action_t irq_action __unused ) {
180 return;
181}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
Error codes.
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
Ethernet protocol.
static struct net_device * netdev
Definition gdbudp.c:53
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOMEM
Not enough space.
Definition errno.h:535
#define EBUSY
Device or resource busy.
Definition errno.h:339
#define ENODEV
No such device.
Definition errno.h:510
#define ETH_ZLEN
Definition if_ether.h:11
#define ETH_FRAME_LEN
Definition if_ether.h:12
#define ntohs(value)
Definition byteswap.h:137
#define PAGE_SIZE
Page size.
Definition io.h:28
void * memset(void *dest, int character, size_t len) __nonnull
void iob_pad(struct io_buffer *iobuf, size_t min_len)
Pad I/O buffer.
Definition iobpad.c:50
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
I/O buffers.
#define iob_put(iobuf, len)
Definition iobuf.h:125
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_pull(iobuf, len)
Definition iobuf.h:107
static int legacy_open(struct net_device *netdev __unused)
Definition legacy.c:60
static void legacy_irq(struct net_device *netdev __unused, int enable)
Definition legacy.c:69
static void legacy_close(struct net_device *netdev __unused)
Definition legacy.c:65
int dummy_connect(struct nic *nic __unused)
Definition legacy.c:175
struct nic legacy_nic
Definition legacy.c:22
static struct net_device_operations legacy_operations
Definition legacy.c:75
int legacy_probe(void *hwdev, void(*set_drvdata)(void *hwdev, void *priv), struct device *dev, int(*probe)(struct nic *nic, void *hwdev), void(*disable)(struct nic *nic, void *hwdev), size_t fake_bss_len)
Definition legacy.c:83
static int legacy_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Definition legacy.c:26
static void legacy_poll(struct net_device *netdev)
Definition legacy.c:41
void legacy_remove(void *hwdev, void *(*get_drvdata)(void *hwdev), void(*disable)(struct nic *nic, void *hwdev))
Definition legacy.c:160
void dummy_irq(struct nic *nic __unused, irq_action_t irq_action __unused)
Definition legacy.c:179
static int legacy_registered
Definition legacy.c:24
void * malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition malloc.c:707
void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition malloc.c:723
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
Network device management.
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition netdevice.h:767
irq_action_t
Definition nic.h:34
@ ENABLE
Definition nic.h:36
@ DISABLE
Definition nic.h:35
unsigned int irq
IRQ.
Definition device.h:40
A hardware device.
Definition device.h:77
struct device_description desc
Device description.
Definition device.h:83
An Ethernet link-layer header.
Definition if_ether.h:32
uint16_t h_protocol
Protocol ID.
Definition if_ether.h:38
uint8_t h_dest[ETH_ALEN]
Destination MAC address.
Definition if_ether.h:34
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
Network device operations.
Definition netdevice.h:214
A network device.
Definition netdevice.h:353
void(* transmit)(struct nic *, const char *, unsigned int, unsigned int, const char *)
Definition nic.h:71
void(* irq)(struct nic *, irq_action_t)
Definition nic.h:73
int(* poll)(struct nic *, int retrieve)
Definition nic.h:70
Definition nic.h:49
void * fake_bss
Definition nic.h:60
unsigned char * packet
Definition nic.h:53
unsigned char * node_addr
Definition nic.h:52
unsigned int packetlen
Definition nic.h:54
unsigned char irqno
Definition nic.h:56
size_t fake_bss_len
Definition nic.h:61
struct nic_operations * nic_op
Definition nic.h:50
static struct tlan_private * priv
Definition tlan.c:225
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition vsprintf.c:465