iPXE
Data Structures | Macros | Enumerations | Functions | Variables
tulip.c File Reference
#include "etherboot.h"
#include "nic.h"
#include <ipxe/ethernet.h>
#include <ipxe/pci.h>

Go to the source code of this file.

Data Structures

struct  pci_id_info
 
struct  pci_id_info::match_info
 
struct  tulip_chip_table
 
struct  medialeaf
 
struct  mediatable
 
struct  mediainfo
 
struct  tulip_rx_desc
 
struct  tulip_tx_desc
 
struct  tulip_private
 
struct  tulip_bss
 
struct  fixups
 

Macros

#define TX_TIME_OUT   2*TICKS_PER_SEC
 
#define get_unaligned(ptr)   (*(ptr))
 
#define put_unaligned(val, ptr)   ((void)( *(ptr) = (val) ))
 
#define get_u16(ptr)   (*(u16 *)(ptr))
 
#define virt_to_le32desc(addr)   virt_to_bus(addr)
 
#define TULIP_IOTYPE   PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0
 
#define TULIP_SIZE   0x80
 
#define FULL_DUPLEX_MAGIC   0x6969
 
#define MEDIA_MASK   31
 
#define EEPROM_ADDRLEN   6
 
#define EEPROM_SIZE   128 /* 2 << EEPROM_ADDRLEN */
 
#define EE_WRITE_CMD   (5 << addr_len)
 
#define EE_READ_CMD   (6 << addr_len)
 
#define EE_ERASE_CMD   (7 << addr_len)
 
#define EE_SHIFT_CLK   0x02 /* EEPROM shift clock. */
 
#define EE_CS   0x01 /* EEPROM chip select. */
 
#define EE_DATA_WRITE   0x04 /* EEPROM chip data in. */
 
#define EE_WRITE_0   0x01
 
#define EE_WRITE_1   0x05
 
#define EE_DATA_READ   0x08 /* EEPROM chip data out. */
 
#define EE_ENB   (0x4800 | EE_CS)
 
#define eeprom_delay()   inl(ee_addr)
 
#define BUFLEN   1536
 
#define DESC_RING_WRAP   0x02000000
 
#define TX_RING_SIZE   2
 
#define RX_RING_SIZE   4
 
#define tulip_bss   NIC_FAKE_BSS ( struct tulip_bss )
 
#define tx_ring   tulip_bss.tx_ring
 
#define txb   tulip_bss.txb
 
#define rx_ring   tulip_bss.rx_ring
 
#define rxb   tulip_bss.rxb
 
#define mdio_delay()   inl(mdio_addr)
 
#define MDIO_SHIFT_CLK   0x10000
 
#define MDIO_DATA_WRITE0   0x00000
 
#define MDIO_DATA_WRITE1   0x20000
 
#define MDIO_ENB   0x00000 /* Ignore the 0x02000 databook setting. */
 
#define MDIO_ENB_IN   0x40000
 
#define MDIO_DATA_READ   0x80000
 

Enumerations

enum  tulip_chips {
  DC21040 =0, DC21041 =1, DC21140 =2, DC21142 =3,
  DC21143 =3, LC82C168, MX98713, MX98715,
  MX98725, AX88141, AX88140, PNIC2,
  COMET, COMPEX9881, I21145, XIRCOM,
  SGThomson
}
 
enum  pci_id_flags_bits {
  PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, PCI_ADDR0 = 0 << 4,
  PCI_ADDR1 = 1 << 4, PCI_ADDR2, PCI_ADDR3 = 3 << 4, PCI_USES_IO =1,
  PCI_USES_MEM =2, PCI_USES_MASTER =4, PCI_ADDR0 =0<<4, PCI_ADDR1 =1<<4,
  PCI_ADDR2 =2<<4, PCI_ADDR3 =3<<4, PCI_ADDR_64BITS =0x100, PCI_NO_ACPI_WAKE =0x200,
  PCI_NO_MIN_LATENCY =0x400, PCI_UNUSED_IRQ =0x800
}
 
enum  tbl_flag {
  HAS_MII =1, HAS_MEDIA_TABLE =2, CSR12_IN_SROM =4, ALWAYS_CHECK_MII =8,
  HAS_PWRDWN =0x10, MC_HASH_ONLY =0x20, HAS_PNICNWAY =0x80, HAS_NWAY =0x40,
  HAS_INTR_MITIGATION =0x100, IS_ASIX =0x200, HAS_8023X =0x400
}
 
enum  MediaIs {
  MediaIsFD = 1, MediaAlwaysFD =2, MediaIsMII =4, MediaIsFx =8,
  MediaIs100 =16
}
 
enum  tulip_offsets {
  CSR0 =0, CSR1 =0x08, CSR2 =0x10, CSR3 =0x18,
  CSR4 =0x20, CSR5 =0x28, CSR6 =0x30, CSR7 =0x38,
  CSR8 =0x40, CSR9 =0x48, CSR10 =0x50, CSR11 =0x58,
  CSR12 =0x60, CSR13 =0x68, CSR14 =0x70, CSR15 =0x78,
  CSR16 =0x80, CSR20 =0xA0
}
 
enum  status_bits {
  TimerInt =0x800, TPLnkFail =0x1000, TPLnkPass =0x10, NormalIntr =0x10000,
  AbnormalIntr =0x8000, RxJabber =0x200, RxDied =0x100, RxNoBuf =0x80,
  RxIntr =0x40, TxFIFOUnderflow =0x20, TxJabber =0x08, TxNoBuf =0x04,
  TxDied =0x02, TxIntr =0x01
}
 
enum  csr6_mode_bits {
  TxOn =0x2000, RxOn =0x0002, FullDuplex =0x0200, AcceptBroadcast =0x0100,
  AcceptAllMulticast =0x0080, AcceptAllPhys =0x0040, AcceptRunt =0x0008
}
 
enum  desc_status_bits {
  DescOwn = 0x8000, DescEndPacket = 0x4000, DescEndRing = 0x2000, LastFrag = 0x80000000,
  DescIntrOnTx = 0x8000, DescIntrOnDMADone = 0x80000000, DisableAlign = 0x00000001, DescOwnded =0x80000000,
  RxDescFatalErr =0x8000, RxWholePkt =0x0300, DescOwn =0x80000000, DescEndRing =0x02000000,
  DescUseLink =0x01000000, DescWholePkt =0x60000000, DescStartPkt =0x20000000, DescEndPkt =0x40000000,
  DescIntr =0x80000000
}
 

Functions

 FILE_LICENCE (GPL_ANY)
 
static int mdio_read (struct nic *nic, int phy_id, int location)
 
static void mdio_write (struct nic *nic, int phy_id, int location, int value)
 
static int read_eeprom (unsigned long ioaddr, int location, int addr_len)
 
static void parse_eeprom (struct nic *nic)
 
static int tulip_probe (struct nic *nic, struct pci_device *pci)
 
static void tulip_init_ring (struct nic *nic)
 
static void tulip_reset (struct nic *nic)
 
static void tulip_transmit (struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
 
static int tulip_poll (struct nic *nic, int retrieve)
 
static void tulip_disable (struct nic *nic, void *hwdev)
 
static void nway_start (struct nic *nic)
 
static void pnic_do_nway (struct nic *nic)
 
static void select_media (struct nic *nic, int startup)
 
static void init_media (struct nic *nic)
 
static void start_link (struct nic *nic)
 
static int tulip_check_duplex (struct nic *nic)
 
static void tulip_wait (unsigned int nticks)
 
static void whereami (const char *str)
 
int mdio_read (struct nic *nic __unused, int phy_id, int location)
 
void mdio_write (struct nic *nic __unused, int phy_id, int location, int value)
 
static void tulip_init_ring (struct nic *nic __unused)
 
static void set_rx_mode (struct nic *nic __unused)
 
static void tulip_disable (struct nic *nic, void *hwdev __unused)
 
static void tulip_irq (struct nic *nic __unused, irq_action_t action __unused)
 
static void nway_start (struct nic *nic __unused)
 
static void pnic_do_nway (struct nic *nic __unused)
 
 PCI_DRIVER (tulip_driver, tulip_nics, PCI_NO_CLASS)
 
 DRIVER ("Tulip", nic_driver, pci_driver, tulip_driver, tulip_probe, tulip_disable, tulip_bss)
 

Variables

static const int csr0 = 0x01A00000 | 0x8000
 
static const char *const medianame [32]
 
static const struct pci_id_info pci_id_tbl []
 
static struct tulip_chip_table tulip_tbl []
 
static const char media_cap [32]
 
static u8 t21040_csr13 [] = {2,0x0C,8,4, 4,0,0,0, 0,0,0,0, 4,0,0,0}
 
static u16 t21041_csr13 [] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }
 
static u16 t21041_csr14 [] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }
 
static u16 t21041_csr15 [] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }
 
static u16 t21142_csr14 [] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, }
 
static u32 ioaddr
 
static struct tulip_privatetp
 
static struct fixups eeprom_fixups []
 
static const char * block_name []
 
static struct nic_operations tulip_operations
 
static struct pci_device_id tulip_nics []
 

Macro Definition Documentation

◆ TX_TIME_OUT

#define TX_TIME_OUT   2*TICKS_PER_SEC

Definition at line 119 of file tulip.c.

◆ get_unaligned

#define get_unaligned (   ptr)    (*(ptr))

Definition at line 123 of file tulip.c.

◆ put_unaligned

#define put_unaligned (   val,
  ptr 
)    ((void)( *(ptr) = (val) ))

Definition at line 124 of file tulip.c.

◆ get_u16

#define get_u16 (   ptr)    (*(u16 *)(ptr))

Definition at line 125 of file tulip.c.

◆ virt_to_le32desc

#define virt_to_le32desc (   addr)    virt_to_bus(addr)

Definition at line 126 of file tulip.c.

◆ TULIP_IOTYPE

#define TULIP_IOTYPE   PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0

Definition at line 128 of file tulip.c.

◆ TULIP_SIZE

#define TULIP_SIZE   0x80

Definition at line 129 of file tulip.c.

◆ FULL_DUPLEX_MAGIC

#define FULL_DUPLEX_MAGIC   0x6969

Definition at line 135 of file tulip.c.

◆ MEDIA_MASK

#define MEDIA_MASK   31

Definition at line 140 of file tulip.c.

◆ EEPROM_ADDRLEN

#define EEPROM_ADDRLEN   6

Definition at line 342 of file tulip.c.

◆ EEPROM_SIZE

#define EEPROM_SIZE   128 /* 2 << EEPROM_ADDRLEN */

Definition at line 343 of file tulip.c.

◆ EE_WRITE_CMD

#define EE_WRITE_CMD   (5 << addr_len)

Definition at line 346 of file tulip.c.

◆ EE_READ_CMD

#define EE_READ_CMD   (6 << addr_len)

Definition at line 347 of file tulip.c.

◆ EE_ERASE_CMD

#define EE_ERASE_CMD   (7 << addr_len)

Definition at line 348 of file tulip.c.

◆ EE_SHIFT_CLK

#define EE_SHIFT_CLK   0x02 /* EEPROM shift clock. */

Definition at line 351 of file tulip.c.

◆ EE_CS

#define EE_CS   0x01 /* EEPROM chip select. */

Definition at line 352 of file tulip.c.

◆ EE_DATA_WRITE

#define EE_DATA_WRITE   0x04 /* EEPROM chip data in. */

Definition at line 353 of file tulip.c.

◆ EE_WRITE_0

#define EE_WRITE_0   0x01

Definition at line 354 of file tulip.c.

◆ EE_WRITE_1

#define EE_WRITE_1   0x05

Definition at line 355 of file tulip.c.

◆ EE_DATA_READ

#define EE_DATA_READ   0x08 /* EEPROM chip data out. */

Definition at line 356 of file tulip.c.

◆ EE_ENB

#define EE_ENB   (0x4800 | EE_CS)

Definition at line 357 of file tulip.c.

◆ eeprom_delay

#define eeprom_delay ( )    inl(ee_addr)

Definition at line 362 of file tulip.c.

◆ BUFLEN

#define BUFLEN   1536

Definition at line 365 of file tulip.c.

◆ DESC_RING_WRAP

#define DESC_RING_WRAP   0x02000000

Definition at line 374 of file tulip.c.

◆ TX_RING_SIZE

#define TX_RING_SIZE   2

Definition at line 427 of file tulip.c.

◆ RX_RING_SIZE

#define RX_RING_SIZE   4

Definition at line 428 of file tulip.c.

◆ tulip_bss

#define tulip_bss   NIC_FAKE_BSS ( struct tulip_bss )

Definition at line 436 of file tulip.c.

◆ tx_ring

#define tx_ring   tulip_bss.tx_ring

Definition at line 437 of file tulip.c.

◆ txb

#define txb   tulip_bss.txb

Definition at line 438 of file tulip.c.

◆ rx_ring

#define rx_ring   tulip_bss.rx_ring

Definition at line 439 of file tulip.c.

◆ rxb

#define rxb   tulip_bss.rxb

Definition at line 440 of file tulip.c.

◆ mdio_delay

#define mdio_delay ( )    inl(mdio_addr)

Definition at line 539 of file tulip.c.

◆ MDIO_SHIFT_CLK

#define MDIO_SHIFT_CLK   0x10000

Definition at line 544 of file tulip.c.

◆ MDIO_DATA_WRITE0

#define MDIO_DATA_WRITE0   0x00000

Definition at line 545 of file tulip.c.

◆ MDIO_DATA_WRITE1

#define MDIO_DATA_WRITE1   0x20000

Definition at line 546 of file tulip.c.

◆ MDIO_ENB

#define MDIO_ENB   0x00000 /* Ignore the 0x02000 databook setting. */

Definition at line 547 of file tulip.c.

◆ MDIO_ENB_IN

#define MDIO_ENB_IN   0x40000

Definition at line 548 of file tulip.c.

◆ MDIO_DATA_READ

#define MDIO_DATA_READ   0x80000

Definition at line 549 of file tulip.c.

Enumeration Type Documentation

◆ tulip_chips

