#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 |
| 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] |
| static void pnic_close | ( | struct net_device *netdev | __unused | ) | [static] |
| 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 }
struct net_device_operations pnic_operations [static] |
Initial value:
{
.open = pnic_open,
.close = pnic_close,
.transmit = pnic_transmit,
.poll = pnic_poll,
.irq = pnic_irq,
}
struct pci_device_id pnic_nics[] [static] |
| 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,
}
1.5.7.1