iPXE
pnic.c File Reference
#include <stdint.h>
#include <stdio.h>
#include <ipxe/io.h>
#include <errno.h>
#include <ipxe/pci.h>
#include <ipxe/if_ether.h>
#include <ipxe/ethernet.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include "pnic_api.h"

Go to the source code of this file.

Data Structures

struct  pnic

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static uint16_t pnic_command_quiet (struct pnic *pnic, uint16_t command, const void *input, uint16_t input_length, void *output, uint16_t output_max_length, uint16_t *output_length)
static uint16_t pnic_command (struct pnic *pnic, uint16_t command, const void *input, uint16_t input_length, void *output, uint16_t output_max_length, uint16_t *output_length)
static int pnic_api_check (uint16_t api_version)
static void pnic_poll (struct net_device *netdev)
static int pnic_transmit (struct net_device *netdev, struct io_buffer *iobuf)
static int pnic_open (struct net_device *netdev __unused)
static void pnic_close (struct net_device *netdev __unused)
static void pnic_irq (struct net_device *netdev, int enable)
static void pnic_remove (struct pci_device *pci)
static int pnic_probe (struct pci_device *pci)

Variables

static struct net_device_operations pnic_operations
static struct pci_device_id pnic_nics []
struct pci_driver pnic_driver __pci_driver

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER )

◆ pnic_command_quiet()

uint16_t pnic_command_quiet ( struct pnic * pnic,
uint16_t command,
const void * input,
uint16_t input_length,
void * output,
uint16_t output_max_length,
uint16_t * output_length )
static

Definition at line 55 of file pnic.c.

58 {
60 uint16_t _output_length;
61
62 if ( input != NULL ) {
63 /* Write input length */
64 outw ( input_length, pnic->ioaddr + PNIC_REG_LEN );
65 /* Write input data */
66 outsb ( pnic->ioaddr + PNIC_REG_DATA, input, input_length );
67 }
68 /* Write command */
70 /* Retrieve status */
72 /* Retrieve output length */
73 _output_length = inw ( pnic->ioaddr + PNIC_REG_LEN );
74 if ( output_length == NULL ) {
75 if ( _output_length != output_max_length ) {
76 printf ( "pnic_command %#hx: wrong data length "
77 "returned (expected %d, got %d)\n", command,
78 output_max_length, _output_length );
79 }
80 } else {
81 *output_length = _output_length;
82 }
83 if ( output != NULL ) {
84 if ( _output_length > output_max_length ) {
85 printf ( "pnic_command %#hx: output buffer too small "
86 "(have %d, need %d)\n", command,
87 output_max_length, _output_length );
88 _output_length = output_max_length;
89 }
90 /* Retrieve output data */
91 insb ( pnic->ioaddr + PNIC_REG_DATA, output, _output_length );
92 }
93 return status;
94}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
unsigned short uint16_t
Definition stdint.h:11
uint8_t status
Status.
Definition ena.h:5
#define inw(io_addr)
Definition io.h:292
#define outw(data, io_addr)
Definition io.h:320
#define insb(io_addr, data, count)
Definition io.h:401
#define outsb(io_addr, data, count)
Definition io.h:435
#define PNIC_REG_CMD
Definition pnic_api.h:26
#define PNIC_REG_DATA
Definition pnic_api.h:29
#define PNIC_REG_STAT
Definition pnic_api.h:27
#define PNIC_REG_LEN
Definition pnic_api.h:28
A command-line command.
Definition command.h:10
Definition pnic.c:39
unsigned short ioaddr
Definition pnic.c:40
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition vsprintf.c:465

References insb, inw, pnic::ioaddr, NULL, outsb, outw, PNIC_REG_CMD, PNIC_REG_DATA, PNIC_REG_LEN, PNIC_REG_STAT, printf(), and status.

Referenced by pnic_command(), and pnic_probe().

◆ pnic_command()

uint16_t pnic_command ( struct pnic * pnic,
uint16_t command,
const void * input,
uint16_t input_length,
void * output,
uint16_t output_max_length,
uint16_t * output_length )
static

Definition at line 96 of file pnic.c.

99 {
101 input, input_length,
102 output, output_max_length,
103 output_length );
104 if ( status == PNIC_STATUS_OK ) return status;
105 printf ( "PNIC command %#hx (len %#hx) failed with status %#hx\n",
106 command, input_length, status );
107 return status;
108}
static uint16_t pnic_command_quiet(struct pnic *pnic, uint16_t command, const void *input, uint16_t input_length, void *output, uint16_t output_max_length, uint16_t *output_length)
Definition pnic.c:55
#define PNIC_STATUS_OK
Definition pnic_api.h:54

References pnic_command_quiet(), PNIC_STATUS_OK, printf(), and status.

Referenced by pnic_irq(), pnic_poll(), pnic_probe(), pnic_remove(), and pnic_transmit().

◆ pnic_api_check()

int pnic_api_check ( uint16_t api_version)
static

Definition at line 111 of file pnic.c.