Enumerator
DC21040 
DC21041 
DC21140 
DC21142 
DC21143 
LC82C168 
MX98713 
MX98715 
MX98725 
AX88141 
AX88140 
PNIC2 
COMET 
COMPEX9881 
I21145 
XIRCOM 
SGThomson 

Definition at line 150 of file tulip.c.

150  {
151  DC21040=0, DC21041=1, DC21140=2, DC21142=3, DC21143=3,
153  COMPEX9881, I21145, XIRCOM, SGThomson, /*Ramesh Chander*/
154 };
Definition: tulip.c:151
Definition: tulip.c:152
Definition: tulip.c:152
Definition: tulip.c:152
Definition: tulip.c:153
Definition: tulip.c:152
Definition: tulip.c:152
Definition: tulip.c:151
Definition: tulip.c:153
Definition: tulip.c:151
Definition: tulip.c:152
Definition: tulip.c:151
Definition: tulip.c:152
Definition: tulip.c:151

◆ pci_id_flags_bits

Enumerator
PCI_USES_IO 
PCI_USES_MEM 
PCI_USES_MASTER 
PCI_ADDR0 
PCI_ADDR1 
PCI_ADDR2 
PCI_ADDR3 
PCI_USES_IO 
PCI_USES_MEM 
PCI_USES_MASTER 
PCI_ADDR0 
PCI_ADDR1 
PCI_ADDR2 
PCI_ADDR3 
PCI_ADDR_64BITS 
PCI_NO_ACPI_WAKE 
PCI_NO_MIN_LATENCY 
PCI_UNUSED_IRQ 

Definition at line 156 of file tulip.c.

156  {
157  /* Set PCI command register bits before calling probe1(). */
159  /* Read and map the single following PCI BAR. */
160  PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
162  PCI_UNUSED_IRQ=0x800,
163 };

◆ tbl_flag

enum tbl_flag
Enumerator
HAS_MII 
HAS_MEDIA_TABLE 
CSR12_IN_SROM 
ALWAYS_CHECK_MII 
HAS_PWRDWN 
MC_HASH_ONLY 
HAS_PNICNWAY 
HAS_NWAY 
HAS_INTR_MITIGATION 
IS_ASIX 
HAS_8023X 

Definition at line 234 of file tulip.c.

234  {
236  HAS_PWRDWN=0x10, MC_HASH_ONLY=0x20, /* Hash-only multicast filter. */
237  HAS_PNICNWAY=0x80, HAS_NWAY=0x40, /* Uses internal NWay xcvr. */
238  HAS_INTR_MITIGATION=0x100, IS_ASIX=0x200, HAS_8023X=0x400,
239 };
Definition: tulip.c:235
Definition: tulip.c:238

◆ MediaIs

enum MediaIs
Enumerator
MediaIsFD 
MediaAlwaysFD 
MediaIsMII 
MediaIsFx 
MediaIs100 

Definition at line 271 of file tulip.c.

271  {
273  MediaIs100=16};

◆ tulip_offsets

Enumerator
CSR0 
CSR1 
CSR2 
CSR3 
CSR4 
CSR5 
CSR6 
CSR7 
CSR8 
CSR9 
CSR10 
CSR11 
CSR12 
CSR13 
CSR14 
CSR15 
CSR16 
CSR20 

Definition at line 294 of file tulip.c.

294  {
295  CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
296  CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
297  CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
298 };
Definition: tulip.c:295
Definition: tulip.c:295
Definition: tulip.c:297
Definition: tulip.c:295
Definition: tulip.c:295
Definition: tulip.c:296
Definition: tulip.c:295
Definition: tulip.c:296
Definition: tulip.c:297
Definition: tulip.c:296
Definition: tulip.c:295
Definition: tulip.c:297
Definition: tulip.c:297
Definition: tulip.c:296
Definition: tulip.c:296
Definition: tulip.c:296
Definition: tulip.c:297
Definition: tulip.c:297

◆ status_bits

Enumerator
TimerInt 
TPLnkFail 
TPLnkPass 
NormalIntr 
AbnormalIntr 
RxJabber 
RxDied 
RxNoBuf 
RxIntr 
TxFIFOUnderflow 
TxJabber 
TxNoBuf 
TxDied 
TxIntr 

Definition at line 301 of file tulip.c.

301  {
302  TimerInt=0x800, TPLnkFail=0x1000, TPLnkPass=0x10,
303  NormalIntr=0x10000, AbnormalIntr=0x8000,
304  RxJabber=0x200, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40,
305  TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
306 };
Definition: tulip.c:304
Definition: tulip.c:304
Definition: tulip.c:305
Definition: tulip.c:305
Definition: tulip.c:305
Definition: tulip.c:304

◆ csr6_mode_bits

Enumerator
TxOn 
RxOn 
FullDuplex 
AcceptBroadcast 
AcceptAllMulticast 
AcceptAllPhys 
AcceptRunt 

Definition at line 309 of file tulip.c.

309  {
310  TxOn=0x2000, RxOn=0x0002, FullDuplex=0x0200,
311  AcceptBroadcast=0x0100, AcceptAllMulticast=0x0080,
312  AcceptAllPhys=0x0040, AcceptRunt=0x0008,
313 };
Definition: tulip.c:310
Definition: tulip.c:310

◆ desc_status_bits

Enumerator
DescOwn 
DescEndPacket 
DescEndRing 
LastFrag 
DescIntrOnTx 
DescIntrOnDMADone 
DisableAlign 
DescOwnded 
RxDescFatalErr 
RxWholePkt 
DescOwn 
DescEndRing 
DescUseLink 
DescWholePkt 
DescStartPkt 
DescEndPkt 
DescIntr 

Definition at line 316 of file tulip.c.

316  {
317  DescOwnded=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300,
318 };

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL_ANY  )

◆ mdio_read() [1/2]

static int mdio_read ( struct nic nic,
int  phy_id,
int  location 
)
static

◆ mdio_write() [1/2]

static void mdio_write ( struct nic nic,
int  phy_id,
int  location,
int  value 
)
static

Referenced by select_media(), and start_link().

◆ read_eeprom()

static int read_eeprom ( unsigned long  ioaddr,
int  location,
int  addr_len 
)
static

Definition at line 677 of file tulip.c.

678 {
679  int i;
680  unsigned short retval = 0;
681  long ee_addr = ioaddr + CSR9;
682  int read_cmd = location | EE_READ_CMD;
683 
684  whereami("read_eeprom\n");
685 
686  outl(EE_ENB & ~EE_CS, ee_addr);
687  outl(EE_ENB, ee_addr);
688 
689  /* Shift the read command bits out. */
690  for (i = 4 + addr_len; i >= 0; i--) {
691  short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
692  outl(EE_ENB | dataval, ee_addr);
693  eeprom_delay();
694  outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
695  eeprom_delay();
696  }
697  outl(EE_ENB, ee_addr);
698 
699  for (i = 16; i > 0; i--) {
700  outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
701  eeprom_delay();
702  retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
703  outl(EE_ENB, ee_addr);
704  eeprom_delay();
705  }
706 
707  /* Terminate the EEPROM access. */
708  outl(EE_ENB & ~EE_CS, ee_addr);
709  return retval;
710 }
#define EE_CS
Definition: tulip.c:352
#define EE_DATA_READ
Definition: tulip.c:356
static void whereami(const char *str)
Definition: tulip.c:513
#define eeprom_delay()
Definition: tulip.c:362
#define EE_DATA_WRITE
Definition: tulip.c:353
#define EE_READ_CMD
Definition: tulip.c:347
static u32 ioaddr
Definition: tulip.c:393
#define EE_ENB
Definition: tulip.c:357
#define outl(data, io_addr)
Definition: io.h:329
Definition: tulip.c:296
unsigned long retval
Definition: xen.h:45
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
static struct command_descriptor read_cmd
"read" command descriptor
Definition: nvo_cmd.c:134
#define EE_SHIFT_CLK
Definition: tulip.c:351

References CSR9, EE_CS, EE_DATA_READ, EE_DATA_WRITE, EE_ENB, EE_READ_CMD, EE_SHIFT_CLK, eeprom_delay, inl(), ioaddr, outl, read_cmd, retval, and whereami().

Referenced by tulip_probe().

◆ parse_eeprom()

static void parse_eeprom ( struct nic nic)
static

Definition at line 716 of file tulip.c.

