pnic.c File Reference

#include <stdint.h>
#include <stdio.h>
#include <gpxe/io.h>
#include <errno.h>
#include <gpxe/pci.h>
#include <gpxe/if_ether.h>
#include <gpxe/ethernet.h>
#include <gpxe/iobuf.h>
#include <gpxe/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, const struct pci_device_id *id __unused)

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 ( 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]

Definition at line 45 of file pnic.c.

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

Referenced by pnic_command(), and pnic_probe().

00048                                                                {
00049         uint16_t status;
00050         uint16_t _output_length;
00051 
00052         if ( input != NULL ) {
00053                 /* Write input length */
00054                 outw ( input_length, pnic->ioaddr + PNIC_REG_LEN );
00055                 /* Write input data */
00056                 outsb ( pnic->ioaddr + PNIC_REG_DATA, input, input_length );
00057         }
00058         /* Write command */
00059         outw ( command, pnic->ioaddr + PNIC_REG_CMD );
00060         /* Retrieve status */
00061         status = inw ( pnic->ioaddr + PNIC_REG_STAT );
00062         /* Retrieve output length */
00063         _output_length = inw ( pnic->ioaddr + PNIC_REG_LEN );
00064         if ( output_length == NULL ) {
00065                 if ( _output_length != output_max_length ) {
00066                         printf ( "pnic_command %#hx: wrong data length "
00067                                  "returned (expected %d, got %d)\n", command,
00068                                  output_max_length, _output_length );
00069                 }
00070         } else {
00071                 *output_length = _output_length;
00072         }
00073         if ( output != NULL ) {
00074                 if ( _output_length > output_max_length ) {
00075                         printf ( "pnic_command %#hx: output buffer too small "
00076                                  "(have %d, need %d)\n", command,
00077                                  output_max_length, _output_length );
00078                         _output_length = output_max_length;
00079                 }
00080                 /* Retrieve output data */
00081                 insb ( pnic->ioaddr + PNIC_REG_DATA, output, _output_length );
00082         }
00083         return status;
00084 }

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]

Definition at line 86 of file pnic.c.

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

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

00089                                                          {
00090         uint16_t status = pnic_command_quiet ( pnic, command,
00091                                                input, input_length,
00092                                                output, output_max_length,
00093                                                output_length );
00094         if ( status == PNIC_STATUS_OK ) return status;
00095         printf ( "PNIC command %#hx (len %#hx) failed with status %#hx\n",
00096                  command, input_length, status );
00097         return status;
00098 }

static int pnic_api_check ( uint16_t  api_version  )  [static]

Definition at line 101 of file pnic.c.

References PNIC_API_VERSION, and printf().

Referenced by pnic_probe().

00101                                                    {
00102         if ( api_version != PNIC_API_VERSION ) {
00103                 printf ( "Warning: API version mismatch! "
00104                          "(NIC's is %d.%d, ours is %d.%d)\n",
00105                          api_version >> 8, api_version & 0xff,
00106                          PNIC_API_VERSION >> 8, PNIC_API_VERSION & 0xff );
00107         }
00108         if ( api_version < PNIC_API_VERSION ) {
00109                 printf ( "** You may need to update your copy of Bochs **\n" );
00110         }
00111         return ( api_version == PNIC_API_VERSION );
00112 }

static void pnic_poll ( struct net_device netdev  )  [static]

Definition at line 117 of file pnic.c.

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

00117                                                     {
00118         struct pnic *pnic = netdev->priv;
00119         struct io_buffer *iobuf;
00120         uint16_t length;
00121         uint16_t qlen;
00122 
00123         /* Fetch all available packets */
00124         while ( 1 ) {
00125                 if ( pnic_command ( pnic, PNIC_CMD_RECV_QLEN, NULL, 0,
00126                                     &qlen, sizeof ( qlen ), NULL )
00127                      != PNIC_STATUS_OK )
00128                         return;
00129                 if ( qlen == 0 )
00130                         return;
00131                 iobuf = alloc_iob ( ETH_FRAME_LEN );
00132                 if ( ! iobuf ) {
00133                         DBG ( "could not allocate buffer\n" );
00134                         netdev_rx_err ( netdev, NULL, -ENOMEM );
00135                         return;
00136                 }
00137                 if ( pnic_command ( pnic, PNIC_CMD_RECV, NULL, 0,
00138                                     iobuf->data, ETH_FRAME_LEN, &length )
00139                      != PNIC_STATUS_OK ) {
00140                         netdev_rx_err ( netdev, iobuf, -EIO );
00141                         return;
00142                 }
00143                 iob_put ( iobuf, length );
00144                 netdev_rx ( netdev, iobuf );
00145         }
00146 }

static int pnic_transmit ( struct net_device netdev,
struct io_buffer iobuf 
) [static]

Definition at line 151 of file pnic.c.

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