111 {
112 if ( api_version != PNIC_API_VERSION ) {
113 printf ( "Warning: API version mismatch! "
114 "(NIC's is %d.%d, ours is %d.%d)\n",
115 api_version >> 8, api_version & 0xff,
116 PNIC_API_VERSION >> 8, PNIC_API_VERSION & 0xff );
117 }
118 if ( api_version < PNIC_API_VERSION ) {
119 printf ( "** You may need to update your copy of Bochs **\n" );
120 }
121 return ( api_version == PNIC_API_VERSION );
122}
#define PNIC_API_VERSION
Definition pnic_api.h:61

References PNIC_API_VERSION, and printf().

Referenced by pnic_probe().

◆ pnic_poll()

void pnic_poll ( struct net_device * netdev)
static

Definition at line 127 of file pnic.c.

127 {
128 struct pnic *pnic = netdev->priv;
129 struct io_buffer *iobuf;
131 uint16_t qlen;
132
133 /* Fetch all available packets */
134 while ( 1 ) {
136 &qlen, sizeof ( qlen ), NULL )
137 != PNIC_STATUS_OK )
138 return;
139 if ( qlen == 0 )
140 return;
141 iobuf = alloc_iob ( ETH_FRAME_LEN );
142 if ( ! iobuf ) {
143 DBG ( "could not allocate buffer\n" );
145 return;
146 }
148 iobuf->data, ETH_FRAME_LEN, &length )
149 != PNIC_STATUS_OK ) {
150 netdev_rx_err ( netdev, iobuf, -EIO );
151 return;
152 }
153 iob_put ( iobuf, length );
154 netdev_rx ( netdev, iobuf );
155 }
156}
static struct net_device * netdev
Definition gdbudp.c:53
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define ENOMEM
Not enough space.
Definition errno.h:535
#define EIO
Input/output error.
Definition errno.h:434
#define ETH_FRAME_LEN
Definition if_ether.h:12
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:125
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
static uint16_t pnic_command(struct pnic *pnic, uint16_t command, const void *input, uint16_t input_length, void *output, uint16_t output_max_length, uint16_t *output_length)
Definition pnic.c:96
#define PNIC_CMD_RECV_QLEN
Definition pnic_api.h:44
#define PNIC_CMD_RECV
Definition pnic_api.h:43
u16 length
Definition sky2.h:1
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53

References alloc_iob(), io_buffer::data, DBG, EIO, ENOMEM, ETH_FRAME_LEN, iob_put, length, netdev, netdev_rx(), netdev_rx_err(), NULL, PNIC_CMD_RECV, PNIC_CMD_RECV_QLEN, pnic_command(), and PNIC_STATUS_OK.

◆ pnic_transmit()

int pnic_transmit ( struct net_device * netdev,
struct io_buffer * iobuf )
static

Definition at line 161 of file pnic.c.

161 {
162 struct pnic *pnic = netdev->priv;
163
164 /* Pad the packet */
165 iob_pad ( iobuf, ETH_ZLEN );
166
167 /* Send packet */
168 pnic_command ( pnic, PNIC_CMD_XMIT, iobuf->data, iob_len ( iobuf ),
169 NULL, 0, NULL );
170
171 netdev_tx_complete ( netdev, iobuf );
172 return 0;
173}
#define ETH_ZLEN
Definition if_ether.h:11
void iob_pad(struct io_buffer *iobuf, size_t min_len)
Pad I/O buffer.
Definition iobpad.c:50
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition netdevice.h:767
#define PNIC_CMD_XMIT
Definition pnic_api.h:42

References io_buffer::data, ETH_ZLEN, iob_len(), iob_pad(), netdev, netdev_tx_complete(), NULL, PNIC_CMD_XMIT, and pnic_command().

◆ pnic_open()

int pnic_open ( struct net_device *netdev __unused)
static

Definition at line 178 of file pnic.c.

178 {
179 /* Nothing to do */
180 return 0;
181}

References __unused, and netdev.

◆ pnic_close()

void pnic_close ( struct net_device *netdev __unused)
static

Definition at line 186 of file pnic.c.

186 {
187 /* Nothing to do */
188}

References __unused, and netdev.

◆ pnic_irq()

void pnic_irq ( struct net_device * netdev,
int enable )
static

Definition at line 193 of file pnic.c.

193 {
194 struct pnic *pnic = netdev->priv;
195 uint8_t mask = ( enable ? 1 : 0 );
196
197 pnic_command ( pnic, PNIC_CMD_MASK_IRQ, &mask, sizeof ( mask ),
198 NULL, 0, NULL );
199}
unsigned char uint8_t
Definition stdint.h:10
#define PNIC_CMD_MASK_IRQ
Definition pnic_api.h:45

References netdev, NULL, PNIC_CMD_MASK_IRQ, and pnic_command().

◆ pnic_remove()

void pnic_remove ( struct pci_device * pci)
static

Definition at line 215 of file pnic.c.

215 {
216 struct net_device *netdev = pci_get_drvdata ( pci );
217 struct pnic *pnic = netdev->priv;
218
222 netdev_put ( netdev );
223}
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
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 * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition pci.h:376
#define PNIC_CMD_RESET
Definition pnic_api.h:41
A network device.
Definition netdevice.h:353