717 {
718  unsigned char *p, *ee_data = tp->eeprom;
719  int new_advertise = 0;
720  int i;
721 
722  whereami("parse_eeprom\n");
723 
724  tp->mtable = NULL;
725  /* Detect an old-style (SA only) EEPROM layout:
726  memcmp(ee_data, ee_data+16, 8). */
727  for (i = 0; i < 8; i ++)
728  if (ee_data[i] != ee_data[16+i])
729  break;
730  if (i >= 8) {
731  /* Do a fix-up based on the vendor half of the station address. */
732  for (i = 0; eeprom_fixups[i].name; i++) {
733  if (nic->node_addr[0] == eeprom_fixups[i].addr0
734  && nic->node_addr[1] == eeprom_fixups[i].addr1
735  && nic->node_addr[2] == eeprom_fixups[i].addr2) {
736  if (nic->node_addr[2] == 0xE8 && ee_data[0x1a] == 0x55)
737  i++; /* An Accton EN1207, not an outlaw Maxtech. */
738  memcpy(ee_data + 26, eeprom_fixups[i].newtable,
739  sizeof(eeprom_fixups[i].newtable));
740  DBG("%s: Old format EEPROM on '%s' board.\n%s: Using substitute media control info.\n",
742  break;
743  }
744  }
745  if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
746  DBG("%s: Old style EEPROM with no media selection information.\n",
747  tp->nic_name);
748  return;
749  }
750  }
751 
752  if (ee_data[19] > 1) {
753  DBG("%s: Multiport cards (%d ports) may not work correctly.\n",
754  tp->nic_name, ee_data[19]);
755  }
756 
757  p = (void *)ee_data + ee_data[27];
758 
759  if (ee_data[27] == 0) { /* No valid media table. */
760  DBG2("%s: No Valid Media Table. ee_data[27] = %hhX\n",
761  tp->nic_name, ee_data[27]);
762  } else if (tp->chip_id == DC21041) {
763  int media = get_u16(p);
764  int count = p[2];
765  p += 3;
766 
767  DBG("%s: 21041 Media table, default media %hX (%s).\n",
768  tp->nic_name, media,
769  media & 0x0800 ? "Autosense" : medianame[media & 15]);
770  for (i = 0; i < count; i++) {
771  unsigned char media_block = *p++;
772  int media_code = media_block & MEDIA_MASK;
773  if (media_block & 0x40)
774  p += 6;
775  switch(media_code) {
776  case 0: new_advertise |= 0x0020; break;
777  case 4: new_advertise |= 0x0040; break;
778  }
779  DBG("%s: 21041 media #%d, %s.\n",
780  tp->nic_name, media_code, medianame[media_code]);
781  }
782  } else {
783  unsigned char csr12dir = 0;
784  int count;
785  struct mediatable *mtable;
786  u16 media = get_u16(p);
787 
788  p += 2;
789  if (tp->flags & CSR12_IN_SROM)
790  csr12dir = *p++;
791  count = *p++;
792 
793  tp->mtable = mtable = (struct mediatable *)&tp->media_table_storage[0];
794 
795  mtable->defaultmedia = media;
796  mtable->leafcount = count;
797  mtable->csr12dir = csr12dir;
798  mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
799  mtable->csr15dir = mtable->csr15val = 0;
800 
801  DBG("%s: EEPROM default media type %s.\n", tp->nic_name,
802  media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
803 
804  for (i = 0; i < count; i++) {
805  struct medialeaf *leaf = &mtable->mleaf[i];
806 
807  if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
808  leaf->type = 0;
809  leaf->media = p[0] & 0x3f;
810  leaf->leafdata = p;
811  if ((p[2] & 0x61) == 0x01) /* Bogus, but Znyx boards do it. */
812  mtable->has_mii = 1;
813  p += 4;
814  } else {
815  switch(leaf->type = p[1]) {
816  case 5:
817  mtable->has_reset = i;
818  leaf->media = p[2] & 0x0f;
819  break;
820  case 1: case 3:
821  mtable->has_mii = 1;
822  leaf->media = 11;
823  break;
824  case 2:
825  if ((p[2] & 0x3f) == 0) {
826  u32 base15 = (p[2] & 0x40) ? get_u16(p + 7) : 0x0008;
827  u16 *p1 = (u16 *)(p + (p[2] & 0x40 ? 9 : 3));
828  mtable->csr15dir = (get_unaligned(p1 + 0)<<16) + base15;
829  mtable->csr15val = (get_unaligned(p1 + 1)<<16) + base15;
830  }
831  /* Fall through. */
832  case 0: case 4:
833  mtable->has_nonmii = 1;
834  leaf->media = p[2] & MEDIA_MASK;
835  switch (leaf->media) {
836  case 0: new_advertise |= 0x0020; break;
837  case 4: new_advertise |= 0x0040; break;
838  case 3: new_advertise |= 0x0080; break;
839  case 5: new_advertise |= 0x0100; break;
840  case 6: new_advertise |= 0x0200; break;
841  }
842  break;
843  default:
844  leaf->media = 19;
845  }
846  leaf->leafdata = p + 2;
847  p += (p[0] & 0x3f) + 1;
848  }
849  if (leaf->media == 11) {
850  unsigned char *bp = leaf->leafdata;
851  DBG2("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %hhX %hhX.\n",
852  tp->nic_name, bp[0], bp[1], bp[2 + bp[1]*2],
853  bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
854  }
855  DBG("%s: Index #%d - Media %s (#%d) described "
856  "by a %s (%d) block.\n",
857  tp->nic_name, i, medianame[leaf->media], leaf->media,
858  leaf->type < 6 ? block_name[leaf->type] : "UNKNOWN",
859  leaf->type);
860  }
861  if (new_advertise)
862  tp->sym_advertise = new_advertise;
863  }
864 }
uint16_t u16
Definition: stdint.h:21
Definition: tulip.c:151
const char * name
Definition: ath9k_hw.c:1984
u32 csr15val
Definition: tulip.c:330
struct medialeaf mleaf[0]
Definition: tulip.c:331
u8 csr12dir
Definition: tulip.c:328
u8 media
Definition: tulip.c:322
static const char * block_name[]
Definition: tulip.c:481
char * name
Definition: tulip.c:448
struct mediatable * mtable
Definition: tulip.c:416
static unsigned char ee_data[EEPROM_SIZE]
Definition: davicom.c:67
uint16_t bp
Definition: registers.h:23
#define MEDIA_MASK
Definition: tulip.c:140
int flags
Definition: tulip.c:400
unsigned has_mii
Definition: tulip.c:329
static void whereami(const char *str)
Definition: tulip.c:513
int chip_id
Definition: tulip.c:397
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned char eeprom[EEPROM_SIZE]
Definition: tulip.c:413
static unsigned int count
Number of entries.
Definition: dwmac.h:225
u8 media_table_storage[(sizeof(struct mediatable)+32 *sizeof(struct medialeaf))]
Definition: tulip.c:414
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
u8 leafcount
Definition: tulip.c:328
#define get_u16(ptr)
Definition: tulip.c:125
u16 defaultmedia
Definition: tulip.c:327
u16 sym_advertise
Definition: tulip.c:415
unsigned char addr2
Definition: tulip.c:449
unsigned has_nonmii
Definition: tulip.c:329
Definition: nic.h:49
static const char *const medianame[32]
Definition: tulip.c:141
unsigned has_reset
Definition: tulip.c:329
static struct fixups eeprom_fixups[]
unsigned char * node_addr
Definition: nic.h:52
static char media[]
Definition: sundance.c:85
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
u32 csr15dir
Definition: tulip.c:330
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
unsigned char addr1
Definition: tulip.c:449
#define get_unaligned(ptr)
Definition: tulip.c:123
unsigned char * leafdata
Definition: tulip.c:323
u8 type
Definition: tulip.c:321
unsigned char addr0
Definition: tulip.c:449
uint32_t u32
Definition: stdint.h:23
#define DBG2(...)
Definition: compiler.h:515

References fixups::addr0, fixups::addr1, fixups::addr2, block_name, bp, tulip_private::chip_id, count, CSR12_IN_SROM, mediatable::csr12dir, mediatable::csr15dir, mediatable::csr15val, DBG, DBG2, DC21041, mediatable::defaultmedia, ee_data, tulip_private::eeprom, eeprom_fixups, tulip_private::flags, get_u16, get_unaligned, mediatable::has_mii, mediatable::has_nonmii, mediatable::has_reset, mediatable::leafcount, medialeaf::leafdata, media, medialeaf::media, MEDIA_MASK, tulip_private::media_table_storage, medianame, memcpy(), mediatable::mleaf, tulip_private::mtable, fixups::name, name, tulip_private::nic_name, nic::node_addr, NULL, tulip_private::sym_advertise, tp, medialeaf::type, and whereami().

Referenced by tulip_probe().

◆ tulip_probe()

static int tulip_probe ( struct nic nic,
struct pci_device pci 
)
static

Definition at line 1174 of file tulip.c.

1174  {
1175 
1176  u32 i;
1177  u8 chip_rev;
1179  unsigned short sum;
1180  int chip_idx;
1181  static unsigned char last_phys_addr[ETH_ALEN] = {0x00, 'L', 'i', 'n', 'u', 'x'};
1182 
1183  if (pci->ioaddr == 0)
1184  return 0;
1185 
1186  ioaddr = pci->ioaddr;
1187  nic->ioaddr = pci->ioaddr & ~3;
1188  nic->irqno = 0;
1189 
1190  /* point to private storage */
1191  tp = &tulip_bss.tpx;
1192 
1193  tp->vendor_id = pci->vendor;
1194  tp->dev_id = pci->device;
1195  tp->nic_name = pci->id->name;
1196 
1197  tp->if_port = 0;
1198  tp->default_port = 0;
1199 
1200  adjust_pci_device(pci);
1201 
1202  /* disable interrupts */
1203  outl(0x00000000, ioaddr + CSR7);
1204 
1205  /* Stop the chip's Tx and Rx processes. */
1206  outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
1207 
1208  /* Clear the missed-packet counter. */
1209  inl(ioaddr + CSR8);
1210 
1211  DBG("\n"); /* so we start on a fresh line */
1212  whereami("tulip_probe\n");
1213 
1214  DBG2 ("%s: Looking for Tulip Chip: Vendor=%hX Device=%hX\n", tp->nic_name,
1215  tp->vendor_id, tp->dev_id);
1216 
1217  /* Figure out which chip we're dealing with */
1218  i = 0;
1219  chip_idx = -1;
1220 
1221  while (pci_id_tbl[i].name) {
1222  if ( (((u32) tp->dev_id << 16) | tp->vendor_id) ==
1223  (pci_id_tbl[i].id.pci & pci_id_tbl[i].id.pci_mask) ) {
1225  break;
1226  }
1227  i++;
1228  }
1229 
1230  if (chip_idx == -1) {
1231  DBG ("%s: Unknown Tulip Chip: Vendor=%hX Device=%hX\n", tp->nic_name,
1232  tp->vendor_id, tp->dev_id);
1233  return 0;
1234  }
1235 
1236  tp->pci_id_idx = i;
1238 
1239  DBG2 ("%s: tp->pci_id_idx == %d, name == %s\n", tp->nic_name,
1241  DBG2 ("%s: chip_idx == %d, name == %s\n", tp->nic_name, chip_idx,
1243 
1244  /* Bring the 21041/21143 out of sleep mode.
1245  Caution: Snooze mode does not work with some boards! */
1246  if (tp->flags & HAS_PWRDWN)
1247  pci_write_config_dword(pci, 0x40, 0x00000000);
1248 
1249  if (inl(ioaddr + CSR5) == 0xFFFFFFFF) {
1250  DBG("%s: The Tulip chip at %X is not functioning.\n",
1251  tp->nic_name, (unsigned int) ioaddr);
1252  return 0;
1253  }
1254 
1255  pci_read_config_byte(pci, PCI_REVISION, &chip_rev);
1256 
1257  DBG("%s: [chip: %s] rev %d at %hX\n", tp->nic_name,
1258  tulip_tbl[chip_idx].chip_name, chip_rev, (unsigned int) ioaddr);
1259  DBG("%s: Vendor=%hX Device=%hX", tp->nic_name, tp->vendor_id, tp->dev_id);
1260 
1261  if (chip_idx == DC21041 && inl(ioaddr + CSR9) & 0x8000) {
1262  DBG(" 21040 compatible mode.");
1263  chip_idx = DC21040;
1264  }
1265 
1266  DBG("\n");
1267 
1268  /* The SROM/EEPROM interface varies dramatically. */
1269  sum = 0;
1270  if (chip_idx == DC21040) {
1271  outl(0, ioaddr + CSR9); /* Reset the pointer with a dummy write. */
1272  for (i = 0; i < ETH_ALEN; i++) {
1273  int value, boguscnt = 100000;
1274  do
1275  value = inl(ioaddr + CSR9);
1276  while (value < 0 && --boguscnt > 0);
1277  nic->node_addr[i] = value;
1278  sum += value & 0xff;
1279  }
1280  } else if (chip_idx == LC82C168) {
1281  for (i = 0; i < 3; i++) {
1282  int value, boguscnt = 100000;
1283  outl(0x600 | i, ioaddr + 0x98);
1284  do
1285  value = inl(ioaddr + CSR9);
1286  while (value < 0 && --boguscnt > 0);
1288  sum += value & 0xffff;
1289  }
1290  } else if (chip_idx == COMET) {
1291  /* No need to read the EEPROM. */
1292  put_unaligned(inl(ioaddr + 0xA4), (u32 *)nic->node_addr);
1293  put_unaligned(inl(ioaddr + 0xA8), (u16 *)(nic->node_addr + 4));
1294  for (i = 0; i < ETH_ALEN; i ++)
1295  sum += nic->node_addr[i];
1296  } else {
1297  /* A serial EEPROM interface, we read now and sort it out later. */
1298  int sa_offset = 0;
1299  int ee_addr_size = read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
1300 
1301  for (i = 0; i < sizeof(ee_data)/2; i++)
1302  ((u16 *)ee_data)[i] =
1303  le16_to_cpu(read_eeprom(ioaddr, i, ee_addr_size));
1304 
1305  /* DEC now has a specification (see Notes) but early board makers
1306  just put the address in the first EEPROM locations. */
1307  /* This does memcmp(eedata, eedata+16, 8) */
1308  for (i = 0; i < 8; i ++)
1309  if (ee_data[i] != ee_data[16+i])
1310  sa_offset = 20;
1311  if (ee_data[0] == 0xff && ee_data[1] == 0xff && ee_data[2] == 0) {
1312  sa_offset = 2; /* Grrr, damn Matrox boards. */
1313  }
1314  for (i = 0; i < ETH_ALEN; i ++) {
1315  nic->node_addr[i] = ee_data[i + sa_offset];
1316  sum += ee_data[i + sa_offset];
1317  }
1318  }
1319  /* Lite-On boards have the address byte-swapped. */
1320  if ((nic->node_addr[0] == 0xA0 || nic->node_addr[0] == 0xC0)
1321  && nic->node_addr[1] == 0x00)
1322  for (i = 0; i < ETH_ALEN; i+=2) {
1323  char tmp = nic->node_addr[i];
1324  nic->node_addr[i] = nic->node_addr[i+1];
1325  nic->node_addr[i+1] = tmp;
1326  }
1327 
1328  if (sum == 0 || sum == ETH_ALEN*0xff) {
1329  DBG("%s: EEPROM not present!\n", tp->nic_name);
1330  for (i = 0; i < ETH_ALEN-1; i++)
1331  nic->node_addr[i] = last_phys_addr[i];
1332  nic->node_addr[i] = last_phys_addr[i] + 1;
1333  }
1334 
1335  for (i = 0; i < ETH_ALEN; i++)
1336  last_phys_addr[i] = nic->node_addr[i];
1337 
1338  DBG ( "%s: %s at ioaddr %hX\n", tp->nic_name, eth_ntoa ( nic->node_addr ),
1339  (unsigned int) ioaddr );
1340 
1341  tp->chip_id = chip_idx;
1342  tp->revision = chip_rev;
1343  tp->csr0 = csr0;
1344 
1345  /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles.
1346  And the ASIX must have a burst limit or horrible things happen. */
1347  if (chip_idx == DC21143 && chip_rev == 65)
1348  tp->csr0 &= ~0x01000000;
1349  else if (tp->flags & IS_ASIX)
1350  tp->csr0 |= 0x2000;
1351 
1352  if (media_cap[tp->default_port] & MediaIsMII) {
1353  static const u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60,
1354  0x80, 0x100, 0x200 };
1355  tp->mii_advertise = media2advert[tp->default_port - 9];
1356  tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */
1357  }
1358 
1359  /* This is logically part of the probe routine, but too complex
1360  to write inline. */
1361  if (tp->flags & HAS_MEDIA_TABLE) {
1362  memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom));
1363  parse_eeprom(nic);
1364  }
1365 
1366  start_link(nic);
1367 
1368  /* reset the device and make ready for tx and rx of packets */
1369  tulip_reset(nic);
1371 
1372  /* give the board a chance to reset before returning */
1374 
1375  return 1;
1376 }
Definition: tulip.c:295
unsigned char irqno
Definition: nic.h:56
uint16_t u16
Definition: stdint.h:21
Definition: tulip.c:151
const char * name
Definition: ath9k_hw.c:1984
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
unsigned short dev_id
Definition: tulip.c:402
int drv_flags
Definition: tulip.c:173
unsigned long ioaddr
I/O address.
Definition: pci.h:225
static int chip_idx
Definition: tlan.c:196
unsigned int default_port
Definition: tulip.c:412
int revision
Definition: tulip.c:399
static struct tulip_chip_table tulip_tbl[]
static const char media_cap[32]
Definition: tulip.c:275
static unsigned char ee_data[EEPROM_SIZE]
Definition: davicom.c:67
static const int csr0
Definition: tulip.c:137
int flags
Definition: tulip.c:400
Definition: tulip.c:152
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition: pci.c:240
Definition: tulip.c:296
char * chip_name
Definition: tulip.c:243
static void whereami(const char *str)
Definition: tulip.c:513
int chip_id
Definition: tulip.c:397
unsigned long tmp
Definition: linux_pci.h:64
unsigned int csr0
Definition: tulip.c:405
static u32 ioaddr
Definition: tulip.c:393
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned int ioaddr
Definition: nic.h:55
uint16_t device
Device ID.
Definition: pci.h:229
const char * name
Definition: tlan.c:110
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
unsigned char eeprom[EEPROM_SIZE]
Definition: tulip.c:413
static void tulip_wait(unsigned int nticks)
Definition: tulip.c:519
#define EEPROM_SIZE
Definition: tulip.c:343
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
static const struct pci_id_info pci_id_tbl[]
Definition: tulip.c:176
Definition: tulip.c:151
unsigned int if_port
Definition: tulip.c:406
#define outl(data, io_addr)
Definition: io.h:329
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:175
#define put_unaligned(val, ptr)
Definition: tulip.c:124
static void tulip_reset(struct nic *nic)
Definition: tulip.c:924
#define ETH_ALEN
Definition: if_ether.h:8
Definition: tulip.c:296
#define le16_to_cpu(value)
Definition: byteswap.h:112
Definition: nic.h:49
const char * name
Name.
Definition: pci.h:176
uint16_t vendor
Vendor ID.
Definition: pci.h:227
struct pci_id_info::match_info id
unsigned char * node_addr
Definition: nic.h:52
static void parse_eeprom(struct nic *nic)
Definition: tulip.c:716
static struct nic_operations tulip_operations
Definition: tulip.c:1163
Definition: tulip.c:296
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
static int read_eeprom(unsigned long ioaddr, int location, int addr_len)
Definition: tulip.c:677
Definition: tulip.c:238
struct pci_device_id * id
Driver device ID.
Definition: pci.h:247
int pci_write_config_dword(struct pci_device *pci, unsigned int where, uint32_t value)
Write 32-bit dword to PCI configuration space.
#define PCI_REVISION
PCI revision.
Definition: pci.h:44
Definition: tulip.c:296
static void start_link(struct nic *nic)
Definition: tulip.c:1378
Definition: tulip.c:151
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
struct tulip_private tpx
Definition: tulip.c:434
struct nic_operations * nic_op
Definition: nic.h:50
u16 mii_advertise
Definition: tulip.c:415
uint8_t u8
Definition: stdint.h:19
int pci_id_idx
Definition: tulip.c:398
unsigned short vendor_id
Definition: tulip.c:401
uint32_t u32
Definition: stdint.h:23
#define DBG2(...)
Definition: compiler.h:515
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.

