iPXE
Functions | Variables
icplus.c File Reference

IC+ network driver. More...

#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/if_ether.h>
#include <ipxe/iobuf.h>
#include <ipxe/malloc.h>
#include <ipxe/pci.h>
#include "icplus.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int icplus_reset (struct icplus_nic *icp)
 Reset hardware. More...
 
static int icplus_read_eeprom (struct nvs_device *nvs, unsigned int address, void *data, size_t len)
 Read data from EEPROM. More...
 
static int icplus_write_eeprom (struct nvs_device *nvs, unsigned int address __unused, const void *data __unused, size_t len __unused)
 Write data to EEPROM. More...
 
static void icplus_init_eeprom (struct icplus_nic *icp)
 Initialise EEPROM. More...
 
static int icplus_mii_read_bit (struct bit_basher *basher, unsigned int bit_id)
 Read input bit. More...
 
static void icplus_mii_write_bit (struct bit_basher *basher, unsigned int bit_id, unsigned long data)
 Set/clear output bit. More...
 
static int icplus_init_phy (struct icplus_nic *icp)
 Configure PHY. More...
 
static void icplus_check_link (struct net_device *netdev)
 Check link state. More...
 
static void icplus_set_base (struct icplus_nic *icp, unsigned int offset, void *base)
 Set descriptor ring base address. More...
 
static int icplus_create_ring (struct icplus_nic *icp, struct icplus_ring *ring)
 Create descriptor ring. More...
 
static void icplus_destroy_ring (struct icplus_nic *icp __unused, struct icplus_ring *ring)
 Destroy descriptor ring. More...
 
void icplus_refill_rx (struct icplus_nic *icp)
 Refill receive descriptor ring. More...
 
static int icplus_open (struct net_device *netdev)
 Open network device. More...
 
static void icplus_close (struct net_device *netdev)
 Close network device. More...
 
static int icplus_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet. More...
 
static void icplus_poll_tx (struct net_device *netdev)
 Poll for completed packets. More...
 
static void icplus_poll_rx (struct net_device *netdev)
 Poll for received packets. More...
 
static void icplus_poll (struct net_device *netdev)
 Poll for completed and received packets. More...
 
static void icplus_irq (struct net_device *netdev, int enable)
 Enable or disable interrupts. More...
 
static int icplus_probe (struct pci_device *pci)
 Probe PCI device. More...
 
static void icplus_remove (struct pci_device *pci)
 Remove PCI device. More...
 

Variables

static const uint8_t icplus_mii_bits []
 Pin mapping for MII bit-bashing interface. More...
 
static struct bit_basher_operations icplus_basher_ops
 MII bit-bashing interface. More...
 
static struct net_device_operations icplus_operations
 IC+ network device operations. More...
 
static struct pci_device_id icplus_nics []
 IC+ PCI device IDs. More...
 
struct pci_driver icplus_driver __pci_driver
 IC+ PCI driver. More...
 

Detailed Description

IC+ network driver.

Definition in file icplus.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ icplus_reset()

static int icplus_reset ( struct icplus_nic icp)
static

Reset hardware.

Parameters
icpIC+ device
Return values
rcReturn status code

Definition at line 58 of file icplus.c.

58  {
59  uint32_t asicctrl;
60  unsigned int i;
61 
62  /* Trigger reset */
65  ICP_ASICCTRL_AUTOINIT ), ( icp->regs + ICP_ASICCTRL ) );
66 
67  /* Wait for reset to complete */
68  for ( i = 0 ; i < ICP_RESET_MAX_WAIT_MS ; i++ ) {
69 
70  /* Check if device is ready */
71  asicctrl = readl ( icp->regs + ICP_ASICCTRL );
72  if ( ! ( asicctrl & ICP_ASICCTRL_RESETBUSY ) )
73  return 0;
74 
75  /* Delay */
76  mdelay ( 1 );
77  }
78 
79  DBGC ( icp, "ICPLUS %p timed out waiting for reset (asicctrl %#08x)\n",
80  icp, asicctrl );
81  return -ETIMEDOUT;
82 }
#define ICP_ASICCTRL_AUTOINIT
Auto init.
Definition: icplus.h:35
#define ICP_ASICCTRL_FIFO
FIFO.
Definition: icplus.h:32
#define ICP_RESET_MAX_WAIT_MS
Maximum time to wait for reset.
Definition: icplus.h:39
uint32_t readl(volatile uint32_t *io_addr)
Read 32-bit dword from memory-mapped device.
#define DBGC(...)
Definition: compiler.h:505
#define ICP_ASICCTRL_NETWORK
Network.
Definition: icplus.h:33
#define ICP_ASICCTRL_HOST
Host.
Definition: icplus.h:34
void writel(uint32_t data, volatile uint32_t *io_addr)
Write 32-bit dword to memory-mapped device.
#define ICP_ASICCTRL
ASIC control register (double word)
Definition: icplus.h:28
#define ICP_ASICCTRL_GLOBALRESET
Global reset.
Definition: icplus.h:30
unsigned int uint32_t
Definition: stdint.h:12
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
#define ICP_ASICCTRL_RESETBUSY
Reset busy.
Definition: icplus.h:36
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
#define ICP_ASICCTRL_DMA
DMA.
Definition: icplus.h:31
void * regs
Registers.
Definition: icplus.h:191

References DBGC, ETIMEDOUT, ICP_ASICCTRL, ICP_ASICCTRL_AUTOINIT, ICP_ASICCTRL_DMA, ICP_ASICCTRL_FIFO, ICP_ASICCTRL_GLOBALRESET, ICP_ASICCTRL_HOST, ICP_ASICCTRL_NETWORK, ICP_ASICCTRL_RESETBUSY, ICP_RESET_MAX_WAIT_MS, mdelay(), readl(), icplus_nic::regs, and writel().

Referenced by icplus_close(), icplus_open(), icplus_probe(), and icplus_remove().

◆ icplus_read_eeprom()

static int icplus_read_eeprom ( struct nvs_device nvs,
unsigned int  address,
void *  data,
size_t  len 
)
static

Read data from EEPROM.

Parameters
nvsNVS device
addressAddress from which to read
dataData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 100 of file icplus.c.

101  {
102  struct icplus_nic *icp =
103  container_of ( nvs, struct icplus_nic, eeprom );
104  unsigned int i;
105  uint16_t eepromctrl;
106  uint16_t *data_word = data;
107 
108  /* Sanity check. We advertise a blocksize of one word, so
109  * should only ever receive single-word requests.
110  */
111  assert ( len == sizeof ( *data_word ) );
112 
113  /* Initiate read */
116  ( icp->regs + ICP_EEPROMCTRL ) );
117 
118  /* Wait for read to complete */
119  for ( i = 0 ; i < ICP_EEPROM_MAX_WAIT_MS ; i++ ) {
120 
121  /* If read is not complete, delay 1ms and retry */
122  eepromctrl = readw ( icp->regs + ICP_EEPROMCTRL );
123  if ( eepromctrl & ICP_EEPROMCTRL_BUSY ) {
124  mdelay ( 1 );
125  continue;
126  }
127 
128  /* Extract data */
129  *data_word = cpu_to_le16 ( readw ( icp->regs + ICP_EEPROMDATA ));
130  return 0;
131  }
132 
133  DBGC ( icp, "ICPLUS %p timed out waiting for EEPROM read\n", icp );
134  return -ETIMEDOUT;
135 }
unsigned short uint16_t
Definition: stdint.h:11
#define ICP_EEPROM_MAX_WAIT_MS
Maximum time to wait for reading EEPROM.
Definition: icplus.h:55
#define ICP_EEPROMCTRL_OPCODE_READ
Read register.
Definition: icplus.h:50
uint16_t readw(volatile uint16_t *io_addr)
Read 16-bit word from memory-mapped device.
uint64_t address
Base address.
Definition: ena.h:24
#define DBGC(...)
Definition: compiler.h:505
eeprom
Definition: 3c90x.h:232
#define ICP_EEPROMCTRL_BUSY
EEPROM busy.
Definition: icplus.h:52
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define ICP_EEPROMCTRL
EEPROM control register (word)
Definition: icplus.h:47
#define ICP_EEPROMDATA
EEPROM data register (word)
Definition: icplus.h:67
#define ICP_EEPROMCTRL_ADDRESS(x)
Address.
Definition: icplus.h:48
An IC+ network card.
Definition: icplus.h:189
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
uint32_t len
Length.
Definition: ena.h:14
#define writew
Definition: w89c840.c:159
#define cpu_to_le16(value)
Definition: byteswap.h:106
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
void * regs
Registers.
Definition: icplus.h:191