00151                                                                                 {
00152         struct pnic *pnic = netdev->priv;
00153 
00154         /* Pad the packet */
00155         iob_pad ( iobuf, ETH_ZLEN );
00156 
00157         /* Send packet */
00158         pnic_command ( pnic, PNIC_CMD_XMIT, iobuf->data, iob_len ( iobuf ),
00159                        NULL, 0, NULL );
00160 
00161         netdev_tx_complete ( netdev, iobuf );
00162         return 0;
00163 }

static int pnic_open ( struct net_device *netdev  __unused  )  [static]

Definition at line 168 of file pnic.c.

00168                                                             {
00169         /* Nothing to do */
00170         return 0;
00171 }

static void pnic_close ( struct net_device *netdev  __unused  )  [static]

Definition at line 176 of file pnic.c.

00176                                                               {
00177         /* Nothing to do */
00178 }

static void pnic_irq ( struct net_device netdev,
int  enable 
) [static]

Definition at line 183 of file pnic.c.

References NULL, PNIC_CMD_MASK_IRQ, pnic_command(), and net_device::priv.

00183                                                                {
00184         struct pnic *pnic = netdev->priv;
00185         uint8_t mask = ( enable ? 1 : 0 );
00186         
00187         pnic_command ( pnic, PNIC_CMD_MASK_IRQ, &mask, sizeof ( mask ),
00188                        NULL, 0, NULL );
00189 }

static void pnic_remove ( struct pci_device pci  )  [static]

Definition at line 205 of file pnic.c.

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

00205                                                    {
00206         struct net_device *netdev = pci_get_drvdata ( pci );
00207         struct pnic *pnic = netdev->priv;
00208 
00209         unregister_netdev ( netdev );
00210         pnic_command ( pnic, PNIC_CMD_RESET, NULL, 0, NULL, 0, NULL );
00211         netdev_nullify ( netdev );
00212         netdev_put ( netdev );
00213 }

static int pnic_probe ( struct pci_device pci,
const struct pci_device_id *id  __unused 
) [static]

Definition at line 218 of file pnic.c.

References adjust_pci_device(), alloc_etherdev(), pci_device::dev, net_device::dev, EIO, ENOMEM, ETH_ALEN, net_device::hw_addr, 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_STATUS_OK, printf(), net_device::priv, and register_netdev().

00219                                                                   {
00220         struct net_device *netdev;
00221         struct pnic *pnic;
00222         uint16_t api_version;
00223         uint16_t status;
00224         int rc;
00225 
00226         /* Allocate net device */
00227         netdev = alloc_etherdev ( sizeof ( *pnic ) );
00228         if ( ! netdev )
00229                 return -ENOMEM;
00230         netdev_init ( netdev, &pnic_operations );
00231         pnic = netdev->priv;
00232         pci_set_drvdata ( pci, netdev );
00233         netdev->dev = &pci->dev;
00234         pnic->ioaddr = pci->ioaddr;
00235 
00236         /* Fix up PCI device */
00237         adjust_pci_device ( pci );
00238         
00239         /* API version check */
00240         status = pnic_command_quiet ( pnic, PNIC_CMD_API_VER, NULL, 0,
00241                                       &api_version,
00242                                       sizeof ( api_version ), NULL );
00243         if ( status != PNIC_STATUS_OK ) {
00244                 printf ( "PNIC failed installation check, code %#hx\n",
00245                          status );
00246                 rc = -EIO;
00247                 goto err;
00248         }
00249         pnic_api_check ( api_version );
00250 
00251         /* Get MAC address */
00252         status = pnic_command ( pnic, PNIC_CMD_READ_MAC, NULL, 0,
00253                                 netdev->hw_addr, ETH_ALEN, NULL );
00254 
00255         /* Mark as link up; PNIC has no concept of link state */
00256         netdev_link_up ( netdev );
00257 
00258         /* Register network device */
00259         if ( ( rc = register_netdev ( netdev ) ) != 0 )
00260                 goto err;
00261 
00262         return 0;
00263 
00264  err:
00265         /* Free net device */
00266         netdev_nullify ( netdev );
00267         netdev_put ( netdev );
00268         return rc;
00269 }


Variable Documentation

Initial value:

 {
        .open           = pnic_open,
        .close          = pnic_close,
        .transmit       = pnic_transmit,
        .poll           = pnic_poll,
        .irq            = pnic_irq,
}

Definition at line 194 of file pnic.c.

struct pci_device_id pnic_nics[] [static]

Initial value:

 {

PCI_ROM ( 0xfefe, 0xefef, "pnic", "Bochs Pseudo NIC Adaptor", 0 ),
}

Definition at line 271 of file pnic.c.

struct pci_driver pnic_driver __pci_driver

Initial value:

 {
        .ids = pnic_nics,
        .id_count = ( sizeof ( pnic_nics ) / sizeof ( pnic_nics[0] ) ),
        .probe = pnic_probe,
        .remove = pnic_remove,
}

Definition at line 276 of file pnic.c.


Generated on Tue Apr 6 20:01:37 2010 for gPXE by  doxygen 1.5.7.1