References adjust_pci_device(), tulip_private::chip_id, chip_idx, tulip_chip_table::chip_name, COMET, csr0, tulip_private::csr0, CSR5, CSR6, CSR7, CSR8, CSR9, DBG, DBG2, DC21040, DC21041, DC21143, tulip_private::default_port, tulip_private::dev_id, pci_device::device, pci_id_info::drv_flags, ee_data, tulip_private::eeprom, EEPROM_SIZE, ETH_ALEN, eth_ntoa(), tulip_chip_table::flags, tulip_private::flags, HAS_8023X, HAS_MEDIA_TABLE, HAS_PWRDWN, pci_id_info::id, pci_device::id, tulip_private::if_port, inl(), nic::ioaddr, pci_device::ioaddr, ioaddr, nic::irqno, IS_ASIX, LC82C168, le16_to_cpu, media_cap, MediaIsMII, memcpy(), tulip_private::mii_advertise, pci_id_info::name, pci_device_id::name, name, tulip_private::nic_name, nic::nic_op, nic::node_addr, outl, parse_eeprom(), pci_id_info::match_info::pci, tulip_private::pci_id_idx, pci_id_tbl, pci_id_info::match_info::pci_mask, pci_read_config_byte(), PCI_REVISION, pci_write_config_dword(), put_unaligned, read_eeprom(), tulip_private::revision, start_link(), TICKS_PER_SEC, tmp, tp, tulip_bss::tpx, tulip_operations, tulip_reset(), tulip_tbl, tulip_wait(), value, pci_device::vendor, tulip_private::vendor_id, and whereami().

◆ tulip_init_ring() [1/2]

static void tulip_init_ring ( struct nic nic)
static

Referenced by tulip_reset().

◆ tulip_reset()

static void tulip_reset ( struct nic nic)
static

Definition at line 924 of file tulip.c.

925 {
926  int i;
927  unsigned long to;
928 
929  whereami("tulip_reset\n");
930 
931  /* Stop Tx and RX */
932  outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
933 
934  /* On some chip revs we must set the MII/SYM port before the reset!? */
935  if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii)) {
936  outl(0x814C0000, ioaddr + CSR6);
937  }
938 
939  /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
940  outl(0x00000001, ioaddr + CSR0);
941  tulip_wait(1);
942 
943  /* turn off reset and set cache align=16lword, burst=unlimit */
944  outl(tp->csr0, ioaddr + CSR0);
945 
946  /* Wait the specified 50 PCI cycles after a reset */
947  tulip_wait(1);
948 
949  /* set up transmit and receive descriptors */
951 
952  if (tp->chip_id == PNIC2) {
953  u32 addr_high = (nic->node_addr[1]<<8) + (nic->node_addr[0]<<0);
954  /* This address setting does not appear to impact chip operation?? */
955  outl((nic->node_addr[5]<<8) + nic->node_addr[4] +
956  (nic->node_addr[3]<<24) + (nic->node_addr[2]<<16),
957  ioaddr + 0xB0);
958  outl(addr_high + (addr_high<<16), ioaddr + 0xB8);
959  }
960 
961  /* MC_HASH_ONLY boards don't support setup packets */
962  if (tp->flags & MC_HASH_ONLY) {
963  u32 addr_low = cpu_to_le32(get_unaligned((u32 *)nic->node_addr));
964  u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(nic->node_addr+4)));
965 
966  /* clear multicast hash filters and setup MAC address filters */
967  if (tp->flags & IS_ASIX) {
968  outl(0, ioaddr + CSR13);
969  outl(addr_low, ioaddr + CSR14);
970  outl(1, ioaddr + CSR13);
971  outl(addr_high, ioaddr + CSR14);
972  outl(2, ioaddr + CSR13);
973  outl(0, ioaddr + CSR14);
974  outl(3, ioaddr + CSR13);
975  outl(0, ioaddr + CSR14);
976  } else if (tp->chip_id == COMET) {
977  outl(addr_low, ioaddr + 0xA4);
978  outl(addr_high, ioaddr + 0xA8);
979  outl(0, ioaddr + 0xAC);
980  outl(0, ioaddr + 0xB0);
981  }
982  } else {
983  /* for other boards we send a setup packet to initialize
984  the filters */
985  u32 tx_flags = 0x08000000 | 192;
986 
987  /* construct perfect filter frame with mac address as first match
988  and broadcast address for all others */
989  for (i=0; i<192; i++)
990  txb[i] = 0xFF;
991  txb[0] = nic->node_addr[0];
992  txb[1] = nic->node_addr[1];
993  txb[4] = nic->node_addr[2];
994  txb[5] = nic->node_addr[3];
995  txb[8] = nic->node_addr[4];
996  txb[9] = nic->node_addr[5];
997 
998  tx_ring[0].length = cpu_to_le32(tx_flags);
999  tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]);
1000  tx_ring[0].status = cpu_to_le32(0x80000000);
1001  }
1002 
1003  /* Point to rx and tx descriptors */
1006 
1007  init_media(nic);
1008 
1009  /* set the chip's operating mode (but don't turn on xmit and recv yet) */
1010  outl((tp->csr6 & ~0x00002002), ioaddr + CSR6);
1011 
1012  /* send setup packet for cards that support it */
1013  if (!(tp->flags & MC_HASH_ONLY)) {
1014  /* enable transmit wait for completion */
1015  outl(tp->csr6 | 0x00002000, ioaddr + CSR6);
1016  /* immediate transmit demand */
1017  outl(0, ioaddr + CSR1);
1018 
1019  to = currticks() + TX_TIME_OUT;
1020  while ((tx_ring[0].status & 0x80000000) && (currticks() < to))
1021  /* wait */ ;
1022 
1023  if (currticks() >= to) {
1024  DBG ("%s: TX Setup Timeout.\n", tp->nic_name);
1025  }
1026  }
1027 
1028  if (tp->chip_id == LC82C168)
1030 
1031  set_rx_mode(nic);
1032 
1033  /* enable transmit and receive */
1034  outl(tp->csr6 | 0x00002002, ioaddr + CSR6);
1035 }
uint16_t u16
Definition: stdint.h:21
Definition: tulip.c:295
Definition: tulip.c:295
struct mediatable * mtable
Definition: tulip.c:416
int flags
Definition: tulip.c:400
unsigned has_mii
Definition: tulip.c:329
Definition: tulip.c:152
static void whereami(const char *str)
Definition: tulip.c:513
int chip_id
Definition: tulip.c:397
unsigned int csr0
Definition: tulip.c:405
static u32 ioaddr
Definition: tulip.c:393
Definition: tulip.c:295
static void tulip_wait(unsigned int nticks)
Definition: tulip.c:519
static int tulip_check_duplex(struct nic *nic)
Definition: tulip.c:1875
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
#define cpu_to_le32(value)
Definition: byteswap.h:107
Definition: tulip.c:152
#define outl(data, io_addr)
Definition: io.h:329
#define TX_TIME_OUT
Definition: tulip.c:119
Definition: nic.h:49
Definition: tulip.c:295
uint8_t status
Status.
Definition: ena.h:16
Definition: tulip.c:297
unsigned char * node_addr
Definition: nic.h:52
Definition: tulip.c:297
#define virt_to_le32desc(addr)
Definition: tulip.c:126
Definition: tulip.c:296
#define rx_ring
Definition: tulip.c:439
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
Definition: tulip.c:238
static void set_rx_mode(struct nic *nic __unused)
Definition: tulip.c:906
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
signed char mii_cnt
Definition: tulip.c:419
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
unsigned int csr6
Definition: tulip.c:405
static void tulip_init_ring(struct nic *nic)
#define txb
Definition: tulip.c:438
#define tx_ring
Definition: tulip.c:437
#define get_unaligned(ptr)
Definition: tulip.c:123
uint32_t u32
Definition: stdint.h:23
static void init_media(struct nic *nic)
Definition: tulip.c:1526

References tulip_private::chip_id, COMET, cpu_to_le32, CSR0, tulip_private::csr0, CSR1, CSR13, CSR14, CSR3, CSR4, CSR6, tulip_private::csr6, currticks(), DBG, tulip_private::flags, get_unaligned, mediatable::has_mii, init_media(), inl(), ioaddr, IS_ASIX, LC82C168, MC_HASH_ONLY, tulip_private::mii_cnt, tulip_private::mtable, tulip_private::nic_name, nic::node_addr, outl, PNIC2, rx_ring, set_rx_mode(), status, tp, tulip_check_duplex(), tulip_init_ring(), tulip_wait(), tx_ring, TX_TIME_OUT, txb, virt_to_le32desc, and whereami().

Referenced by tulip_disable(), and tulip_probe().

◆ tulip_transmit()

static void tulip_transmit ( struct nic nic,
const char *  d,
unsigned int  t,
unsigned int  s,
const char *  p 
)
static

Definition at line 1041 of file tulip.c.

1043 {
1044  u16 nstype;
1045  u32 to;
1046  u32 csr6 = inl(ioaddr + CSR6);
1047 
1048  whereami("tulip_transmit\n");
1049 
1050  /* Disable Tx */
1051  outl(csr6 & ~0x00002000, ioaddr + CSR6);
1052 
1053  memcpy(txb, d, ETH_ALEN);
1055  nstype = htons((u16) t);
1056  memcpy(txb + 2 * ETH_ALEN, (u8 *)&nstype, 2);
1057  memcpy(txb + ETH_HLEN, p, s);
1058 
1059  s += ETH_HLEN;
1060  s &= 0x0FFF;
1061 
1062  /* pad to minimum packet size */
1063  while (s < ETH_ZLEN)
1064  txb[s++] = '\0';
1065 
1066  DBG2("%s: sending %d bytes ethtype %hX\n", tp->nic_name, s, t);
1067 
1068  /* setup the transmit descriptor */
1069  /* 0x60000000 = no interrupt on completion */
1070  tx_ring[0].length = cpu_to_le32(0x60000000 | s);
1071  tx_ring[0].status = cpu_to_le32(0x80000000);
1072 
1073  /* Point to transmit descriptor */
1075 
1076  /* Enable Tx */
1077  outl(csr6 | 0x00002000, ioaddr + CSR6);
1078  /* immediate transmit demand */
1079  outl(0, ioaddr + CSR1);
1080 
1081  to = currticks() + TX_TIME_OUT;
1082  while ((tx_ring[0].status & 0x80000000) && (currticks() < to))
1083  /* wait */ ;
1084 
1085  if (currticks() >= to) {
1086  DBG ("TX Timeout!\n");
1087  }
1088 
1089  /* Disable Tx */
1090  outl(csr6 & ~0x00002000, ioaddr + CSR6);
1091 }
uint16_t u16
Definition: stdint.h:21
Definition: tulip.c:295
Definition: tulip.c:295
static void whereami(const char *str)
Definition: tulip.c:513
static u32 ioaddr
Definition: tulip.c:393
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define ETH_HLEN
Definition: if_ether.h:9
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define outl(data, io_addr)
Definition: io.h:329
#define TX_TIME_OUT
Definition: tulip.c:119
#define ETH_ALEN
Definition: if_ether.h:8
#define ETH_ZLEN
Definition: if_ether.h:10
Definition: nic.h:49
uint8_t status
Status.
Definition: ena.h:16
unsigned char * node_addr
Definition: nic.h:52
#define virt_to_le32desc(addr)
Definition: tulip.c:126
Definition: tulip.c:296
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define txb
Definition: tulip.c:438
#define tx_ring
Definition: tulip.c:437
#define htons(value)
Definition: byteswap.h:135
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23
#define DBG2(...)
Definition: compiler.h:515

References cpu_to_le32, CSR1, CSR4, CSR6, currticks(), DBG, DBG2, ETH_ALEN, ETH_HLEN, ETH_ZLEN, htons, inl(), ioaddr, memcpy(), tulip_private::nic_name, nic::node_addr, outl, status, tp, tx_ring, TX_TIME_OUT, txb, virt_to_le32desc, and whereami().

◆ tulip_poll()

static int tulip_poll ( struct nic nic,
int  retrieve 
)
static

Definition at line 1096 of file tulip.c.

1097 {
1098 
1099  whereami("tulip_poll\n");
1100 
1101  /* no packet waiting. packet still owned by NIC */
1102  if (rx_ring[tp->cur_rx].status & 0x80000000)
1103  return 0;
1104 
1105  if ( ! retrieve ) return 1;
1106 
1107  whereami("tulip_poll got one\n");
1108 
1109  nic->packetlen = (rx_ring[tp->cur_rx].status & 0x3FFF0000) >> 16;
1110 
1111  /* if we get a corrupted packet. throw it away and move on */
1112  if (rx_ring[tp->cur_rx].status & 0x00008000) {
1113  /* return the descriptor and buffer to receive ring */
1114  rx_ring[tp->cur_rx].status = 0x80000000;
1115  tp->cur_rx = (tp->cur_rx + 1) % RX_RING_SIZE;
1116  return 0;
1117  }
1118 
1119  /* copy packet to working buffer */
1121 
1122  /* return the descriptor and buffer to receive ring */
1123  rx_ring[tp->cur_rx].status = 0x80000000;
1124  tp->cur_rx = (tp->cur_rx + 1) % RX_RING_SIZE;
1125 
1126  return 1;
1127 }
#define BUFLEN
Definition: tulip.c:365
#define rxb
Definition: tulip.c:440
static void whereami(const char *str)
Definition: tulip.c:513
#define RX_RING_SIZE
Definition: tulip.c:428
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static struct tulip_private * tp
Definition: tulip.c:442
unsigned int packetlen
Definition: nic.h:54
Definition: nic.h:49
unsigned char * packet
Definition: nic.h:53
#define rx_ring
Definition: tulip.c:439
int cur_rx
Definition: tulip.c:396