References address, assert(), container_of, cpu_to_le16, data, DBGC, ETIMEDOUT, ICP_EEPROM_MAX_WAIT_MS, ICP_EEPROMCTRL, ICP_EEPROMCTRL_ADDRESS, ICP_EEPROMCTRL_BUSY, ICP_EEPROMCTRL_OPCODE_READ, ICP_EEPROMDATA, len, mdelay(), readw(), icplus_nic::regs, and writew.

Referenced by icplus_init_eeprom().

◆ icplus_write_eeprom()

static int icplus_write_eeprom ( struct nvs_device nvs,
unsigned int address  __unused,
const void *data  __unused,
size_t len  __unused 
)
static

Write data to EEPROM.

Parameters
nvsNVS device
addressAddress to which to write
dataData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 146 of file icplus.c.

149  {
150  struct icplus_nic *icp =
151  container_of ( nvs, struct icplus_nic, eeprom );
152 
153  DBGC ( icp, "ICPLUS %p EEPROM write not supported\n", icp );
154  return -ENOTSUP;
155 }
#define DBGC(...)
Definition: compiler.h:505
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
eeprom
Definition: 3c90x.h:232
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An IC+ network card.
Definition: icplus.h:189

References container_of, DBGC, and ENOTSUP.

Referenced by icplus_init_eeprom().

◆ icplus_init_eeprom()

static void icplus_init_eeprom ( struct icplus_nic icp)
static

Initialise EEPROM.

Parameters
icpIC+ device

Definition at line 162 of file icplus.c.

162  {
163 
164  /* The hardware supports only single-word reads */
167  icp->eeprom.block_size = 1;
170 }
#define ICP_EEPROM_WORD_LEN_LOG2
EEPROM word length.
Definition: icplus.h:58
int(* write)(struct nvs_device *nvs, unsigned int address, const void *data, size_t len)
Write data to device.
Definition: nvs.h:59
unsigned int word_len_log2
Word length.
Definition: nvs.h:22
struct nvs_device eeprom
EEPROM.
Definition: icplus.h:193
static int icplus_write_eeprom(struct nvs_device *nvs, unsigned int address __unused, const void *data __unused, size_t len __unused)
Write data to EEPROM.
Definition: icplus.c:146
unsigned int block_size
Data block size (in words)
Definition: nvs.h:36
static int icplus_read_eeprom(struct nvs_device *nvs, unsigned int address, void *data, size_t len)
Read data from EEPROM.
Definition: icplus.c:100
#define ICP_EEPROM_MIN_SIZE_WORDS
Minimum EEPROM size, in words.
Definition: icplus.h:61
int(* read)(struct nvs_device *nvs, unsigned int address, void *data, size_t len)
Read data from device.
Definition: nvs.h:47
unsigned int size
Device size (in words)
Definition: nvs.h:24

References nvs_device::block_size, icplus_nic::eeprom, ICP_EEPROM_MIN_SIZE_WORDS, ICP_EEPROM_WORD_LEN_LOG2, icplus_read_eeprom(), icplus_write_eeprom(), nvs_device::read, nvs_device::size, nvs_device::word_len_log2, and nvs_device::write.

Referenced by icplus_probe().

◆ icplus_mii_read_bit()

static int icplus_mii_read_bit ( struct bit_basher basher,
unsigned int  bit_id 
)
static

Read input bit.

Parameters
basherBit-bashing interface
bit_idBit number
Return values
zeroInput is a logic 0
non-zeroInput is a logic 1

Definition at line 194 of file icplus.c.

195  {
196  struct icplus_nic *icp = container_of ( basher, struct icplus_nic,
197  miibit.basher );
198  uint8_t mask = icplus_mii_bits[bit_id];
199  uint8_t reg;
200 
202  reg = readb ( icp->regs + ICP_PHYCTRL );
203  DBG_ENABLE ( DBGLVL_IO );
204  return ( reg & mask );
205 }
uint8_t readb(volatile uint8_t *io_addr)
Read byte from memory-mapped device.
#define DBGLVL_IO
Definition: compiler.h:322
static unsigned int unsigned int reg
Definition: myson.h:162
#define DBG_ENABLE(level)
Definition: compiler.h:313
static const uint8_t icplus_mii_bits[]
Pin mapping for MII bit-bashing interface.
Definition: icplus.c:180
#define DBG_DISABLE(level)
Definition: compiler.h:312
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
unsigned char uint8_t
Definition: stdint.h:10
An IC+ network card.
Definition: icplus.h:189
struct mii_bit_basher miibit
MII bit bashing interface.
Definition: icplus.h:195
struct bit_basher basher
Bit-bashing interface.
Definition: mii_bit.h:37
#define ICP_PHYCTRL
PHY control register (byte)
Definition: icplus.h:84
void * regs
Registers.
Definition: icplus.h:191

References mii_bit_basher::basher, container_of, DBG_DISABLE, DBG_ENABLE, DBGLVL_IO, ICP_PHYCTRL, icplus_mii_bits, icplus_nic::miibit, readb(), reg, and icplus_nic::regs.

◆ icplus_mii_write_bit()

static void icplus_mii_write_bit ( struct bit_basher basher,
unsigned int  bit_id,
unsigned long  data 
)
static

Set/clear output bit.

Parameters
basherBit-bashing interface
bit_idBit number
dataValue to write

Definition at line 214 of file icplus.c.

215  {
216  struct icplus_nic *icp = container_of ( basher, struct icplus_nic,
217  miibit.basher );
218  uint8_t mask = icplus_mii_bits[bit_id];
219  uint8_t reg;
220 
222  reg = readb ( icp->regs + ICP_PHYCTRL );
223  reg &= ~mask;
224  reg |= ( data & mask );
225  writeb ( reg, icp->regs + ICP_PHYCTRL );
226  readb ( icp->regs + ICP_PHYCTRL ); /* Ensure write reaches chip */
227  DBG_ENABLE ( DBGLVL_IO );
228 }
uint8_t readb(volatile uint8_t *io_addr)
Read byte from memory-mapped device.
#define DBGLVL_IO
Definition: compiler.h:322
static unsigned int unsigned int reg
Definition: myson.h:162
#define DBG_ENABLE(level)
Definition: compiler.h:313
static const uint8_t icplus_mii_bits[]
Pin mapping for MII bit-bashing interface.
Definition: icplus.c:180
#define DBG_DISABLE(level)
Definition: compiler.h:312
void writeb(uint8_t data, volatile uint8_t *io_addr)
Write byte to memory-mapped device.
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
unsigned char uint8_t
Definition: stdint.h:10
An IC+ network card.
Definition: icplus.h:189
struct mii_bit_basher miibit
MII bit bashing interface.
Definition: icplus.h:195
struct bit_basher basher
Bit-bashing interface.
Definition: mii_bit.h:37
#define ICP_PHYCTRL
PHY control register (byte)
Definition: icplus.h:84
uint8_t data[48]
Additional event data.
Definition: ena.h:22
void * regs
Registers.
Definition: icplus.h:191

