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 
20 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
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 
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;
97  netdev->priv = &nic;
98  memset ( &nic, 0, sizeof ( nic ) );
99  set_drvdata ( hwdev, netdev );
100  netdev->dev = dev;
101 
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 */
122 
123  /* Do not remove this message */
124  printf ( "WARNING: Using legacy NIC wrapper on %s\n",
126 
127  legacy_registered = 1;
128  return 0;
129 
130  err_register:
131  disable ( &nic, hwdev );
132  err_probe:
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 
145  disable ( nic, hwdev );
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 }
unsigned char irqno
Definition: nic.h:56
uint16_t h_protocol
Protocol ID.
Definition: if_ether.h:37
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
Definition: nic.h:35
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int(* poll)(struct nic *, int retrieve)
Definition: nic.h:64
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition: netdevice.h:752
#define iob_put(iobuf, len)
Definition: iobuf.h:120
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
#define EBUSY
Device or resource busy.
Definition: errno.h:338
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:222
Error codes.
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static int legacy_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Definition: legacy.c:26
#define ntohs(value)
Definition: byteswap.h:136
void(* irq)(struct nic *, irq_action_t)
Definition: nic.h:67
void(* transmit)(struct nic *, const char *, unsigned int, unsigned int, const char *)
Definition: nic.h:65
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
int dummy_connect(struct nic *nic __unused)
Definition: legacy.c:151
static struct net_device_operations legacy_operations
Definition: legacy.c:74
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:515
uint8_t h_dest[ETH_ALEN]
Destination MAC address.
Definition: if_ether.h:33
#define ENOMEM
Not enough space.
Definition: errno.h:534
A hardware device.
Definition: device.h:73
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
Ethernet protocol.
unsigned int irq
IRQ.
Definition: device.h:39
#define ETH_FRAME_LEN
Definition: if_ether.h:11
void * priv
Driver private data.
Definition: netdevice.h:431
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition: netdevice.h:774
static struct net_device * netdev
Definition: gdbudp.c:52
irq_action_t
Definition: nic.h:34
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
void dummy_irq(struct nic *nic __unused, irq_action_t irq_action __unused)
Definition: legacy.c:155
unsigned int packetlen
Definition: nic.h:54
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:759
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
A network device.
Definition: netdevice.h:352
#define ENODEV
No such device.
Definition: errno.h:509
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:528
#define ETH_ZLEN
Definition: if_ether.h:10
Definition: nic.h:49
void legacy_remove(void *hwdev, void *(*get_drvdata)(void *hwdev), void(*disable)(struct nic *nic, void *hwdev))
Definition: legacy.c:138
Network device operations.
Definition: netdevice.h:213
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:548
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
Network device management.
Definition: nic.h:36
unsigned char * packet
Definition: nic.h:53
unsigned char * node_addr
Definition: nic.h:52
static struct tlan_private * priv
Definition: tlan.c:224
void * data
Start of data.
Definition: iobuf.h:48
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:264
struct device_description desc
Device description.
Definition: device.h:79
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static void legacy_close(struct net_device *netdev __unused)
Definition: legacy.c:64
struct nic_operations * nic_op
Definition: nic.h:50
static void legacy_irq(struct net_device *netdev __unused, int enable)
Definition: legacy.c:68
static void legacy_poll(struct net_device *netdev)
Definition: legacy.c:41
struct nic nic
Definition: legacy.c:22
An Ethernet link-layer header.
Definition: if_ether.h:31
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:381
static int legacy_registered
Definition: legacy.c:24
void iob_pad(struct io_buffer *iobuf, size_t min_len)
Pad I/O buffer.
Definition: iobpad.c:49
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
void * memset(void *dest, int character, size_t len) __nonnull
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))
Definition: legacy.c:82
A persistent I/O buffer.
Definition: iobuf.h:33
static int legacy_open(struct net_device *netdev __unused)
Definition: legacy.c:59