References BUFLEN, tulip_private::cur_rx, memcpy(), nic::packet, nic::packetlen, rx_ring, RX_RING_SIZE, rxb, tp, and whereami().

◆ tulip_disable() [1/2]

static void tulip_disable ( struct nic nic,
void *  hwdev 
)
static

◆ nway_start() [1/2]

static void nway_start ( struct nic nic)
static

Referenced by init_media(), and start_link().

◆ pnic_do_nway() [1/2]

static void pnic_do_nway ( struct nic nic)
static

Referenced by init_media().

◆ select_media()

static void select_media ( struct nic nic,
int  startup 
)
static

Definition at line 1673 of file tulip.c.

1674 {
1675  struct mediatable *mtable = tp->mtable;
1676  u32 new_csr6;
1677  int i;
1678 
1679  whereami("select_media\n");
1680 
1681  if (mtable) {
1682  struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index];
1683  unsigned char *p = mleaf->leafdata;
1684  switch (mleaf->type) {
1685  case 0: /* 21140 non-MII xcvr. */
1686  DBG2("%s: Using a 21140 non-MII transceiver"
1687  " with control setting %hhX.\n",
1688  tp->nic_name, p[1]);
1689  tp->if_port = p[0];
1690  if (startup)
1691  outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
1692  outl(p[1], ioaddr + CSR12);
1693  new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
1694  break;
1695  case 2: case 4: {
1696  u16 setup[5];
1697  u32 csr13val, csr14val, csr15dir, csr15val;
1698  for (i = 0; i < 5; i++)
1699  setup[i] = get_u16(&p[i*2 + 1]);
1700 
1701  tp->if_port = p[0] & 15;
1703  tp->full_duplex = 1;
1704 
1705  if (startup && mtable->has_reset) {
1706  struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
1707  unsigned char *rst = rleaf->leafdata;
1708  DBG2("%s: Resetting the transceiver.\n",
1709  tp->nic_name);
1710  for (i = 0; i < rst[0]; i++)
1711  outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
1712  }
1713  DBG2("%s: 21143 non-MII %s transceiver control %hX/%hX.\n",
1714  tp->nic_name, medianame[tp->if_port], setup[0], setup[1]);
1715  if (p[0] & 0x40) { /* SIA (CSR13-15) setup values are provided. */
1716  csr13val = setup[0];
1717  csr14val = setup[1];
1718  csr15dir = (setup[3]<<16) | setup[2];
1719  csr15val = (setup[4]<<16) | setup[2];
1720  outl(0, ioaddr + CSR13);
1721  outl(csr14val, ioaddr + CSR14);
1722  outl(csr15dir, ioaddr + CSR15); /* Direction */
1723  outl(csr15val, ioaddr + CSR15); /* Data */
1724  outl(csr13val, ioaddr + CSR13);
1725  } else {
1726  csr13val = 1;
1727  csr14val = 0x0003FF7F;
1728  csr15dir = (setup[0]<<16) | 0x0008;
1729  csr15val = (setup[1]<<16) | 0x0008;
1730  if (tp->if_port <= 4)
1731  csr14val = t21142_csr14[tp->if_port];
1732  if (startup) {
1733  outl(0, ioaddr + CSR13);
1734  outl(csr14val, ioaddr + CSR14);
1735  }
1736  outl(csr15dir, ioaddr + CSR15); /* Direction */
1737  outl(csr15val, ioaddr + CSR15); /* Data */
1738  if (startup) outl(csr13val, ioaddr + CSR13);
1739  }
1740  DBG2("%s: Setting CSR15 to %X/%X.\n",
1741  tp->nic_name, csr15dir, csr15val);
1742  if (mleaf->type == 4)
1743  new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
1744  else
1745  new_csr6 = 0x82420000;
1746  break;
1747  }
1748  case 1: case 3: {
1749  int phy_num = p[0];
1750  int init_length = p[1];
1751  u16 *misc_info;
1752 
1753  tp->if_port = 11;
1754  new_csr6 = 0x020E0000;
1755  if (mleaf->type == 3) { /* 21142 */
1756  u16 *init_sequence = (u16*)(p+2);
1757  u16 *reset_sequence = &((u16*)(p+3))[init_length];
1758  int reset_length = p[2 + init_length*2];
1759  misc_info = reset_sequence + reset_length;
1760  if (startup)
1761  for (i = 0; i < reset_length; i++)
1762  outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
1763  for (i = 0; i < init_length; i++)
1764  outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
1765  } else {
1766  u8 *init_sequence = p + 2;
1767  u8 *reset_sequence = p + 3 + init_length;
1768  int reset_length = p[2 + init_length];
1769  misc_info = (u16*)(reset_sequence + reset_length);
1770  if (startup) {
1771  outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
1772  for (i = 0; i < reset_length; i++)
1773  outl(reset_sequence[i], ioaddr + CSR12);
1774  }
1775  for (i = 0; i < init_length; i++)
1776  outl(init_sequence[i], ioaddr + CSR12);
1777  }
1778  tp->advertising[phy_num] = get_u16(&misc_info[1]) | 1;
1779  if (startup < 2) {
1780  if (tp->mii_advertise == 0)
1781  tp->mii_advertise = tp->advertising[phy_num];
1782  DBG2("%s: Advertising %hX on MII %d.\n",
1783  tp->nic_name, tp->mii_advertise, tp->phys[phy_num]);
1784  mdio_write(nic, tp->phys[phy_num], 4, tp->mii_advertise);
1785  }
1786  break;
1787  }
1788  default:
1789  DBG("%s: Invalid media table selection %d.\n",
1790  tp->nic_name, mleaf->type);
1791  new_csr6 = 0x020E0000;
1792  }
1793  DBG2("%s: Using media type %s, CSR12 is %hhX.\n",
1795  inl(ioaddr + CSR12) & 0xff);
1796  } else if (tp->chip_id == DC21041) {
1797  int port = tp->if_port <= 4 ? tp->if_port : 0;
1798  DBG2("%s: 21041 using media %s, CSR12 is %hX.\n",
1799  tp->nic_name, medianame[port == 3 ? 12: port],
1800  inl(ioaddr + CSR12));
1801  outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
1805  new_csr6 = 0x80020000;
1806  } else if (tp->chip_id == LC82C168) {
1807  if (startup && ! tp->medialock)
1808  tp->if_port = tp->mii_cnt ? 11 : 0;
1809  DBG2("%s: PNIC PHY status is %hX, media %s.\n",
1810  tp->nic_name, inl(ioaddr + 0xB8), medianame[tp->if_port]);
1811  if (tp->mii_cnt) {
1812  new_csr6 = 0x810C0000;
1813  outl(0x0001, ioaddr + CSR15);
1814  outl(0x0201B07A, ioaddr + 0xB8);
1815  } else if (startup) {
1816  /* Start with 10mbps to do autonegotiation. */
1817  outl(0x32, ioaddr + CSR12);
1818  new_csr6 = 0x00420000;
1819  outl(0x0001B078, ioaddr + 0xB8);
1820  outl(0x0201B078, ioaddr + 0xB8);
1821  } else if (tp->if_port == 3 || tp->if_port == 5) {
1822  outl(0x33, ioaddr + CSR12);
1823  new_csr6 = 0x01860000;
1824  /* Trigger autonegotiation. */
1825  outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8);
1826  } else {
1827  outl(0x32, ioaddr + CSR12);
1828  new_csr6 = 0x00420000;
1829  outl(0x1F078, ioaddr + 0xB8);
1830  }
1831  } else if (tp->chip_id == DC21040) { /* 21040 */
1832  /* Turn on the xcvr interface. */
1833  int csr12 = inl(ioaddr + CSR12);
1834  DBG2("%s: 21040 media type is %s, CSR12 is %hhX.\n",
1835  tp->nic_name, medianame[tp->if_port], csr12);
1837  tp->full_duplex = 1;
1838  new_csr6 = 0x20000;
1839  /* Set the full duplux match frame. */
1841  outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
1842  if (t21040_csr13[tp->if_port] & 8) {
1843  outl(0x0705, ioaddr + CSR14);
1844  outl(0x0006, ioaddr + CSR15);
1845  } else {
1846  outl(0xffff, ioaddr + CSR14);
1847  outl(0x0000, ioaddr + CSR15);
1848  }
1849  outl(0x8f01 | t21040_csr13[tp->if_port], ioaddr + CSR13);
1850  } else { /* Unknown chip type with no media table. */
1851  if (tp->default_port == 0)
1852  tp->if_port = tp->mii_cnt ? 11 : 3;
1853  if (media_cap[tp->if_port] & MediaIsMII) {
1854  new_csr6 = 0x020E0000;
1855  } else if (media_cap[tp->if_port] & MediaIsFx) {
1856  new_csr6 = 0x028600000;
1857  } else
1858  new_csr6 = 0x038600000;
1859  DBG2("%s: No media description table, assuming "
1860  "%s transceiver, CSR12 %hhX.\n",
1862  inl(ioaddr + CSR12));
1863  }
1864 
1865  tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
1866  return;
1867 }
uint16_t u16
Definition: stdint.h:21
Definition: tulip.c:151
static u8 t21040_csr13[]
Definition: tulip.c:277
struct medialeaf mleaf[0]
Definition: tulip.c:331
u8 csr12dir
Definition: tulip.c:328
unsigned int default_port
Definition: tulip.c:412
struct mediatable * mtable
Definition: tulip.c:416
static const char media_cap[32]
Definition: tulip.c:275
static u16 t21041_csr14[]
Definition: tulip.c:281
static u16 t21041_csr15[]
Definition: tulip.c:282
u16 advertising[4]
Definition: tulip.c:418
static void whereami(const char *str)
Definition: tulip.c:513
#define FULL_DUPLEX_MAGIC
Definition: tulip.c:135
int chip_id
Definition: tulip.c:397
static u32 ioaddr
Definition: tulip.c:393
u8 port
Port number.
Definition: CIB_PRM.h:31
static u16 t21041_csr13[]
Definition: tulip.c:280
Definition: tulip.c:296
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
static void mdio_write(struct nic *nic, int phy_id, int location, int value)
Definition: tulip.c:151
#define get_u16(ptr)
Definition: tulip.c:125
unsigned int if_port
Definition: tulip.c:406
#define outl(data, io_addr)
Definition: io.h:329
Definition: nic.h:49
static const char *const medianame[32]
Definition: tulip.c:141
unsigned has_reset
Definition: tulip.c:329
Definition: tulip.c:297
Definition: tulip.c:297
unsigned int full_duplex
Definition: tulip.c:407
int cur_index
Definition: tulip.c:420
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
signed char phys[4]
Definition: tulip.c:419
unsigned int medialock
Definition: tulip.c:409
signed char mii_cnt
Definition: tulip.c:419
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
unsigned int csr6
Definition: tulip.c:405
static u16 t21142_csr14[]
Definition: tulip.c:287
u16 mii_advertise
Definition: tulip.c:415
unsigned char * leafdata
Definition: tulip.c:323
u8 type
Definition: tulip.c:321
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23
void startup(void)
Start up iPXE.
Definition: init.c:69
#define DBG2(...)
Definition: compiler.h:515
Definition: tulip.c:297
Definition: tulip.c:297

References tulip_private::advertising, tulip_private::chip_id, CSR11, CSR12, mediatable::csr12dir, CSR13, CSR14, CSR15, tulip_private::csr6, tulip_private::cur_index, DBG, DBG2, DC21040, DC21041, tulip_private::default_port, tulip_private::full_duplex, FULL_DUPLEX_MAGIC, get_u16, mediatable::has_reset, tulip_private::if_port, inl(), ioaddr, LC82C168, medialeaf::leafdata, mdio_write(), media_cap, MediaAlwaysFD, MediaIsFx, MediaIsMII, tulip_private::medialock, medianame, tulip_private::mii_advertise, tulip_private::mii_cnt, mediatable::mleaf, tulip_private::mtable, tulip_private::nic_name, outl, tulip_private::phys, port, startup(), t21040_csr13, t21041_csr13, t21041_csr14, t21041_csr15, t21142_csr14, tp, medialeaf::type, and whereami().

Referenced by init_media(), and start_link().

◆ init_media()

static void init_media ( struct nic nic)
static

Definition at line 1526 of file tulip.c.