References mii_bit_basher::basher, container_of, data, DBG_DISABLE, DBG_ENABLE, DBGLVL_IO, ICP_PHYCTRL, icplus_mii_bits, icplus_nic::miibit, readb(), reg, icplus_nic::regs, and writeb().

◆ icplus_init_phy()

static int icplus_init_phy ( struct icplus_nic icp)
static

Configure PHY.

Parameters
icpIC+ device
Return values
rcReturn status code

Definition at line 249 of file icplus.c.

249  {
250  uint32_t asicctrl;
251  int rc;
252 
253  /* Find PHY address */
254  if ( ( rc = mii_find ( &icp->mii ) ) != 0 ) {
255  DBGC ( icp, "ICPLUS %p could not find PHY address: %s\n",
256  icp, strerror ( rc ) );
257  return rc;
258  }
259 
260  /* Configure PHY to advertise 1000Mbps if applicable */
261  asicctrl = readl ( icp->regs + ICP_ASICCTRL );
262  if ( asicctrl & ICP_ASICCTRL_PHYSPEED1000 ) {
263  if ( ( rc = mii_write ( &icp->mii, MII_CTRL1000,
264  ADVERTISE_1000FULL ) ) != 0 ) {
265  DBGC ( icp, "ICPLUS %p could not advertise 1000Mbps: "
266  "%s\n", icp, strerror ( rc ) );
267  return rc;
268  }
269  }
270 
271  /* Reset PHY */
272  if ( ( rc = mii_reset ( &icp->mii ) ) != 0 ) {
273  DBGC ( icp, "ICPLUS %p could not reset PHY: %s\n",
274  icp, strerror ( rc ) );
275  return rc;
276  }
277 
278  return 0;
279 }
#define ICP_ASICCTRL_PHYSPEED1000
PHY speed 1000.
Definition: icplus.h:29
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ADVERTISE_1000FULL
Definition: mii.h:133
uint32_t readl(volatile uint32_t *io_addr)
Read 32-bit dword from memory-mapped device.
#define DBGC(...)
Definition: compiler.h:505
#define MII_CTRL1000
Definition: mii.h:24
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define ICP_ASICCTRL
ASIC control register (double word)
Definition: icplus.h:28
int mii_reset(struct mii_device *mii)
Reset MII device.
Definition: mii.c:74
unsigned int uint32_t
Definition: stdint.h:12
int mii_find(struct mii_device *mii)
Find PHY address.
Definition: mii.c:157
struct mii_device mii
MII device.
Definition: icplus.h:197
static int mii_write(struct mii_device *mii, unsigned int reg, unsigned int data)
Write to MII register.
Definition: mii.h:104
void * regs
Registers.
Definition: icplus.h:191

References ADVERTISE_1000FULL, DBGC, ICP_ASICCTRL, ICP_ASICCTRL_PHYSPEED1000, icplus_nic::mii, MII_CTRL1000, mii_find(), mii_reset(), mii_write(), rc, readl(), icplus_nic::regs, and strerror().

Referenced by icplus_probe().

◆ icplus_check_link()

static void icplus_check_link ( struct net_device netdev)
static

Check link state.

Parameters
netdevNetwork device

Definition at line 286 of file icplus.c.

286  {
287  struct icplus_nic *icp = netdev->priv;
288  uint8_t phyctrl;
289 
290  /* Read link status */
291  phyctrl = readb ( icp->regs + ICP_PHYCTRL );
292  DBGC ( icp, "ICPLUS %p PHY control is %02x\n", icp, phyctrl );
293 
294  /* Update network device */
295  if ( phyctrl & ICP_PHYCTRL_LINKSPEED ) {
297  } else {
299  }
300 }
uint8_t readb(volatile uint8_t *io_addr)
Read byte from memory-mapped device.
#define DBGC(...)
Definition: compiler.h:505
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition: netdevice.c:230
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
unsigned char uint8_t
Definition: stdint.h:10
An IC+ network card.
Definition: icplus.h:189
#define ICP_PHYCTRL
PHY control register (byte)
Definition: icplus.h:84
#define ICP_PHYCTRL_LINKSPEED
Link speed.
Definition: icplus.h:88
void * regs
Registers.
Definition: icplus.h:191

References DBGC, ICP_PHYCTRL, ICP_PHYCTRL_LINKSPEED, netdev, netdev_link_down(), netdev_link_up(), net_device::priv, readb(), and icplus_nic::regs.

Referenced by icplus_open(), icplus_poll(), and icplus_probe().

◆ icplus_set_base()

static void icplus_set_base ( struct icplus_nic icp,
unsigned int  offset,
void *  base 
)
inlinestatic

Set descriptor ring base address.

Parameters
icpIC+ device
offsetRegister offset
addressBase address

Definition at line 316 of file icplus.c.

317  {
319 
320  /* Program base address registers */
321  writel ( ( phys & 0xffffffffUL ),
322  ( icp->regs + offset + ICP_BASE_LO ) );
323  if ( sizeof ( phys ) > sizeof ( uint32_t ) ) {
324  writel ( ( ( ( uint64_t ) phys ) >> 32 ),
325  ( icp->regs + offset + ICP_BASE_HI ) );
326  } else {
327  writel ( 0, ( icp->regs + offset + ICP_BASE_HI ) );
328  }
329 }
unsigned long long uint64_t
Definition: stdint.h:13
static const void * base
Base address.
Definition: crypto.h:335
static signed char phys[4]
Definition: epic100.c:88
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
#define ICP_BASE_HI
Base address high register offset.
Definition: icplus.h:25
#define ICP_BASE_LO
Base address low register offset.
Definition: icplus.h:22
void writel(uint32_t data, volatile uint32_t *io_addr)
Write 32-bit dword to memory-mapped device.
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
unsigned int uint32_t
Definition: stdint.h:12
unsigned long physaddr_t
Definition: stdint.h:20
void * regs
Registers.
Definition: icplus.h:191

References base, ICP_BASE_HI, ICP_BASE_LO, offset, phys, icplus_nic::regs, virt_to_bus(), and writel().

Referenced by icplus_open().

◆ icplus_create_ring()

static int icplus_create_ring ( struct icplus_nic icp,
struct icplus_ring ring 
)
static

Create descriptor ring.

Parameters
icpIC+ device
ringDescriptor ring
Return values
rcReturn status code

Definition at line 338 of file icplus.c.