References netdev, netdev_nullify(), netdev_put(), NULL, pci_get_drvdata(), PNIC_CMD_RESET, pnic_command(), and unregister_netdev().

◆ pnic_probe()

int pnic_probe ( struct pci_device * pci)
static

Definition at line 228 of file pnic.c.

228 {
229 struct net_device *netdev;
230 struct pnic *pnic;
231 uint16_t api_version;
233 int rc;
234
235 /* Allocate net device */
236 netdev = alloc_etherdev ( sizeof ( *pnic ) );
237 if ( ! netdev )
238 return -ENOMEM;
240 pnic = netdev->priv;
241 pci_set_drvdata ( pci, netdev );
242 netdev->dev = &pci->dev;
243 pnic->ioaddr = pci->ioaddr;
244
245 /* Fix up PCI device */
246 adjust_pci_device ( pci );
247
248 /* API version check */
250 &api_version,
251 sizeof ( api_version ), NULL );
252 if ( status != PNIC_STATUS_OK ) {
253 printf ( "PNIC failed installation check, code %#hx\n",
254 status );
255 rc = -EIO;
256 goto err;
257 }
258 pnic_api_check ( api_version );
259
260 /* Get MAC address */
262 netdev->hw_addr, ETH_ALEN, NULL );
263
264 /* Register network device */
265 if ( ( rc = register_netdev ( netdev ) ) != 0 )
266 goto err;
267
268 /* Mark as link up; PNIC has no concept of link state */
270
271 return 0;
272
273 err:
274 /* Free net device */
276 netdev_put ( netdev );
277 return rc;
278}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
#define ETH_ALEN
Definition if_ether.h:9
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
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
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition pci.c:241
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition pci.h:366
static struct net_device_operations pnic_operations
Definition pnic.c:204
static int pnic_api_check(uint16_t api_version)
Definition pnic.c:111
#define PNIC_CMD_API_VER
Definition pnic_api.h:39
#define PNIC_CMD_READ_MAC
Definition pnic_api.h:40
unsigned long ioaddr
I/O address.
Definition pci.h:226
struct device dev
Generic device.
Definition pci.h:213

References adjust_pci_device(), alloc_etherdev(), pci_device::dev, EIO, ENOMEM, ETH_ALEN, pci_device::ioaddr, pnic::ioaddr, netdev, netdev_init(), netdev_link_up(), netdev_nullify(), netdev_put(), NULL, pci_set_drvdata(), pnic_api_check(), PNIC_CMD_API_VER, PNIC_CMD_READ_MAC, pnic_command(), pnic_command_quiet(), pnic_operations, PNIC_STATUS_OK, printf(), rc, register_netdev(), and status.

Variable Documentation

◆ pnic_operations

struct net_device_operations pnic_operations
static
Initial value:
= {
.open = pnic_open,
.close = pnic_close,
.transmit = pnic_transmit,
.poll = pnic_poll,
.irq = pnic_irq,
}
static int pnic_open(struct net_device *netdev __unused)
Definition pnic.c:178
static void pnic_irq(struct net_device *netdev, int enable)
Definition pnic.c:193
static void pnic_poll(struct net_device *netdev)
Definition pnic.c:127
static int pnic_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Definition pnic.c:161
static void pnic_close(struct net_device *netdev __unused)
Definition pnic.c:186

Definition at line 204 of file pnic.c.

204 {
205 .open = pnic_open,
206 .close = pnic_close,
207 .transmit = pnic_transmit,
208 .poll = pnic_poll,
209 .irq = pnic_irq,
210};

Referenced by pnic_probe().

◆ pnic_nics

struct pci_device_id pnic_nics[]
static
Initial value:
= {
PCI_ROM ( 0xfefe, 0xefef, "pnic", "Bochs Pseudo NIC Adaptor", 0 ),
}
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition pci.h:308

Definition at line 280 of file pnic.c.

280 {
281/* genrules.pl doesn't let us use macros for PCI IDs...*/
282PCI_ROM ( 0xfefe, 0xefef, "pnic", "Bochs Pseudo NIC Adaptor", 0 ),
283};

◆ __pci_driver

struct pci_driver pnic_driver __pci_driver
Initial value:
= {
.ids = pnic_nics,
.id_count = ( sizeof ( pnic_nics ) / sizeof ( pnic_nics[0] ) ),
.probe = pnic_probe,
}
static int pnic_probe(struct pci_device *pci)
Definition pnic.c:228
static struct pci_device_id pnic_nics[]
Definition pnic.c:280
static void pnic_remove(struct pci_device *pci)
Definition pnic.c:215
static struct xen_remove_from_physmap * remove
Definition xenmem.h:40

Definition at line 285 of file pnic.c.

285 {
286 .ids = pnic_nics,
287 .id_count = ( sizeof ( pnic_nics ) / sizeof ( pnic_nics[0] ) ),
288 .probe = pnic_probe,
290};