1527 {
1528  int i;
1529 
1530  whereami("init_media\n");
1531 
1532  tp->saved_if_port = tp->if_port;
1533  if (tp->if_port == 0)
1534  tp->if_port = tp->default_port;
1535 
1536  /* Allow selecting a default media. */
1537  i = 0;
1538  if (tp->mtable == NULL)
1539  goto media_picked;
1540  if (tp->if_port) {
1541  int looking_for = media_cap[tp->if_port] & MediaIsMII ? 11 :
1542  (tp->if_port == 12 ? 0 : tp->if_port);
1543  for (i = 0; i < tp->mtable->leafcount; i++)
1544  if (tp->mtable->mleaf[i].media == looking_for) {
1545  DBG("%s: Using user-specified media %s.\n",
1547  goto media_picked;
1548  }
1549  }
1550  if ((tp->mtable->defaultmedia & 0x0800) == 0) {
1551  int looking_for = tp->mtable->defaultmedia & 15;
1552  for (i = 0; i < tp->mtable->leafcount; i++)
1553  if (tp->mtable->mleaf[i].media == looking_for) {
1554  DBG("%s: Using EEPROM-set media %s.\n",
1555  tp->nic_name, medianame[looking_for]);
1556  goto media_picked;
1557  }
1558  }
1559  /* Start sensing first non-full-duplex media. */
1560  for (i = tp->mtable->leafcount - 1;
1561  (media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--)
1562  ;
1563  media_picked:
1564 
1565  tp->csr6 = 0;
1566  tp->cur_index = i;
1567  tp->nwayset = 0;
1568 
1569  if (tp->if_port) {
1570  if (tp->chip_id == DC21143 && media_cap[tp->if_port] & MediaIsMII) {
1571  /* We must reset the media CSRs when we force-select MII mode. */
1572  outl(0x0000, ioaddr + CSR13);
1573  outl(0x0000, ioaddr + CSR14);
1574  outl(0x0008, ioaddr + CSR15);
1575  }
1576  select_media(nic, 1);
1577  return;
1578  }
1579  switch(tp->chip_id) {
1580  case DC21041:
1581  /* tp->nway = 1;*/
1582  nway_start(nic);
1583  break;
1584  case DC21142:
1585  if (tp->mii_cnt) {
1586  select_media(nic, 1);
1587  DBG2("%s: Using MII transceiver %d, status %hX.\n",
1588  tp->nic_name, tp->phys[0], mdio_read(nic, tp->phys[0], 1));
1589  outl(0x82020000, ioaddr + CSR6);
1590  tp->csr6 = 0x820E0000;
1591  tp->if_port = 11;
1592  outl(0x0000, ioaddr + CSR13);
1593  outl(0x0000, ioaddr + CSR14);
1594  } else
1595  nway_start(nic);
1596  break;
1597  case PNIC2:
1598  nway_start(nic);
1599  break;
1600  case LC82C168:
1601  if (tp->mii_cnt) {
1602  tp->if_port = 11;
1603  tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0);
1604  outl(0x0001, ioaddr + CSR15);
1605  } else if (inl(ioaddr + CSR5) & TPLnkPass)
1606  pnic_do_nway(nic);
1607  else {
1608  /* Start with 10mbps to do autonegotiation. */
1609  outl(0x32, ioaddr + CSR12);
1610  tp->csr6 = 0x00420000;
1611  outl(0x0001B078, ioaddr + 0xB8);
1612  outl(0x0201B078, ioaddr + 0xB8);
1613  }
1614  break;
1615  case MX98713: case COMPEX9881:
1616  tp->if_port = 0;
1617  tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
1618  outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
1619  break;
1620  case MX98715: case MX98725:
1621  /* Provided by BOLO, Macronix - 12/10/1998. */
1622  tp->if_port = 0;
1623  tp->csr6 = 0x01a80200;
1624  outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
1625  outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
1626  break;
1627  case COMET:
1628  /* Enable automatic Tx underrun recovery */
1629  outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88);
1630  tp->if_port = 0;
1631  tp->csr6 = 0x00040000;
1632  break;
1633  case AX88140: case AX88141:
1634  tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100;
1635  break;
1636  default:
1637  select_media(nic, 1);
1638  }
1639 }
Definition: tulip.c:295
Definition: tulip.c:151
struct medialeaf mleaf[0]
Definition: tulip.c:331
uint16_t inw(volatile uint16_t *io_addr)
Read 16-bit word from I/O-mapped device.
u8 media
Definition: tulip.c:322
Definition: tulip.c:152
Definition: tulip.c:152
static int mdio_read(struct nic *nic, int phy_id, int location)
static void select_media(struct nic *nic, int startup)
Definition: tulip.c:1673
static void nway_start(struct nic *nic)
unsigned int default_port
Definition: tulip.c:412
struct mediatable * mtable
Definition: tulip.c:416
static const char media_cap[32]
Definition: tulip.c:275
Definition: tulip.c:152
Definition: tulip.c:152
static void whereami(const char *str)
Definition: tulip.c:513
int saved_if_port
Definition: tulip.c:421
int chip_id
Definition: tulip.c:397
Definition: tulip.c:152
Definition: tulip.c:151
static u32 ioaddr
Definition: tulip.c:393
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
static void pnic_do_nway(struct nic *nic)
u8 leafcount
Definition: tulip.c:328
unsigned int if_port
Definition: tulip.c:406
Definition: tulip.c:152
#define outl(data, io_addr)
Definition: io.h:329
u16 defaultmedia
Definition: tulip.c:327
Definition: nic.h:49
static const char *const medianame[32]
Definition: tulip.c:141
Definition: tulip.c:297
Definition: tulip.c:297
Definition: tulip.c:296
unsigned int full_duplex
Definition: tulip.c:407
int cur_index
Definition: tulip.c:420
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
signed char phys[4]
Definition: tulip.c:419
unsigned int nwayset
Definition: tulip.c:411
Definition: tulip.c:152
Definition: tulip.c:151
signed char mii_cnt
Definition: tulip.c:419
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
unsigned int csr6
Definition: tulip.c:405
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define DBG2(...)
Definition: compiler.h:515
Definition: tulip.c:297
Definition: tulip.c:297

References AX88140, AX88141, tulip_private::chip_id, COMET, COMPEX9881, CSR12, CSR13, CSR14, CSR15, CSR5, CSR6, tulip_private::csr6, tulip_private::cur_index, DBG, DBG2, DC21041, DC21142, DC21143, tulip_private::default_port, mediatable::defaultmedia, tulip_private::full_duplex, tulip_private::if_port, inl(), inw(), ioaddr, LC82C168, mediatable::leafcount, mdio_read(), medialeaf::media, media_cap, MediaAlwaysFD, MediaIsMII, medianame, tulip_private::mii_cnt, mediatable::mleaf, tulip_private::mtable, MX98713, MX98715, MX98725, tulip_private::nic_name, NULL, nway_start(), tulip_private::nwayset, outl, tulip_private::phys, PNIC2, pnic_do_nway(), tulip_private::saved_if_port, select_media(), tp, TPLnkPass, and whereami().

Referenced by tulip_reset().

◆ start_link()

static void start_link ( struct nic nic)
static

Definition at line 1378 of file tulip.c.

1379 {
1380  int i;
1381 
1382  whereami("start_link\n");
1383 
1384  if ((tp->flags & ALWAYS_CHECK_MII) ||
1385  (tp->mtable && tp->mtable->has_mii) ||
1386  ( ! tp->mtable && (tp->flags & HAS_MII))) {
1387  unsigned int phy, phy_idx;
1388  if (tp->mtable && tp->mtable->has_mii) {
1389  for (i = 0; i < tp->mtable->leafcount; i++)
1390  if (tp->mtable->mleaf[i].media == 11) {
1391  tp->cur_index = i;
1392  tp->saved_if_port = tp->if_port;
1393  select_media(nic, 2);
1394  tp->if_port = tp->saved_if_port;
1395  break;
1396  }
1397  }
1398 
1399  /* Find the connected MII xcvrs. */
1400  for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
1401  phy++) {
1402  int mii_status = mdio_read(nic, phy, 1);
1403  if ((mii_status & 0x8301) == 0x8001 ||
1404  ((mii_status & 0x8000) == 0 && (mii_status & 0x7800) != 0)) {
1405  int mii_reg0 = mdio_read(nic, phy, 0);
1406  int mii_advert = mdio_read(nic, phy, 4);
1407  int to_advert;
1408 
1409  if (tp->mii_advertise)
1410  to_advert = tp->mii_advertise;
1411  else if (tp->advertising[phy_idx])
1412  to_advert = tp->advertising[phy_idx];
1413  else /* Leave unchanged. */
1414  tp->mii_advertise = to_advert = mii_advert;
1415 
1416  tp->phys[phy_idx++] = phy;
1417  DBG("%s: MII transceiver %d config %hX status %hX advertising %hX.\n",
1418  tp->nic_name, phy, mii_reg0, mii_status, mii_advert);
1419  /* Fixup for DLink with miswired PHY. */
1420  if (mii_advert != to_advert) {
1421  DBG("%s: Advertising %hX on PHY %d previously advertising %hX.\n",
1422  tp->nic_name, to_advert, phy, mii_advert);
1423  mdio_write(nic, phy, 4, to_advert);
1424  }
1425  /* Enable autonegotiation: some boards default to off. */
1426  mdio_write(nic, phy, 0, mii_reg0 |
1427  (tp->full_duplex ? 0x1100 : 0x1000) |
1428  (media_cap[tp->default_port]&MediaIs100 ? 0x2000:0));
1429  }
1430  }
1431  tp->mii_cnt = phy_idx;
1432  if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) {
1433  DBG("%s: ***WARNING***: No MII transceiver found!\n",
1434  tp->nic_name);
1435  tp->phys[0] = 1;
1436  }
1437  }
1438 
1439  /* Reset the xcvr interface and turn on heartbeat. */
1440  switch (tp->chip_id) {
1441  case DC21040:
1442  outl(0x00000000, ioaddr + CSR13);
1443  outl(0x00000004, ioaddr + CSR13);
1444  break;
1445  case DC21041:
1446  /* This is nway_start(). */
1447  if (tp->sym_advertise == 0)
1448  tp->sym_advertise = 0x0061;
1449  outl(0x00000000, ioaddr + CSR13);
1450  outl(0xFFFFFFFF, ioaddr + CSR14);
1451  outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */
1452  outl(inl(ioaddr + CSR6) | 0x0200, ioaddr + CSR6);
1453  outl(0x0000EF01, ioaddr + CSR13);
1454  break;
1455  case DC21140: default:
1456  if (tp->mtable)
1457  outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
1458  break;
1459  case DC21142:
1460  case PNIC2:
1461  if (tp->mii_cnt || media_cap[tp->if_port] & MediaIsMII) {
1462  outl(0x82020000, ioaddr + CSR6);
1463  outl(0x0000, ioaddr + CSR13);
1464  outl(0x0000, ioaddr + CSR14);
1465  outl(0x820E0000, ioaddr + CSR6);
1466  } else
1467  nway_start(nic);
1468  break;
1469  case LC82C168:
1470  if ( ! tp->mii_cnt) {
1471  tp->nway = 1;
1472  tp->nwayset = 0;
1473  outl(0x00420000, ioaddr + CSR6);
1474  outl(0x30, ioaddr + CSR12);
1475  outl(0x0001F078, ioaddr + 0xB8);
1476  outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
1477  }
1478  break;
1479  case MX98713: case COMPEX9881:
1480  outl(0x00000000, ioaddr + CSR6);
1481  outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
1482  outl(0x00000001, ioaddr + CSR13);
1483  break;
1484  case MX98715: case MX98725:
1485  outl(0x01a80000, ioaddr + CSR6);
1486  outl(0xFFFFFFFF, ioaddr + CSR14);
1487  outl(0x00001000, ioaddr + CSR12);
1488  break;
1489  case COMET:
1490  /* No initialization necessary. */
1491  break;
1492  }
1493 }
Definition: tulip.c:151
struct medialeaf mleaf[0]
Definition: tulip.c:331
u8 csr12dir
Definition: tulip.c:328
u8 media
Definition: tulip.c:322
Definition: tulip.c:152
Definition: tulip.c:152
static int mdio_read(struct nic *nic, int phy_id, int location)
static void select_media(struct nic *nic, int startup)
Definition: tulip.c:1673
static void nway_start(struct nic *nic)
unsigned int default_port
Definition: tulip.c:412
struct mediatable * mtable
Definition: tulip.c:416
static const char media_cap[32]
Definition: tulip.c:275
u16 advertising[4]
Definition: tulip.c:418
Definition: tulip.c:152
int flags
Definition: tulip.c:400
unsigned has_mii
Definition: tulip.c:329
Definition: tulip.c:152
static void whereami(const char *str)
Definition: tulip.c:513
int saved_if_port
Definition: tulip.c:421
int chip_id
Definition: tulip.c:397
Definition: tulip.c:235
Definition: tulip.c:151
static u32 ioaddr
Definition: tulip.c:393
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
u8 leafcount
Definition: tulip.c:328
static void mdio_write(struct nic *nic, int phy_id, int location, int value)
Definition: tulip.c:151
unsigned int if_port
Definition: tulip.c:406
Definition: tulip.c:152
#define outl(data, io_addr)
Definition: io.h:329
u16 sym_advertise
Definition: tulip.c:415
Definition: nic.h:49
Definition: tulip.c:297
Definition: tulip.c:297
Definition: tulip.c:296
unsigned int full_duplex
Definition: tulip.c:407
int cur_index
Definition: tulip.c:420
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
signed char phys[4]
Definition: tulip.c:419
unsigned int nwayset
Definition: tulip.c:411
unsigned int nway
Definition: tulip.c:411
Definition: tulip.c:151
signed char mii_cnt
Definition: tulip.c:419
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
u16 mii_advertise
Definition: tulip.c:415
Definition: tulip.c:297
Definition: tulip.c:297

References tulip_private::advertising, ALWAYS_CHECK_MII, tulip_private::chip_id, COMET, COMPEX9881, CSR12, mediatable::csr12dir, CSR13, CSR14, CSR15, CSR6, tulip_private::cur_index, DBG, DC21040, DC21041, DC21140, DC21142, tulip_private::default_port, tulip_private::flags, tulip_private::full_duplex, HAS_MII, mediatable::has_mii, tulip_private::if_port, inl(), ioaddr, LC82C168, mediatable::leafcount, mdio_read(), mdio_write(), medialeaf::media, media_cap, MediaIs100, MediaIsMII, tulip_private::mii_advertise, tulip_private::mii_cnt, mediatable::mleaf, tulip_private::mtable, MX98713, MX98715, MX98725, tulip_private::nic_name, tulip_private::nway, nway_start(), tulip_private::nwayset, outl, tulip_private::phys, PNIC2, tulip_private::saved_if_port, select_media(), tulip_private::sym_advertise, tp, and whereami().

Referenced by tulip_probe().

◆ tulip_check_duplex()

static int tulip_check_duplex ( struct nic nic)
static

Definition at line 1875 of file tulip.c.