338  {
339  size_t len = ( sizeof ( ring->entry[0] ) * ICP_NUM_DESC );
340  int rc;
341  unsigned int i;
342  struct icplus_descriptor *desc;
343  struct icplus_descriptor *next;
344 
345  /* Allocate descriptor ring */
346  ring->entry = malloc_phys ( len, ICP_ALIGN );
347  if ( ! ring->entry ) {
348  rc = -ENOMEM;
349  goto err_alloc;
350  }
351 
352  /* Initialise descriptor ring */
353  memset ( ring->entry, 0, len );
354  for ( i = 0 ; i < ICP_NUM_DESC ; i++ ) {
355  desc = &ring->entry[i];
356  next = &ring->entry[ ( i + 1 ) % ICP_NUM_DESC ];
357  desc->next = cpu_to_le64 ( virt_to_bus ( next ) );
358  desc->flags = ( ICP_TX_UNALIGN | ICP_TX_INDICATE );
359  desc->control = ( ICP_TX_SOLE_FRAG | ICP_DONE );
360  }
361 
362  /* Reset transmit producer & consumer counters */
363  ring->prod = 0;
364  ring->cons = 0;
365 
366  DBGC ( icp, "ICP %p %s ring at [%#08lx,%#08lx)\n",
367  icp, ( ( ring->listptr == ICP_TFDLISTPTR ) ? "TX" : "RX" ),
368  virt_to_bus ( ring->entry ),
369  ( virt_to_bus ( ring->entry ) + len ) );
370  return 0;
371 
372  free_phys ( ring->entry, len );
373  ring->entry = NULL;
374  err_alloc:
375  return rc;
376 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ICP_TX_UNALIGN
Transmit alignment disabled.
Definition: icplus.h:144
#define ICP_TFDLISTPTR
List pointer transmit register.
Definition: icplus.h:101
uint32_t next
Next descriptor address.
Definition: myson.h:18
unsigned int prod
Producer counter.
Definition: icplus.h:173
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define DBGC(...)
Definition: compiler.h:505
static void *__malloc malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition: malloc.h:62
#define cpu_to_le64(value)
Definition: byteswap.h:108
struct icplus_descriptor * entry
Ring entries.
Definition: icplus.h:177
#define ICP_TX_INDICATE
Request transmit completion.
Definition: icplus.h:147
#define ENOMEM
Not enough space.
Definition: errno.h:534
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
#define ICP_TX_SOLE_FRAG
Sole transmit fragment.
Definition: icplus.h:150
unsigned int cons
Consumer counter.
Definition: icplus.h:175
Transmit or receive descriptor.
Definition: icplus.h:121
unsigned int listptr
Definition: icplus.h:179
#define ICP_NUM_DESC
Number of descriptors.
Definition: icplus.h:183
uint32_t len
Length.
Definition: ena.h:14
#define ICP_ALIGN
Alignment requirement.
Definition: icplus.h:19
static void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition: malloc.h:77
#define ICP_DONE
Descriptor complete.
Definition: icplus.h:141
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
void * memset(void *dest, int character, size_t len) __nonnull

References icplus_ring::cons, cpu_to_le64, DBGC, desc, ENOMEM, icplus_ring::entry, free_phys(), ICP_ALIGN, ICP_DONE, ICP_NUM_DESC, ICP_TFDLISTPTR, ICP_TX_INDICATE, ICP_TX_SOLE_FRAG, ICP_TX_UNALIGN, len, icplus_ring::listptr, malloc_phys(), memset(), next, NULL, icplus_ring::prod, rc, and virt_to_bus().

Referenced by icplus_open().

◆ icplus_destroy_ring()

static void icplus_destroy_ring ( struct icplus_nic *icp  __unused,
struct icplus_ring ring 
)
static

Destroy descriptor ring.

Parameters
icpIC+ device
ringDescriptor ring

Definition at line 384 of file icplus.c.

385  {
386  size_t len = ( sizeof ( ring->entry[0] ) * ICP_NUM_DESC );
387 
388  /* Free descriptor ring */
389  free_phys ( ring->entry, len );
390  ring->entry = NULL;
391 }
struct icplus_descriptor * entry
Ring entries.
Definition: icplus.h:177
#define ICP_NUM_DESC
Number of descriptors.
Definition: icplus.h:183
uint32_t len
Length.
Definition: ena.h:14
static void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition: malloc.h:77
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References icplus_ring::entry, free_phys(), ICP_NUM_DESC, len, and NULL.

Referenced by icplus_close(), and icplus_open().

◆ icplus_refill_rx()

void icplus_refill_rx ( struct icplus_nic icp)

Refill receive descriptor ring.

Parameters
icpIC+ device

Definition at line 398 of file icplus.c.

398  {
399  struct icplus_descriptor *desc;
400  struct io_buffer *iobuf;
401  unsigned int rx_idx;
403  unsigned int refilled = 0;
404 
405  /* Refill ring */
406  while ( ( icp->rx.prod - icp->rx.cons ) < ICP_NUM_DESC ) {
407 
408  /* Allocate I/O buffer */
409  iobuf = alloc_iob ( ICP_RX_MAX_LEN );
410  if ( ! iobuf ) {
411  /* Wait for next refill */
412  break;
413  }
414 
415  /* Get next receive descriptor */
416  rx_idx = ( icp->rx.prod++ % ICP_NUM_DESC );
417  desc = &icp->rx.entry[rx_idx];
418 
419  /* Populate receive descriptor */
420  address = virt_to_bus ( iobuf->data );
421  desc->data.address = cpu_to_le64 ( address );
422  desc->data.len = cpu_to_le16 ( ICP_RX_MAX_LEN );
423  wmb();
424  desc->control = 0;
425 
426  /* Record I/O buffer */
427  assert ( icp->rx_iobuf[rx_idx] == NULL );
428  icp->rx_iobuf[rx_idx] = iobuf;
429 
430  DBGC2 ( icp, "ICP %p RX %d is [%llx,%llx)\n", icp, rx_idx,
431  ( ( unsigned long long ) address ),
432  ( ( unsigned long long ) address + ICP_RX_MAX_LEN ) );
433  refilled++;
434  }
435 
436  /* Push descriptors to card, if applicable */
437  if ( refilled ) {
438  wmb();
440  }
441 }
wmb()
unsigned int prod
Producer counter.
Definition: icplus.h:173
#define ICP_RX_MAX_LEN
Maximum receive packet length.
Definition: icplus.h:186
uint64_t address
Base address.
Definition: ena.h:24
#define ICP_DMACTRL
DMA control register (word/double word)
Definition: icplus.h:42
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define cpu_to_le64(value)
Definition: byteswap.h:108
struct icplus_descriptor * entry
Ring entries.
Definition: icplus.h:177
#define ICP_DMACTRL_RXPOLLNOW
Receive poll now.
Definition: icplus.h:43
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int cons
Consumer counter.
Definition: icplus.h:175
Transmit or receive descriptor.
Definition: icplus.h:121
unsigned long physaddr_t
Definition: stdint.h:20
#define ICP_NUM_DESC
Number of descriptors.
Definition: icplus.h:183
#define DBGC2(...)
Definition: compiler.h:522
struct io_buffer * rx_iobuf[ICP_NUM_DESC]
Receive I/O buffers.
Definition: icplus.h:203
#define writew
Definition: w89c840.c:159
void * data
Start of data.
Definition: iobuf.h:48
#define cpu_to_le16(value)
Definition: byteswap.h:106
struct icplus_ring rx
Receive descriptor ring.
Definition: icplus.h:201
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
A persistent I/O buffer.
Definition: iobuf.h:33
void * regs
Registers.
Definition: icplus.h:191

References address, alloc_iob(), assert(), icplus_ring::cons, cpu_to_le16, cpu_to_le64, io_buffer::data, DBGC2, desc, icplus_ring::entry, ICP_DMACTRL, ICP_DMACTRL_RXPOLLNOW, ICP_NUM_DESC, ICP_RX_MAX_LEN, NULL, icplus_ring::prod, icplus_nic::regs, icplus_nic::rx, icplus_nic::rx_iobuf, virt_to_bus(), wmb(), and writew.

Referenced by icplus_open(), and icplus_poll().

◆ icplus_open()

static int icplus_open ( struct net_device netdev)
static

Open network device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 449 of file icplus.c.

449  {
450  struct icplus_nic *icp = netdev->priv;
451  int rc;
452 
453  /* Create transmit descriptor ring */
454  if ( ( rc = icplus_create_ring ( icp, &icp->tx ) ) != 0 )
455  goto err_create_tx;
456 
457  /* Create receive descriptor ring */
458  if ( ( rc = icplus_create_ring ( icp, &icp->rx ) ) != 0 )
459  goto err_create_rx;
460 
461  /* Program descriptor base address */
462  icplus_set_base ( icp, icp->tx.listptr, icp->tx.entry );
463  icplus_set_base ( icp, icp->rx.listptr, icp->rx.entry );
464 
465  /* Enable receive mode */
468  icp->regs + ICP_RXMODE );
469 
470  /* Enable transmitter and receiver */
472  ICP_MACCTRL_DUPLEX ), icp->regs + ICP_MACCTRL );
473 
474  /* Fill receive ring */
475  icplus_refill_rx ( icp );
476 
477  /* Check link state */
479 
480  return 0;
481 
482  icplus_reset ( icp );
483  icplus_destroy_ring ( icp, &icp->rx );
484  err_create_rx:
485  icplus_destroy_ring ( icp, &icp->tx );
486  err_create_tx:
487  return rc;
488 }
#define ICP_MACCTRL
MAC control register (double word)
Definition: icplus.h:76
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void icplus_check_link(struct net_device *netdev)
Check link state.
Definition: icplus.c:286
static int icplus_reset(struct icplus_nic *icp)
Reset hardware.
Definition: icplus.c:58
static void icplus_destroy_ring(struct icplus_nic *icp __unused, struct icplus_ring *ring)
Destroy descriptor ring.
Definition: icplus.c:384
struct icplus_ring tx
Transmit descriptor ring.
Definition: icplus.h:199
#define ICP_RXMODE_ALLFRAMES
Receive all frames.
Definition: icplus.h:95
static void icplus_set_base(struct icplus_nic *icp, unsigned int offset, void *base)
Set descriptor ring base address.
Definition: icplus.c:316
#define ICP_RXMODE_MULTICAST
Receice multicast.
Definition: icplus.h:93
#define ICP_MACCTRL_TXENABLE
TX enable.
Definition: icplus.h:78
struct icplus_descriptor * entry
Ring entries.
Definition: icplus.h:177
#define ICP_RXMODE
Receive mode register (word)
Definition: icplus.h:91
#define ICP_MACCTRL_RXENABLE
RX enable.
Definition: icplus.h:80
#define ICP_RXMODE_UNICAST
Receive unicast.
Definition: icplus.h:92
#define ICP_MACCTRL_DUPLEX
Duplex select.
Definition: icplus.h:77
void * priv
Driver private data.
Definition: netdevice.h:431
void writel(uint32_t data, volatile uint32_t *io_addr)
Write 32-bit dword to memory-mapped device.
static struct net_device * netdev
Definition: gdbudp.c:52
#define ICP_RXMODE_BROADCAST
Receive broadcast.
Definition: icplus.h:94
void icplus_refill_rx(struct icplus_nic *icp)
Refill receive descriptor ring.
Definition: icplus.c:398
An IC+ network card.
Definition: icplus.h:189
unsigned int listptr
Definition: icplus.h:179
#define writew
Definition: w89c840.c:159
struct icplus_ring rx
Receive descriptor ring.
Definition: icplus.h:201
static int icplus_create_ring(struct icplus_nic *icp, struct icplus_ring *ring)
Create descriptor ring.
Definition: icplus.c:338
void * regs
Registers.
Definition: icplus.h:191

References icplus_ring::entry, ICP_MACCTRL, ICP_MACCTRL_DUPLEX, ICP_MACCTRL_RXENABLE, ICP_MACCTRL_TXENABLE, ICP_RXMODE, ICP_RXMODE_ALLFRAMES, ICP_RXMODE_BROADCAST, ICP_RXMODE_MULTICAST, ICP_RXMODE_UNICAST, icplus_check_link(), icplus_create_ring(), icplus_destroy_ring(), icplus_refill_rx(), icplus_reset(), icplus_set_base(), icplus_ring::listptr, netdev, net_device::priv, rc, icplus_nic::regs, icplus_nic::rx, icplus_nic::tx, writel(), and writew.

◆ icplus_close()

static void icplus_close ( struct net_device netdev)
static

Close network device.

Parameters
netdevNetwork device

Definition at line 495 of file icplus.c.

495  {
496  struct icplus_nic *icp = netdev->priv;
497  unsigned int i;
498 
499  /* Perform global reset */
500  icplus_reset ( icp );
501 
502  /* Destroy receive descriptor ring */
503  icplus_destroy_ring ( icp, &icp->rx );
504 
505  /* Destroy transmit descriptor ring */
506  icplus_destroy_ring ( icp, &icp->tx );
507 
508  /* Discard any unused receive buffers */
509  for ( i = 0 ; i < ICP_NUM_DESC ; i++ ) {
510  if ( icp->rx_iobuf[i] )
511  free_iob ( icp->rx_iobuf[i] );
512  icp->rx_iobuf[i] = NULL;
513  }
514 }
static int icplus_reset(struct icplus_nic *icp)
Reset hardware.
Definition: icplus.c:58
static void icplus_destroy_ring(struct icplus_nic *icp __unused, struct icplus_ring *ring)
Destroy descriptor ring.
Definition: icplus.c:384
struct icplus_ring tx
Transmit descriptor ring.
Definition: icplus.h:199
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
An IC+ network card.
Definition: icplus.h:189
#define ICP_NUM_DESC
Number of descriptors.
Definition: icplus.h:183
struct io_buffer * rx_iobuf[ICP_NUM_DESC]
Receive I/O buffers.
Definition: icplus.h:203
struct icplus_ring rx
Receive descriptor ring.
Definition: icplus.h:201
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References free_iob(), ICP_NUM_DESC, icplus_destroy_ring(), icplus_reset(), netdev, NULL, net_device::priv, icplus_nic::rx, icplus_nic::rx_iobuf, and icplus_nic::tx.

◆ icplus_transmit()

static int icplus_transmit ( struct net_device netdev,
struct io_buffer iobuf 
)
static

Transmit packet.

Parameters
netdevNetwork device
iobufI/O buffer
Return values
rcReturn status code

Definition at line 523 of file icplus.c.