1876 {
1877  unsigned int bmsr, lpa, negotiated, new_csr6;
1878 
1879  bmsr = mdio_read(nic, tp->phys[0], 1);
1880  lpa = mdio_read(nic, tp->phys[0], 5);
1881 
1882  DBG2("%s: MII status %#x, Link partner report %#x.\n",
1883  tp->nic_name, bmsr, lpa);
1884 
1885  if (bmsr == 0xffff)
1886  return -2;
1887  if ((bmsr & 4) == 0) {
1888  int new_bmsr = mdio_read(nic, tp->phys[0], 1);
1889  if ((new_bmsr & 4) == 0) {
1890  DBG2("%s: No link beat on the MII interface,"
1891  " status %#x.\n", tp->nic_name,
1892  new_bmsr);
1893  return -1;
1894  }
1895  }
1896  tp->full_duplex = lpa & 0x140;
1897 
1898  new_csr6 = tp->csr6;
1899  negotiated = lpa & tp->advertising[0];
1900 
1901  if(negotiated & 0x380) new_csr6 &= ~0x400000;
1902  else new_csr6 |= 0x400000;
1903  if (tp->full_duplex) new_csr6 |= 0x200;
1904  else new_csr6 &= ~0x200;
1905 
1906  if (new_csr6 != tp->csr6) {
1907  tp->csr6 = new_csr6;
1908 
1909  DBG("%s: Setting %s-duplex based on MII"
1910  "#%d link partner capability of %#x.\n",
1911  tp->nic_name,
1912  tp->full_duplex ? "full" : "half",
1913  tp->phys[0], lpa);
1914  return 1;
1915  }
1916 
1917  return 0;
1918 }
static int mdio_read(struct nic *nic, int phy_id, int location)
u16 advertising[4]
Definition: tulip.c:418
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
Definition: nic.h:49
unsigned int full_duplex
Definition: tulip.c:407
signed char phys[4]
Definition: tulip.c:419
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
unsigned int csr6
Definition: tulip.c:405
#define DBG2(...)
Definition: compiler.h:515

References tulip_private::advertising, tulip_private::csr6, DBG, DBG2, tulip_private::full_duplex, mdio_read(), tulip_private::nic_name, tulip_private::phys, and tp.

Referenced by tulip_reset().

◆ tulip_wait()

static void tulip_wait ( unsigned int  nticks)
static

Definition at line 519 of file tulip.c.

520 {
521  unsigned int to = currticks() + nticks;
522  while (currticks() < to)
523  /* wait */ ;
524 }
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42

References currticks().

Referenced by tulip_probe(), and tulip_reset().

◆ whereami()

static void whereami ( const char *  str)
static

Definition at line 513 of file tulip.c.

514 {
515  DBGP("%s\n", str);
516  /* sleep(2); */
517 }
#define DBGP(...)
Definition: compiler.h:532

References DBGP.

Referenced by init_media(), mdio_read(), mdio_write(), nway_start(), parse_eeprom(), pnic_do_nway(), read_eeprom(), select_media(), start_link(), tulip_disable(), tulip_init_ring(), tulip_poll(), tulip_probe(), tulip_reset(), and tulip_transmit().

◆ mdio_read() [2/2]

int mdio_read ( struct nic *nic  __unused,
int  phy_id,
int  location 
)

Definition at line 556 of file tulip.c.

557 {
558  int i;
559  int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
560  int retval = 0;
561  long mdio_addr = ioaddr + CSR9;
562 
563  whereami("mdio_read\n");
564 
565  if (tp->chip_id == LC82C168) {
566  int i = 1000;
567  outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
568  inl(ioaddr + 0xA0);
569  inl(ioaddr + 0xA0);
570  while (--i > 0)
571  if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
572  return retval & 0xffff;
573  return 0xffff;
574  }
575 
576  if (tp->chip_id == COMET) {
577  if (phy_id == 1) {
578  if (location < 7)
579  return inl(ioaddr + 0xB4 + (location<<2));
580  else if (location == 17)
581  return inl(ioaddr + 0xD0);
582  else if (location >= 29 && location <= 31)
583  return inl(ioaddr + 0xD4 + ((location-29)<<2));
584  }
585  return 0xffff;
586  }
587 
588  /* Establish sync by sending at least 32 logic ones. */
589  for (i = 32; i >= 0; i--) {
590  outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
591  mdio_delay();
593  mdio_delay();
594  }
595  /* Shift the read command bits out. */
596  for (i = 15; i >= 0; i--) {
597  int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
598 
599  outl(MDIO_ENB | dataval, mdio_addr);
600  mdio_delay();
601  outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
602  mdio_delay();
603  }
604  /* Read the two transition, 16 data, and wire-idle bits. */
605  for (i = 19; i > 0; i--) {
606  outl(MDIO_ENB_IN, mdio_addr);
607  mdio_delay();
608  retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
609  outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
610  mdio_delay();
611  }
612  return (retval>>1) & 0xffff;
613 }
#define MDIO_ENB
Definition: tulip.c:547
#define MDIO_DATA_WRITE1
Definition: tulip.c:546
Definition: tulip.c:152
static void whereami(const char *str)
Definition: tulip.c:513
int chip_id
Definition: tulip.c:397
static u32 ioaddr
Definition: tulip.c:393
#define MDIO_DATA_READ
Definition: tulip.c:549
static struct tulip_private * tp
Definition: tulip.c:442
#define outl(data, io_addr)
Definition: io.h:329
#define MDIO_ENB_IN
Definition: tulip.c:548
Definition: tulip.c:296
unsigned long retval
Definition: xen.h:45
#define MDIO_SHIFT_CLK
Definition: tulip.c:544
#define mdio_delay()
Definition: tulip.c:539
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
static struct command_descriptor read_cmd
"read" command descriptor
Definition: nvo_cmd.c:134

References tulip_private::chip_id, COMET, CSR9, inl(), ioaddr, LC82C168, MDIO_DATA_READ, MDIO_DATA_WRITE1, mdio_delay, MDIO_ENB, MDIO_ENB_IN, MDIO_SHIFT_CLK, outl, read_cmd, retval, tp, and whereami().

◆ mdio_write() [2/2]

void mdio_write ( struct nic *nic  __unused,
int  phy_id,
int  location,
int  value 
)

Definition at line 615 of file tulip.c.

616 {
617  int i;
618  int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
619  long mdio_addr = ioaddr + CSR9;
620 
621  whereami("mdio_write\n");
622 
623  if (tp->chip_id == LC82C168) {
624  int i = 1000;
625  outl(cmd, ioaddr + 0xA0);
626  do
627  if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
628  break;
629  while (--i > 0);
630  return;
631  }
632 
633  if (tp->chip_id == COMET) {
634  if (phy_id != 1)
635  return;
636  if (location < 7)
637  outl(value, ioaddr + 0xB4 + (location<<2));
638  else if (location == 17)
639  outl(value, ioaddr + 0xD0);
640  else if (location >= 29 && location <= 31)
641  outl(value, ioaddr + 0xD4 + ((location-29)<<2));
642  return;
643  }
644 
645  /* Establish sync by sending 32 logic ones. */
646  for (i = 32; i >= 0; i--) {
647  outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
648  mdio_delay();
650  mdio_delay();
651  }
652  /* Shift the command bits out. */
653  for (i = 31; i >= 0; i--) {
654  int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
655  outl(MDIO_ENB | dataval, mdio_addr);
656  mdio_delay();
657  outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
658  mdio_delay();
659  }
660  /* Clear out extra bits. */
661  for (i = 2; i > 0; i--) {
662  outl(MDIO_ENB_IN, mdio_addr);
663  mdio_delay();
664  outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
665  mdio_delay();
666  }
667 }
#define MDIO_ENB
Definition: tulip.c:547
#define MDIO_DATA_WRITE1
Definition: tulip.c:546
Definition: tulip.c:152
static void whereami(const char *str)
Definition: tulip.c:513
int chip_id
Definition: tulip.c:397
static u32 ioaddr
Definition: tulip.c:393
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
static struct tulip_private * tp
Definition: tulip.c:442
#define outl(data, io_addr)
Definition: io.h:329
#define MDIO_ENB_IN
Definition: tulip.c:548
Definition: tulip.c:296
#define MDIO_SHIFT_CLK
Definition: tulip.c:544
#define mdio_delay()
Definition: tulip.c:539
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
struct golan_eqe_cmd cmd
Definition: CIB_PRM.h:29

References tulip_private::chip_id, cmd, COMET, CSR9, inl(), ioaddr, LC82C168, MDIO_DATA_WRITE1, mdio_delay, MDIO_ENB, MDIO_ENB_IN, MDIO_SHIFT_CLK, outl, tp, value, and whereami().

◆ tulip_init_ring() [2/2]

static void tulip_init_ring ( struct nic *nic  __unused)
static

Definition at line 870 of file tulip.c.

871 {
872  int i;
873 
874  whereami("tulip_init_ring\n");
875 
876  tp->cur_rx = 0;
877 
878  for (i = 0; i < RX_RING_SIZE; i++) {
879  rx_ring[i].status = cpu_to_le32(0x80000000);
880  rx_ring[i].length = cpu_to_le32(BUFLEN);
881  rx_ring[i].buffer1 = virt_to_le32desc(&rxb[i * BUFLEN]);
882  rx_ring[i].buffer2 = virt_to_le32desc(&rx_ring[i+1]);
883  }
884  /* Mark the last entry as wrapping the ring. */
885  rx_ring[i-1].length = cpu_to_le32(DESC_RING_WRAP | BUFLEN);
886  rx_ring[i-1].buffer2 = virt_to_le32desc(&rx_ring[0]);
887 
888  /* We only use 1 transmit buffer, but we use 2 descriptors so
889  transmit engines have somewhere to point to if they feel the need */
890 
891  tx_ring[0].status = 0x00000000;
892  tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]);
893  tx_ring[0].buffer2 = virt_to_le32desc(&tx_ring[1]);
894 
895  /* this descriptor should never get used, since it will never be owned
896  by the machine (status will always == 0) */
897  tx_ring[1].status = 0x00000000;
898  tx_ring[1].buffer1 = virt_to_le32desc(&txb[0]);
899  tx_ring[1].buffer2 = virt_to_le32desc(&tx_ring[0]);
900 
901  /* Mark the last entry as wrapping the ring, though this should never happen */
902  tx_ring[1].length = cpu_to_le32(DESC_RING_WRAP | BUFLEN);
903 }
#define BUFLEN
Definition: tulip.c:365
#define rxb
Definition: tulip.c:440
#define DESC_RING_WRAP
Definition: tulip.c:374
static void whereami(const char *str)
Definition: tulip.c:513
#define RX_RING_SIZE
Definition: tulip.c:428
static struct tulip_private * tp
Definition: tulip.c:442
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define virt_to_le32desc(addr)
Definition: tulip.c:126
#define rx_ring
Definition: tulip.c:439
int cur_rx
Definition: tulip.c:396
#define txb
Definition: tulip.c:438
#define tx_ring
Definition: tulip.c:437

References BUFLEN, cpu_to_le32, tulip_private::cur_rx, DESC_RING_WRAP, rx_ring, RX_RING_SIZE, rxb, tp, tx_ring, txb, virt_to_le32desc, and whereami().

◆ set_rx_mode()

static void set_rx_mode ( struct nic *nic  __unused)
static

Definition at line 906 of file tulip.c.

906  {
907  int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
908 
909  tp->csr6 &= ~0x00D5;
910 
911  /* !IFF_PROMISC */
913  csr6 |= AcceptAllMulticast;
914 
915  outl(csr6, ioaddr + CSR6);
916 
917 
918 
919 }
static u32 ioaddr
Definition: tulip.c:393
static struct tulip_private * tp
Definition: tulip.c:442
#define outl(data, io_addr)
Definition: io.h:329
Definition: tulip.c:296
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
unsigned int csr6
Definition: tulip.c:405

References AcceptAllMulticast, CSR6, tulip_private::csr6, inl(), ioaddr, outl, and tp.

Referenced by tulip_reset().

◆ tulip_disable() [2/2]

static void tulip_disable ( struct nic nic,
void *hwdev  __unused 
)
static

Definition at line 1132 of file tulip.c.

1132  {
1133 
1134  whereami("tulip_disable\n");
1135 
1136  tulip_reset(nic);
1137 
1138  /* disable interrupts */
1139  outl(0x00000000, ioaddr + CSR7);
1140 
1141  /* Stop the chip's Tx and Rx processes. */
1142  outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
1143 
1144  /* Clear the missed-packet counter. */
1145  inl(ioaddr + CSR8);
1146 }
Definition: tulip.c:296
static void whereami(const char *str)
Definition: tulip.c:513
static u32 ioaddr
Definition: tulip.c:393
#define outl(data, io_addr)
Definition: io.h:329
static void tulip_reset(struct nic *nic)
Definition: tulip.c:924
Definition: nic.h:49
Definition: tulip.c:296
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
Definition: tulip.c:296

References CSR6, CSR7, CSR8, inl(), ioaddr, outl, tulip_reset(), and whereami().

◆ tulip_irq()

static void tulip_irq ( struct nic *nic  __unused,
irq_action_t action  __unused 
)
static

Definition at line 1151 of file tulip.c.

1152 {
1153  switch ( action ) {
1154  case DISABLE :
1155  break;
1156  case ENABLE :
1157  break;
1158  case FORCE :
1159  break;
1160  }
1161 }
Definition: nic.h:35
Definition: nic.h:37
Definition: nic.h:36

References DISABLE, ENABLE, and FORCE.

◆ nway_start() [2/2]

static void nway_start ( struct nic *nic  __unused)
static

Definition at line 1495 of file tulip.c.