524  {
525  struct icplus_nic *icp = netdev->priv;
526  struct icplus_descriptor *desc;
527  unsigned int tx_idx;
529 
530  /* Check if ring is full */
531  if ( ( icp->tx.prod - icp->tx.cons ) >= ICP_NUM_DESC ) {
532  DBGC ( icp, "ICP %p out of transmit descriptors\n", icp );
533  return -ENOBUFS;
534  }
535 
536  /* Find TX descriptor entry to use */
537  tx_idx = ( icp->tx.prod++ % ICP_NUM_DESC );
538  desc = &icp->tx.entry[tx_idx];
539 
540  /* Fill in TX descriptor */
541  address = virt_to_bus ( iobuf->data );
542  desc->data.address = cpu_to_le64 ( address );
543  desc->data.len = cpu_to_le16 ( iob_len ( iobuf ) );
544  wmb();
545  desc->control = ICP_TX_SOLE_FRAG;
546  wmb();
547 
548  /* Ring doorbell */
550 
551  DBGC2 ( icp, "ICP %p TX %d is [%llx,%llx)\n", icp, tx_idx,
552  ( ( unsigned long long ) address ),
553  ( ( unsigned long long ) address + iob_len ( iobuf ) ) );
554  DBGC2_HDA ( icp, virt_to_phys ( desc ), desc, sizeof ( *desc ) );
555  return 0;
556 }
wmb()
struct icplus_ring tx
Transmit descriptor ring.
Definition: icplus.h:199
unsigned int prod
Producer counter.
Definition: icplus.h:173
uint64_t address
Base address.
Definition: ena.h:24
#define ICP_DMACTRL
DMA control register (word/double word)
Definition: icplus.h:42
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define DBGC(...)
Definition: compiler.h:505
#define cpu_to_le64(value)
Definition: byteswap.h:108
struct icplus_descriptor * entry
Ring entries.
Definition: icplus.h:177
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
#define ICP_TX_SOLE_FRAG
Sole transmit fragment.
Definition: icplus.h:150
#define DBGC2_HDA(...)
Definition: compiler.h:523
unsigned int cons
Consumer counter.
Definition: icplus.h:175
Transmit or receive descriptor.
Definition: icplus.h:121
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
An IC+ network card.
Definition: icplus.h:189
unsigned long physaddr_t
Definition: stdint.h:20
#define ICP_NUM_DESC
Number of descriptors.
Definition: icplus.h:183
#define ICP_DMACTRL_TXPOLLNOW
Transmit poll now.
Definition: icplus.h:44
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
#define DBGC2(...)
Definition: compiler.h:522
#define writew
Definition: w89c840.c:159
void * data
Start of data.
Definition: iobuf.h:48
#define cpu_to_le16(value)
Definition: byteswap.h:106
void * regs
Registers.
Definition: icplus.h:191

References address, icplus_ring::cons, cpu_to_le16, cpu_to_le64, io_buffer::data, DBGC, DBGC2, DBGC2_HDA, desc, ENOBUFS, icplus_ring::entry, ICP_DMACTRL, ICP_DMACTRL_TXPOLLNOW, ICP_NUM_DESC, ICP_TX_SOLE_FRAG, iob_len(), netdev, net_device::priv, icplus_ring::prod, icplus_nic::regs, icplus_nic::tx, virt_to_bus(), virt_to_phys(), wmb(), and writew.

◆ icplus_poll_tx()

static void icplus_poll_tx ( struct net_device netdev)
static

Poll for completed packets.

Parameters
netdevNetwork device

Definition at line 563 of file icplus.c.

563  {
564  struct icplus_nic *icp = netdev->priv;
565  struct icplus_descriptor *desc;
566  unsigned int tx_idx;
567 
568  /* Check for completed packets */
569  while ( icp->tx.cons != icp->tx.prod ) {
570 
571  /* Get next transmit descriptor */
572  tx_idx = ( icp->tx.cons % ICP_NUM_DESC );
573  desc = &icp->tx.entry[tx_idx];
574 
575  /* Stop if descriptor is still in use */
576  if ( ! ( desc->control & ICP_DONE ) )
577  return;
578 
579  /* Complete TX descriptor */
580  DBGC2 ( icp, "ICP %p TX %d complete\n", icp, tx_idx );
582  icp->tx.cons++;
583  }
584 }
struct icplus_ring tx
Transmit descriptor ring.
Definition: icplus.h:199
unsigned int prod
Producer counter.
Definition: icplus.h:173
static void netdev_tx_complete_next(struct net_device *netdev)
Complete network transmission.
Definition: netdevice.h:764
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
struct icplus_descriptor * entry
Ring entries.
Definition: icplus.h:177
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
unsigned int cons
Consumer counter.
Definition: icplus.h:175
Transmit or receive descriptor.
Definition: icplus.h:121
An IC+ network card.
Definition: icplus.h:189
#define ICP_NUM_DESC
Number of descriptors.
Definition: icplus.h:183
#define DBGC2(...)
Definition: compiler.h:522
#define ICP_DONE
Descriptor complete.
Definition: icplus.h:141

References icplus_ring::cons, DBGC2, desc, icplus_ring::entry, ICP_DONE, ICP_NUM_DESC, netdev, netdev_tx_complete_next(), net_device::priv, icplus_ring::prod, and icplus_nic::tx.

Referenced by icplus_poll().

◆ icplus_poll_rx()

static void icplus_poll_rx ( struct net_device netdev)
static

Poll for received packets.

Parameters
netdevNetwork device

Definition at line 591 of file icplus.c.

591  {
592  struct icplus_nic *icp = netdev->priv;
593  struct icplus_descriptor *desc;
594  struct io_buffer *iobuf;
595  unsigned int rx_idx;
596  size_t len;
597 
598  /* Check for received packets */
599  while ( icp->rx.cons != icp->rx.prod ) {
600 
601  /* Get next transmit descriptor */
602  rx_idx = ( icp->rx.cons % ICP_NUM_DESC );
603  desc = &icp->rx.entry[rx_idx];
604 
605  /* Stop if descriptor is still in use */
606  if ( ! ( desc->control & ICP_DONE ) )
607  return;
608 
609  /* Populate I/O buffer */
610  iobuf = icp->rx_iobuf[rx_idx];
611  icp->rx_iobuf[rx_idx] = NULL;
612  len = le16_to_cpu ( desc->len );
613  iob_put ( iobuf, len );
614 
615  /* Hand off to network stack */
616  if ( desc->flags & ( ICP_RX_ERR_OVERRUN | ICP_RX_ERR_RUNT |
619  DBGC ( icp, "ICP %p RX %d error (length %zd, "
620  "flags %02x)\n", icp, rx_idx, len, desc->flags );
621  netdev_rx_err ( netdev, iobuf, -EIO );
622  } else {
623  DBGC2 ( icp, "ICP %p RX %d complete (length "
624  "%zd)\n", icp, rx_idx, len );
625  netdev_rx ( netdev, iobuf );
626  }
627  icp->rx.cons++;
628  }
629 }
#define iob_put(iobuf, len)
Definition: iobuf.h:120
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:586
#define ICP_RX_ERR_ALIGN
Receive alignment error.
Definition: icplus.h:159
unsigned int prod
Producer counter.
Definition: icplus.h:173
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define ICP_RX_ERR_OVERSIZED
Receive oversized frame error.
Definition: icplus.h:165
#define DBGC(...)
Definition: compiler.h:505
struct icplus_descriptor * entry
Ring entries.
Definition: icplus.h:177
#define ICP_RX_ERR_RUNT
Receive runt frame error.
Definition: icplus.h:156
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
#define ICP_RX_ERR_FCS
Receive FCS error.
Definition: icplus.h:162
unsigned int cons
Consumer counter.
Definition: icplus.h:175
Transmit or receive descriptor.
Definition: icplus.h:121
#define ICP_RX_ERR_OVERRUN
Recieve frame overrun error.
Definition: icplus.h:153
#define le16_to_cpu(value)
Definition: byteswap.h:112
An IC+ network card.
Definition: icplus.h:189
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:548
#define ICP_NUM_DESC
Number of descriptors.
Definition: icplus.h:183
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
struct io_buffer * rx_iobuf[ICP_NUM_DESC]
Receive I/O buffers.
Definition: icplus.h:203
#define EIO
Input/output error.
Definition: errno.h:433
struct icplus_ring rx
Receive descriptor ring.
Definition: icplus.h:201
#define ICP_RX_ERR_LEN
Recieve length error.
Definition: icplus.h:168
#define ICP_DONE
Descriptor complete.
Definition: icplus.h:141
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
A persistent I/O buffer.
Definition: iobuf.h:33

References icplus_ring::cons, DBGC, DBGC2, desc, EIO, icplus_ring::entry, ICP_DONE, ICP_NUM_DESC, ICP_RX_ERR_ALIGN, ICP_RX_ERR_FCS, ICP_RX_ERR_LEN, ICP_RX_ERR_OVERRUN, ICP_RX_ERR_OVERSIZED, ICP_RX_ERR_RUNT, iob_put, le16_to_cpu, len, netdev, netdev_rx(), netdev_rx_err(), NULL, net_device::priv, icplus_ring::prod, icplus_nic::rx, and icplus_nic::rx_iobuf.

Referenced by icplus_poll().

◆ icplus_poll()

static void icplus_poll ( struct net_device netdev)
static

Poll for completed and received packets.

Parameters
netdevNetwork device

Definition at line 636 of file icplus.c.

636  {
637  struct icplus_nic *icp = netdev->priv;
638  uint16_t intstatus;
639  uint32_t txstatus;
640 
641  /* Check for interrupts */
642  intstatus = readw ( icp->regs + ICP_INTSTATUS );
643 
644  /* Poll for TX completions, if applicable */
645  if ( intstatus & ICP_INTSTATUS_TXCOMPLETE ) {
646  txstatus = readl ( icp->regs + ICP_TXSTATUS );
647  if ( txstatus & ICP_TXSTATUS_ERROR )
648  DBGC ( icp, "ICP %p TX error: %08x\n", icp, txstatus );
650  }
651 
652  /* Poll for RX completions, if applicable */
653  if ( intstatus & ICP_INTSTATUS_RXDMACOMPLETE ) {
656  }
657 
658  /* Check link state, if applicable */
659  if ( intstatus & ICP_INTSTATUS_LINKEVENT ) {
662  }
663 
664  /* Refill receive ring */
665  icplus_refill_rx ( icp );
666 }
#define ICP_TXSTATUS_ERROR
TX error.
Definition: icplus.h:105
unsigned short uint16_t
Definition: stdint.h:11
static void icplus_check_link(struct net_device *netdev)
Check link state.
Definition: icplus.c:286
uint16_t readw(volatile uint16_t *io_addr)
Read 16-bit word from memory-mapped device.
uint32_t readl(volatile uint32_t *io_addr)
Read 32-bit dword from memory-mapped device.
#define ICP_INTSTATUS
Interupt status register (word)
Definition: icplus.h:70
#define DBGC(...)
Definition: compiler.h:505
static void icplus_poll_tx(struct net_device *netdev)
Poll for completed packets.
Definition: icplus.c:563
#define ICP_INTSTATUS_LINKEVENT
Link event.
Definition: icplus.h:72
static void icplus_poll_rx(struct net_device *netdev)
Poll for received packets.
Definition: icplus.c:591
#define ICP_INTSTATUS_RXDMACOMPLETE
RX DMA complete.
Definition: icplus.h:73
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
#define ICP_TXSTATUS
Transmit status register.
Definition: icplus.h:104
unsigned int uint32_t
Definition: stdint.h:12
void icplus_refill_rx(struct icplus_nic *icp)
Refill receive descriptor ring.
Definition: icplus.c:398
An IC+ network card.
Definition: icplus.h:189
#define writew
Definition: w89c840.c:159
#define ICP_INTSTATUS_TXCOMPLETE
TX complete.
Definition: icplus.h:71
void * regs
Registers.
Definition: icplus.h:191

References DBGC, ICP_INTSTATUS, ICP_INTSTATUS_LINKEVENT, ICP_INTSTATUS_RXDMACOMPLETE, ICP_INTSTATUS_TXCOMPLETE, ICP_TXSTATUS, ICP_TXSTATUS_ERROR, icplus_check_link(), icplus_poll_rx(), icplus_poll_tx(), icplus_refill_rx(), netdev, net_device::priv, readl(), readw(), icplus_nic::regs, and writew.

◆ icplus_irq()

static void icplus_irq ( struct net_device netdev,
int  enable 
)
static

Enable or disable interrupts.

Parameters
netdevNetwork device
enableInterrupts should be enabled

Definition at line 674 of file icplus.c.

674  {
675  struct icplus_nic *icp = netdev->priv;
676 
677  DBGC ( icp, "ICPLUS %p does not yet support interrupts\n", icp );
678  ( void ) enable;
679 }
#define DBGC(...)
Definition: compiler.h:505
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
An IC+ network card.
Definition: icplus.h:189

References DBGC, netdev, and net_device::priv.

◆ icplus_probe()

static int icplus_probe ( struct pci_device pci)
static

Probe PCI device.

Parameters
pciPCI device
Return values
rcReturn status code

Definition at line 703 of file icplus.c.

703  {
704  struct net_device *netdev;
705  struct icplus_nic *icp;
706  int rc;
707 
708  /* Allocate and initialise net device */
709  netdev = alloc_etherdev ( sizeof ( *icp ) );
710  if ( ! netdev ) {
711  rc = -ENOMEM;
712  goto err_alloc;
713  }
715  icp = netdev->priv;
716  pci_set_drvdata ( pci, netdev );
717  netdev->dev = &pci->dev;
718  memset ( icp, 0, sizeof ( *icp ) );
720  init_mii_bit_basher ( &icp->miibit );
721  mii_init ( &icp->mii, &icp->miibit.mdio, 0 );
722  icp->tx.listptr = ICP_TFDLISTPTR;
723  icp->rx.listptr = ICP_RFDLISTPTR;
724 
725  /* Fix up PCI device */
726  adjust_pci_device ( pci );
727 
728  /* Map registers */
729  icp->regs = pci_ioremap ( pci, pci->membase, ICP_BAR_SIZE );
730  if ( ! icp->regs ) {
731  rc = -ENODEV;
732  goto err_ioremap;
733  }
734 
735  /* Reset the NIC */
736  if ( ( rc = icplus_reset ( icp ) ) != 0 )
737  goto err_reset;
738 
739  /* Initialise EEPROM */
740  icplus_init_eeprom ( icp );
741 
742  /* Read EEPROM MAC address */
743  if ( ( rc = nvs_read ( &icp->eeprom, ICP_EEPROM_MAC,
744  netdev->hw_addr, ETH_ALEN ) ) != 0 ) {
745  DBGC ( icp, "ICPLUS %p could not read EEPROM MAC address: %s\n",
746  icp, strerror ( rc ) );
747  goto err_eeprom;
748  }
749 
750  /* Configure PHY */
751  if ( ( rc = icplus_init_phy ( icp ) ) != 0 )
752  goto err_phy;
753 
754  /* Register network device */
755  if ( ( rc = register_netdev ( netdev ) ) != 0 )
756  goto err_register_netdev;
757 
758  /* Set initial link state */
760 
761  return 0;
762 
764  err_register_netdev:
765  err_phy:
766  err_eeprom:
767  icplus_reset ( icp );
768  err_reset:
769  iounmap ( icp->regs );
770  err_ioremap:
772  netdev_put ( netdev );
773  err_alloc:
774  return rc;
775 }
#define ICP_EEPROM_MAC
Address of MAC address within EEPROM.
Definition: icplus.h:64
unsigned long membase
Memory base.
Definition: pci.h:215
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct mii_interface mdio
MII interface.
Definition: mii_bit.h:35
static void icplus_check_link(struct net_device *netdev)
Check link state.
Definition: icplus.c:286
struct nvs_device eeprom
EEPROM.
Definition: icplus.h:193
static int icplus_reset(struct icplus_nic *icp)
Reset hardware.
Definition: icplus.c:58
#define ICP_TFDLISTPTR
List pointer transmit register.
Definition: icplus.h:101
struct icplus_ring tx
Transmit descriptor ring.
Definition: icplus.h:199
void init_mii_bit_basher(struct mii_bit_basher *miibit)
Initialise bit-bashing interface.
Definition: mii_bit.c:160
static struct bit_basher_operations icplus_basher_ops
MII bit-bashing interface.
Definition: icplus.c:231
#define ICP_RFDLISTPTR
List pointer receive register.
Definition: icplus.h:98
#define DBGC(...)
Definition: compiler.h:505
static void icplus_init_eeprom(struct icplus_nic *icp)
Initialise EEPROM.
Definition: icplus.c:162
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition: pci.c:154
struct bit_basher_operations * op
Bit-bashing operations.
Definition: bitbash.h:57
struct device dev
Generic device.
Definition: pci.h:208
#define ICP_BAR_SIZE
BAR size.
Definition: icplus.h:16
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:515
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition: pci.h:359
#define ENOMEM
Not enough space.
Definition: errno.h:534
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
static int icplus_init_phy(struct icplus_nic *icp)
Configure PHY.
Definition: icplus.c:249
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:759
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_ALEN
Definition: if_ether.h:8
An IC+ network card.
Definition: icplus.h:189
unsigned int listptr
Definition: icplus.h:179
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
static void mii_init(struct mii_device *mii, struct mii_interface *mdio, unsigned int address)
Initialise MII device.
Definition: mii.h:75
struct mii_bit_basher miibit
MII bit bashing interface.
Definition: icplus.h:195
struct mii_device mii
MII device.
Definition: icplus.h:197
static struct net_device_operations icplus_operations
IC+ network device operations.
Definition: icplus.c:682
struct bit_basher basher
Bit-bashing interface.
Definition: mii_bit.h:37
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:264
void iounmap(volatile const void *io_addr)
Unmap I/O address.
struct icplus_ring rx
Receive descriptor ring.
Definition: icplus.h:201
int nvs_read(struct nvs_device *nvs, unsigned int address, void *data, size_t len)
Read from non-volatile storage device.
Definition: nvs.c:75
void * pci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:381
void * memset(void *dest, int character, size_t len) __nonnull
void * regs
Registers.
Definition: icplus.h:191

References adjust_pci_device(), alloc_etherdev(), mii_bit_basher::basher, DBGC, pci_device::dev, net_device::dev, icplus_nic::eeprom, ENODEV, ENOMEM, ETH_ALEN, net_device::hw_addr, ICP_BAR_SIZE, ICP_EEPROM_MAC, ICP_RFDLISTPTR, ICP_TFDLISTPTR, icplus_basher_ops, icplus_check_link(), icplus_init_eeprom(), icplus_init_phy(), icplus_operations, icplus_reset(), init_mii_bit_basher(), iounmap(), icplus_ring::listptr, mii_bit_basher::mdio, pci_device::membase, memset(), icplus_nic::mii, mii_init(), icplus_nic::miibit, netdev, netdev_init(), netdev_nullify(), netdev_put(), nvs_read(), bit_basher::op, pci_ioremap(), pci_set_drvdata(), net_device::priv, rc, register_netdev(), icplus_nic::regs, icplus_nic::rx, strerror(), icplus_nic::tx, and unregister_netdev().

◆ icplus_remove()

static void icplus_remove ( struct pci_device pci)
static

Remove PCI device.

Parameters
pciPCI device

Definition at line 782 of file icplus.c.

782  {
783  struct net_device *netdev = pci_get_drvdata ( pci );
784  struct icplus_nic *icp = netdev->priv;
785 
786  /* Unregister network device */
788 
789  /* Reset card */
790  icplus_reset ( icp );
791 
792  /* Free network device */
793  iounmap ( icp->regs );
795  netdev_put ( netdev );
796 }
static int icplus_reset(struct icplus_nic *icp)
Reset hardware.
Definition: icplus.c:58
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
A network device.
Definition: netdevice.h:352
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:528
An IC+ network card.
Definition: icplus.h:189
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition: pci.h:369
void iounmap(volatile const void *io_addr)
Unmap I/O address.
void * regs
Registers.
Definition: icplus.h:191

References icplus_reset(), iounmap(), netdev, netdev_nullify(), netdev_put(), pci_get_drvdata(), net_device::priv, icplus_nic::regs, and unregister_netdev().

Variable Documentation

◆ icplus_mii_bits

const uint8_t icplus_mii_bits[]
static
Initial value:
= {
}
MII data direction.
Definition: mii_bit.h:47
MII data.
Definition: mii_bit.h:45
MII clock.
Definition: mii_bit.h:43
#define ICP_PHYCTRL_MGMTDIR
Management direction.
Definition: icplus.h:87
#define ICP_PHYCTRL_MGMTDATA
Management data.
Definition: icplus.h:86
#define ICP_PHYCTRL_MGMTCLK
Management clock.
Definition: icplus.h:85

Pin mapping for MII bit-bashing interface.

Definition at line 180 of file icplus.c.

Referenced by icplus_mii_read_bit(), and icplus_mii_write_bit().

◆ icplus_basher_ops

struct bit_basher_operations icplus_basher_ops
static
Initial value:
= {
}
static void icplus_mii_write_bit(struct bit_basher *basher, unsigned int bit_id, unsigned long data)
Set/clear output bit.
Definition: icplus.c:214
static int icplus_mii_read_bit(struct bit_basher *basher, unsigned int bit_id)
Read input bit.
Definition: icplus.c:194

MII bit-bashing interface.

Definition at line 231 of file icplus.c.

Referenced by icplus_probe().

◆ icplus_operations

struct net_device_operations icplus_operations
static
Initial value:
= {
.open = icplus_open,
.close = icplus_close,
.transmit = icplus_transmit,
.poll = icplus_poll,
.irq = icplus_irq,
}
static void icplus_close(struct net_device *netdev)
Close network device.
Definition: icplus.c:495
static int icplus_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: icplus.c:523
static void icplus_irq(struct net_device *netdev, int enable)
Enable or disable interrupts.
Definition: icplus.c:674
static void icplus_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition: icplus.c:636
static int icplus_open(struct net_device *netdev)
Open network device.
Definition: icplus.c:449

IC+ network device operations.

Definition at line 682 of file icplus.c.

Referenced by icplus_probe().

◆ icplus_nics

struct pci_device_id icplus_nics[]
static
Initial value:
= {
PCI_ROM ( 0x13f0, 0x1023, "ip1000a", "IP1000A", 0 ),
}
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition: pci.h:303

IC+ PCI device IDs.

Definition at line 799 of file icplus.c.

◆ __pci_driver

struct pci_driver icplus_driver __pci_driver
Initial value:
= {
.ids = icplus_nics,
.id_count = ( sizeof ( icplus_nics ) / sizeof ( icplus_nics[0] ) ),
.probe = icplus_probe,
}
static void icplus_remove(struct pci_device *pci)
Remove PCI device.
Definition: icplus.c:782
static struct pci_device_id icplus_nics[]
IC+ PCI device IDs.
Definition: icplus.c:799
static struct xen_remove_from_physmap * remove
Definition: xenmem.h:39
static int icplus_probe(struct pci_device *pci)
Probe PCI device.
Definition: icplus.c:703

IC+ PCI driver.

Definition at line 804 of file icplus.c.