1496 {
1497  int csr14 = ((tp->sym_advertise & 0x0780) << 9) |
1498  ((tp->sym_advertise&0x0020)<<1) | 0xffbf;
1499 
1500  whereami("nway_start\n");
1501 
1502  tp->if_port = 0;
1503  tp->nway = tp->mediasense = 1;
1504  tp->nwayset = tp->lpar = 0;
1505  if (tp->chip_id == PNIC2) {
1506  tp->csr6 = 0x01000000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0);
1507  return;
1508  }
1509  DBG2("%s: Restarting internal NWay autonegotiation, %X.\n",
1510  tp->nic_name, csr14);
1511  outl(0x0001, ioaddr + CSR13);
1512  outl(csr14, ioaddr + CSR14);
1513  tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0);
1514  outl(tp->csr6, ioaddr + CSR6);
1515  if (tp->mtable && tp->mtable->csr15dir) {
1518  } else if (tp->chip_id != PNIC2)
1519  outw(0x0008, ioaddr + CSR15);
1520  if (tp->chip_id == DC21041) /* Trigger NWAY. */
1521  outl(0xEF01, ioaddr + CSR12);
1522  else
1523  outl(0x1301, ioaddr + CSR12);
1524 }
Definition: tulip.c:151
u32 csr15val
Definition: tulip.c:330
#define outw(data, io_addr)
Definition: io.h:319
struct mediatable * mtable
Definition: tulip.c:416
static void whereami(const char *str)
Definition: tulip.c:513
int chip_id
Definition: tulip.c:397
u16 lpar
Definition: tulip.c:417
static u32 ioaddr
Definition: tulip.c:393
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
unsigned int if_port
Definition: tulip.c:406
Definition: tulip.c:152
#define outl(data, io_addr)
Definition: io.h:329
u16 sym_advertise
Definition: tulip.c:415
Definition: tulip.c:297
Definition: tulip.c:297
Definition: tulip.c:296
unsigned int nwayset
Definition: tulip.c:411
unsigned int nway
Definition: tulip.c:411
unsigned int mediasense
Definition: tulip.c:410
unsigned int csr6
Definition: tulip.c:405
u32 csr15dir
Definition: tulip.c:330
#define DBG2(...)
Definition: compiler.h:515
Definition: tulip.c:297
Definition: tulip.c:297

References tulip_private::chip_id, CSR12, CSR13, CSR14, CSR15, mediatable::csr15dir, mediatable::csr15val, CSR6, tulip_private::csr6, DBG2, DC21041, tulip_private::if_port, ioaddr, tulip_private::lpar, tulip_private::mediasense, tulip_private::mtable, tulip_private::nic_name, tulip_private::nway, tulip_private::nwayset, outl, outw, PNIC2, tulip_private::sym_advertise, tp, and whereami().

◆ pnic_do_nway() [2/2]

static void pnic_do_nway ( struct nic *nic  __unused)
static

Definition at line 1641 of file tulip.c.

1642 {
1643  u32 phy_reg = inl(ioaddr + 0xB8);
1644  u32 new_csr6 = tp->csr6 & ~0x40C40200;
1645 
1646  whereami("pnic_do_nway\n");
1647 
1648  if (phy_reg & 0x78000000) { /* Ignore baseT4 */
1649  if (phy_reg & 0x20000000) tp->if_port = 5;
1650  else if (phy_reg & 0x40000000) tp->if_port = 3;
1651  else if (phy_reg & 0x10000000) tp->if_port = 4;
1652  else if (phy_reg & 0x08000000) tp->if_port = 0;
1653  tp->nwayset = 1;
1654  new_csr6 = (tp->if_port & 1) ? 0x01860000 : 0x00420000;
1655  outl(0x32 | (tp->if_port & 1), ioaddr + CSR12);
1656  if (tp->if_port & 1)
1657  outl(0x1F868, ioaddr + 0xB8);
1658  if (phy_reg & 0x30000000) {
1659  tp->full_duplex = 1;
1660  new_csr6 |= 0x00000200;
1661  }
1662  DBG2("%s: PNIC autonegotiated status %X, %s.\n",
1663  tp->nic_name, phy_reg, medianame[tp->if_port]);
1664  if (tp->csr6 != new_csr6) {
1665  tp->csr6 = new_csr6;
1666  outl(tp->csr6 | 0x0002, ioaddr + CSR6); /* Restart Tx */
1667  outl(tp->csr6 | 0x2002, ioaddr + CSR6);
1668  }
1669  }
1670 }
static void whereami(const char *str)
Definition: tulip.c:513
static u32 ioaddr
Definition: tulip.c:393
static struct tulip_private * tp
Definition: tulip.c:442
const char * nic_name
Definition: tulip.c:404
unsigned int if_port
Definition: tulip.c:406
#define outl(data, io_addr)
Definition: io.h:329
static const char *const medianame[32]
Definition: tulip.c:141
Definition: tulip.c:296
unsigned int full_duplex
Definition: tulip.c:407
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
unsigned int nwayset
Definition: tulip.c:411
unsigned int csr6
Definition: tulip.c:405
uint32_t u32
Definition: stdint.h:23
#define DBG2(...)
Definition: compiler.h:515
Definition: tulip.c:297

References CSR12, CSR6, tulip_private::csr6, DBG2, tulip_private::full_duplex, tulip_private::if_port, inl(), ioaddr, medianame, tulip_private::nic_name, tulip_private::nwayset, outl, tp, and whereami().

◆ PCI_DRIVER()

PCI_DRIVER ( tulip_driver  ,
tulip_nics  ,
PCI_NO_CLASS   
)

◆ DRIVER()

DRIVER ( "Tulip"  ,
nic_driver  ,
pci_driver  ,
tulip_driver  ,
tulip_probe  ,
tulip_disable  ,
tulip_bss   
)

Variable Documentation

◆ csr0

const int csr0 = 0x01A00000 | 0x8000
static

Definition at line 137 of file tulip.c.

Referenced by tulip_probe().

◆ medianame

const char* const medianame[32]
static
Initial value:
= {
"10baseT", "10base2", "AUI", "100baseTx",
"10baseT-FDX", "100baseTx-FDX", "100baseT4", "100baseFx",
"100baseFx-FDX", "MII 10baseT", "MII 10baseT-FDX", "MII",
"10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FDX", "MII 100baseT4",
"MII 100baseFx-HDX", "MII 100baseFx-FDX", "Home-PNA 1Mbps", "Invalid-19",
}

Definition at line 141 of file tulip.c.

Referenced by init_media(), parse_eeprom(), pnic_do_nway(), and select_media().

◆ pci_id_tbl

const struct pci_id_info pci_id_tbl[]
static

Definition at line 176 of file tulip.c.

Referenced by tulip_probe().

◆ tulip_tbl

struct tulip_chip_table tulip_tbl[]
static
Initial value:
= {
{ "Digital DC21040 Tulip", 0},
{ "Digital DC21041 Tulip", HAS_MEDIA_TABLE | HAS_NWAY },
{ "Digital DS21140 Tulip", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
{ "Digital DS21143 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII
{ "Lite-On 82c168 PNIC", HAS_MII | HAS_PNICNWAY },
{ "Macronix 98713 PMAC", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
{ "Macronix 98715 PMAC", HAS_MEDIA_TABLE },
{ "Macronix 98725 PMAC", HAS_MEDIA_TABLE },
{ "ASIX AX88140", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM
| IS_ASIX },
{ "Lite-On PNIC-II", HAS_MII | HAS_NWAY | HAS_8023X },
{ "ADMtek Comet", HAS_MII | MC_HASH_ONLY },
{ "Compex 9881 PMAC", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
{ "Intel DS21145 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII
{ "Xircom tulip work-alike", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII
{ "SGThomson STE10/100A", HAS_MII | MC_HASH_ONLY },
{ NULL, 0 },
}
Definition: tulip.c:235
Definition: tulip.c:238
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

Referenced by tulip_probe().

◆ media_cap

const char media_cap[32]
static
Initial value:
=
{0,0,0,16, 3,19,16,24, 27,4,7,5, 0,20,23,20, 20,31,0,0, }

Definition at line 275 of file tulip.c.

Referenced by init_media(), select_media(), start_link(), and tulip_probe().

◆ t21040_csr13

u8 t21040_csr13[] = {2,0x0C,8,4, 4,0,0,0, 0,0,0,0, 4,0,0,0}
static

Definition at line 277 of file tulip.c.

Referenced by select_media().

◆ t21041_csr13

u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }
static

Definition at line 280 of file tulip.c.

Referenced by select_media().

◆ t21041_csr14

u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }
static

Definition at line 281 of file tulip.c.

Referenced by select_media().

◆ t21041_csr15

u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }
static

Definition at line 282 of file tulip.c.

Referenced by select_media().

◆ t21142_csr14

u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, }
static

Definition at line 287 of file tulip.c.

Referenced by select_media().

◆ ioaddr

u32 ioaddr
static

◆ tp

struct tulip_private* tp
static

Definition at line 442 of file tulip.c.

Referenced by __mdio_read(), __mdio_write(), __tg3_set_coalesce(), __tg3_set_mac_addr(), __tg3_set_rx_mode(), fiber_autoneg(), init_media(), mdio_read(), mdio_write(), nway_start(), parse_eeprom(), pnic_do_nway(), select_media(), set_rx_mode(), sis190_default_phy(), sis190_down(), sis190_free(), sis190_get_mac_addr_from_apc(), sis190_get_mac_addr_from_eeprom(), sis190_hw_start(), sis190_init_board(), sis190_init_phy(), sis190_init_ring(), sis190_init_ring_indexes(), sis190_init_rxfilter(), sis190_irq(), sis190_mii_probe(), sis190_mii_probe_88e1111_fixup(), sis190_mii_remove(), sis190_open(), sis190_phy_task(), sis190_poll(), sis190_probe(), sis190_process_rx(), sis190_process_tx(), sis190_remove(), sis190_rx_fill(), sis190_set_rgmii(), sis190_set_rx_mode(), sis190_set_speed_auto(), sis190_transmit(), sky2_ramset(), start_link(), tg3_5700_link_polarity(), tg3_abort_hw(), tg3_adv_1000T_flowctrl_ok(), tg3_alloc_consistent(), tg3_aux_stat_to_speed_duplex(), tg3_bmcr_reset(), tg3_chip_reset(), tg3_close(), tg3_copper_is_advertising_all(), tg3_disable_ints(), tg3_disable_nvram_access(), tg3_do_test_dma(), tg3_enable_ints(), tg3_enable_nvram_access(), tg3_fiber_aneg_smachine(), tg3_free_consistent(), tg3_get_device_address(), tg3_get_eeprom_hw_cfg(), tg3_get_invariants(), tg3_halt(), tg3_init_5401phy_dsp(), tg3_init_bcm8002(), tg3_init_bufmgr_config(), tg3_init_hw(), tg3_init_one(), tg3_init_rings(), tg3_irq(), tg3_link_report(), tg3_lookup_by_subsys(), tg3_mdio_init(), tg3_nvram_lock(), tg3_nvram_phys_addr(), tg3_nvram_read(), tg3_nvram_read_be32(), tg3_nvram_unlock(), tg3_open(), tg3_phy_apply_otp(), tg3_phy_autoneg_cfg(), tg3_phy_auxctl_read(), tg3_phy_auxctl_write(), tg3_phy_copper_begin(), tg3_phy_init_link_config(), tg3_phy_probe(), tg3_phy_reset(), tg3_phy_reset_5703_4_5(), tg3_phy_reset_chanpat(), tg3_phy_set_wirespeed(), tg3_phy_toggle_automdix(), tg3_phy_write_and_check_testpat(), tg3_phydsp_write(), tg3_poll(), tg3_poll_fw(), tg3_poll_link(), tg3_read32_mbox_5906(), tg3_read_indirect_mbox(), tg3_read_indirect_reg32(), tg3_read_mem(), tg3_read_otp_phycfg(), tg3_readphy(), tg3_refill_prod_ring(), tg3_reset_hw(), tg3_restore_pci_state(), tg3_rings_reset(), tg3_rx_complete(), tg3_rx_prodring_fini(), tg3_save_pci_state(), tg3_set_bdinfo(), tg3_set_power_state_0(), tg3_set_txd(), tg3_setup_copper_phy(), tg3_setup_fiber_by_hand(), tg3_setup_fiber_hw_autoneg(), tg3_setup_fiber_mii_phy(), tg3_setup_fiber_phy(), tg3_setup_flow_control(), tg3_setup_phy(), tg3_setup_rxbd_thresholds(), tg3_stop_block(), tg3_stop_fw(), tg3_switch_clocks(), tg3_test_and_report_link_chg(), tg3_test_dma(), tg3_transmit(), tg3_tx_avail(), tg3_tx_complete(), tg3_ump_link_report(), tg3_wait_macro_done(), tg3_write32_mbox_5906(), tg3_write_indirect_mbox(), tg3_write_indirect_reg32(), tg3_write_mem(), tg3_write_sig_pre_reset(), tg3_writephy(), tulip_check_duplex(), tulip_init_ring(), tulip_poll(), tulip_probe(), tulip_reset(), tulip_transmit(), and tw32_mailbox_flush().

◆ eeprom_fixups

struct fixups eeprom_fixups[]
static
Initial value:
= {
{"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
{"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
0x0000, 0x009E,
0x0004, 0x009E,
0x0903, 0x006D,
0x0905, 0x006D, }},
{"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
0x0107, 0x8021,
0x0108, 0x8021,
0x0100, 0x009E,
0x0104, 0x009E,
0x0103, 0x006D,
0x0105, 0x006D, }},
{"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
0x1001, 0x009E,
0x0000, 0x009E,
0x0004, 0x009E,
0x0303, 0x006D,
0x0305, 0x006D, }},
{"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
0x1B01, 0x0000,
0x0B00, 0x009E,
0x0B04, 0x009E,
0x1B03, 0x006D,
0x1B05, 0x006D,
}},
{NULL, 0, 0, 0, {}}}
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

Referenced by parse_eeprom().

◆ block_name

const char* block_name[]
static
Initial value:
= {"21140 non-MII", "21140 MII PHY",
"21142 Serial PHY", "21142 MII PHY", "21143 SYM PHY", "21143 reset method"}

Definition at line 481 of file tulip.c.

Referenced by parse_eeprom().

◆ tulip_operations

struct nic_operations tulip_operations
static
Initial value:
= {
.connect = dummy_connect,
.poll = tulip_poll,
.transmit = tulip_transmit,
.irq = tulip_irq,
}
static void tulip_irq(struct nic *nic __unused, irq_action_t action __unused)
Definition: tulip.c:1151
static void tulip_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
Definition: tulip.c:1041
int dummy_connect(struct nic *nic __unused)
Definition: legacy.c:175
static int tulip_poll(struct nic *nic, int retrieve)
Definition: tulip.c:1096

Definition at line 1163 of file tulip.c.

Referenced by tulip_probe().

◆ tulip_nics

struct pci_device_id tulip_nics[]
static

Definition at line 1920 of file tulip.c.