epic100.c File Reference

#include "etherboot.h"
#include <gpxe/pci.h>
#include <gpxe/ethernet.h>
#include "nic.h"
#include "console.h"
#include "epic100.h"

Go to the source code of this file.

Data Structures

struct  epic_rx_desc
struct  epic_tx_desc

Defines

#define LINUX_OUT_MACROS
#define virt_to_le32desc(addr)   cpu_to_le32(virt_to_bus(addr))
#define le32desc_to_virt(addr)   bus_to_virt(le32_to_cpu(addr))
#define TX_RING_SIZE   2
#define RX_RING_SIZE   2
#define PKT_BUF_SZ   1536
#define EPIC_DEBUG   0
#define TD_STDFLAGS   TD_LASTDESC
#define delay(nanosec)
#define rx_ring   epic100_bufs.rx_ring
#define tx_ring   epic100_bufs.tx_ring
#define rx_packet   epic100_bufs.rx_packet
#define tx_packet   epic100_bufs.tx_packet
#define MII_READOP   1
#define MII_WRITEOP   2

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static void epic100_open (void)
static void epic100_init_ring (void)
static void epic100_disable (struct nic *nic)
static int epic100_poll (struct nic *nic, int retrieve)
static void epic100_transmit (struct nic *nic, const char *destaddr, unsigned int type, unsigned int len, const char *data)
static int mii_read (int phy_id, int location)
static void epic100_irq (struct nic *nic, irq_action_t action)
static int epic100_probe (struct nic *nic, struct pci_device *pci)
static void set_rx_mode (void)
static void epic100_disable (struct nic *nic __unused)
static void epic100_irq (struct nic *nic __unused, irq_action_t action __unused)
 PCI_DRIVER (epic100_driver, epic100_nics, PCI_NO_CLASS)
 DRIVER ("EPIC100", nic_driver, pci_driver, epic100_driver, epic100_probe, epic100_disable)

Variables

static struct nic_operations epic100_operations
static int ioaddr
static int command
static int intstat
static int intmask
static int genctl
static int eectl
static int test
static int mmctl
static int mmdata
static int lan0
static int mc0
static int rxcon
static int txcon
static int prcdar
static int ptcdar
static int eththr
static unsigned int cur_rx
static unsigned int cur_tx
static signed char phys [4]
struct {
   struct epic_rx_desc   rx_ring [RX_RING_SIZE]
   struct epic_tx_desc   tx_ring [TX_RING_SIZE]
   unsigned char   rx_packet [PKT_BUF_SZ *RX_RING_SIZE]
   unsigned char   tx_packet [PKT_BUF_SZ *TX_RING_SIZE]
__shared
static struct pci_device_id epic100_nics []


Define Documentation

#define LINUX_OUT_MACROS

Definition at line 7 of file epic100.c.

#define virt_to_le32desc ( addr   )     cpu_to_le32(virt_to_bus(addr))

Definition at line 17 of file epic100.c.

#define le32desc_to_virt ( addr   )     bus_to_virt(le32_to_cpu(addr))

Definition at line 18 of file epic100.c.

#define TX_RING_SIZE   2

Definition at line 20 of file epic100.c.

#define RX_RING_SIZE   2

Definition at line 21 of file epic100.c.

#define PKT_BUF_SZ   1536

Definition at line 23 of file epic100.c.

#define EPIC_DEBUG   0

Definition at line 31 of file epic100.c.

#define TD_STDFLAGS   TD_LASTDESC

Definition at line 41 of file epic100.c.

Referenced by epic100_init_ring().

#define delay ( nanosec   ) 

Value:

do { int _i = 3; while (--_i > 0) \
                                     { __SLOW_DOWN_IO; }} while (0)

Definition at line 50 of file epic100.c.

Referenced by ath5k_hw_reset(), and sleep_exec().

Definition at line 100 of file epic100.c.

Referenced by epic100_init_ring(), and epic100_poll().

Definition at line 101 of file epic100.c.

Referenced by epic100_init_ring(), and epic100_transmit().

#define MII_READOP   1

Definition at line 498 of file epic100.c.

Referenced by mii_read().

#define MII_WRITEOP   2

Definition at line 499 of file epic100.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static void epic100_open ( void   )  [static]

Definition at line 231 of file epic100.c.

References CR_QUEUE_RX, CR_START_RX, epic100_init_ring(), eththr, full_duplex, GC_MRC_READ_MULT, GC_ONE_COPY, GC_RX_FIFO_THR_64, genctl, mii_read(), outl, phys, prcdar, printf(), ptcdar, putchar(), rx_ring, set_rx_mode(), TC_EARLY_TX_ENABLE, TC_LM_FULL_DPX, TC_LM_NORMAL, TX_FIFO_THRESH, tx_ring, TX_SLOT_TIME, txcon, and virt_to_le32desc.

Referenced by epic100_probe(), and epic100_transmit().

00232 {
00233     int mii_reg5;
00234     int full_duplex = 0;
00235     unsigned long tmp;
00236 
00237     epic100_init_ring();
00238 
00239     /* Pull the chip out of low-power mode, and set for PCI read multiple. */
00240     outl(GC_RX_FIFO_THR_64 | GC_MRC_READ_MULT | GC_ONE_COPY, genctl);
00241 
00242     outl(TX_FIFO_THRESH, eththr);
00243 
00244     tmp = TC_EARLY_TX_ENABLE | TX_SLOT_TIME;
00245 
00246     mii_reg5 = mii_read(phys[0], 5);
00247     if (mii_reg5 != 0xffff && (mii_reg5 & 0x0100)) {
00248         full_duplex = 1;
00249         printf(" full-duplex mode");
00250         tmp |= TC_LM_FULL_DPX;
00251     } else
00252         tmp |= TC_LM_NORMAL;
00253 
00254     outl(tmp, txcon);
00255 
00256     /* Give adress of RX and TX ring to the chip */
00257     outl(virt_to_le32desc(&rx_ring), prcdar);
00258     outl(virt_to_le32desc(&tx_ring), ptcdar);
00259 
00260     /* Start the chip's Rx process: receive unicast and broadcast */
00261     set_rx_mode();
00262     outl(CR_START_RX | CR_QUEUE_RX, command);
00263 
00264     putchar('\n');
00265 }

static void epic100_init_ring ( void   )  [static]

Definition at line 269 of file epic100.c.

References cpu_to_le32, cur_rx, cur_tx, PKT_BUF_SZ, RRING_OWN, rx_packet, rx_ring, RX_RING_SIZE, TD_STDFLAGS, tx_packet, tx_ring, TX_RING_SIZE, virt_to_bus(), and virt_to_le32desc.

Referenced by epic100_open().

00270 {
00271     int i;
00272 
00273     cur_rx = cur_tx = 0;
00274 
00275     for (i = 0; i < RX_RING_SIZE; i++) {
00276         rx_ring[i].status    = cpu_to_le32(RRING_OWN);  /* Owned by Epic chip */
00277         rx_ring[i].buflength = cpu_to_le32(PKT_BUF_SZ);
00278         rx_ring[i].bufaddr   = virt_to_bus(&rx_packet[i * PKT_BUF_SZ]);
00279         rx_ring[i].next      = virt_to_le32desc(&rx_ring[i + 1]) ;
00280     }
00281     /* Mark the last entry as wrapping the ring. */
00282     rx_ring[i-1].next = virt_to_le32desc(&rx_ring[0]);
00283 
00284     /*
00285      *The Tx buffer descriptor is filled in as needed,
00286      * but we do need to clear the ownership bit.
00287      */
00288 
00289     for (i = 0; i < TX_RING_SIZE; i++) {
00290         tx_ring[i].status  = 0x0000;                    /* Owned by CPU */
00291         tx_ring[i].buflength = 0x0000 | cpu_to_le32(TD_STDFLAGS << 16);
00292         tx_ring[i].bufaddr = virt_to_bus(&tx_packet[i * PKT_BUF_SZ]);
00293         tx_ring[i].next    = virt_to_le32desc(&tx_ring[i + 1]);
00294     }
00295         tx_ring[i-1].next    = virt_to_le32desc(&tx_ring[0]);
00296 }

static void epic100_disable ( struct nic nic  )  [static]

static int epic100_poll ( struct nic nic,
int  retrieve 
) [static]

Definition at line 378 of file epic100.c.

References epic_tx_desc::buflength, cpu_to_le32, CR_QUEUE_RX, CR_START_RX, cur_rx, entry, INTR_CLEARERRS, intstat, le32_to_cpu, memcpy, outl, nic::packet, nic::packetlen, PKT_BUF_SZ, printf(), RRING_OWN, rx_packet, rx_ring, RX_RING_SIZE, and epic_tx_desc::status.

00379 {
00380     int entry;
00381     int retcode;
00382     int status;
00383     entry = cur_rx % RX_RING_SIZE;
00384 
00385     if ((rx_ring[entry].status & cpu_to_le32(RRING_OWN)) == RRING_OWN)
00386         return (0);
00387 
00388     if ( ! retrieve ) return 1;
00389 
00390     status = le32_to_cpu(rx_ring[entry].status);
00391     /* We own the next entry, it's a new packet. Send it up. */
00392 
00393 #if     (EPIC_DEBUG > 4)
00394     printf("epic_poll: entry %d status %hX\n", entry, status);
00395 #endif
00396 
00397     cur_rx++;
00398     if (status & 0x2000) {
00399         printf("epic_poll: Giant packet\n");
00400         retcode = 0;
00401     } else if (status & 0x0006) {
00402         /* Rx Frame errors are counted in hardware. */
00403         printf("epic_poll: Frame received with errors\n");
00404         retcode = 0;
00405     } else {
00406         /* Omit the four octet CRC from the length. */
00407         nic->packetlen = le32_to_cpu((rx_ring[entry].buflength))- 4;
00408         memcpy(nic->packet, &rx_packet[entry * PKT_BUF_SZ], nic->packetlen);
00409         retcode = 1;
00410     }
00411 
00412     /* Clear all error sources. */
00413     outl(status & INTR_CLEARERRS, intstat);
00414 
00415     /* Give the descriptor back to the chip */
00416     rx_ring[entry].status = RRING_OWN;
00417 
00418     /* Restart Receiver */
00419     outl(CR_START_RX | CR_QUEUE_RX, command); 
00420 
00421     return retcode;
00422 }

static void epic100_transmit ( struct nic nic,
const char *  destaddr,
unsigned int  type,
unsigned int  len,
const char *  data 
) [static]

Definition at line 308 of file epic100.c.

References cpu_to_le32, CR_QUEUE_TX, cur_tx, currticks(), entry, epic100_open(), ETH_ALEN, ETH_HLEN, ETH_ZLEN, htons, le32_to_cpu, memcpy, nic::node_addr, outl, PKT_BUF_SZ, printf(), epic_tx_desc::status, TRING_OWN, tx_packet, tx_ring, and TX_RING_SIZE.

00310 {
00311     unsigned short nstype;
00312     unsigned char *txp;
00313     int entry;
00314     unsigned long ct;
00315 
00316     /* Calculate the next Tx descriptor entry. */
00317     entry = cur_tx % TX_RING_SIZE;
00318 
00319     if ((tx_ring[entry].status & TRING_OWN) == TRING_OWN) {
00320         printf("eth_transmit: Unable to transmit. status=%4.4lx. Resetting...\n",
00321                tx_ring[entry].status);
00322 
00323         epic100_open();
00324         return;
00325     }
00326 
00327     txp = tx_packet + (entry * PKT_BUF_SZ);
00328 
00329     memcpy(txp, destaddr, ETH_ALEN);
00330     memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
00331     nstype = htons(type);
00332     memcpy(txp + 12, (char*)&nstype, 2);
00333     memcpy(txp + ETH_HLEN, data, len);
00334 
00335     len += ETH_HLEN;
00336         len &= 0x0FFF;
00337         while(len < ETH_ZLEN)
00338                 txp[len++] = '\0';
00339     /*
00340      * Caution: the write order is important here,
00341      * set the base address with the "ownership"
00342      * bits last.
00343      */
00344    
00345     tx_ring[entry].buflength |= cpu_to_le32(len);
00346     tx_ring[entry].status = cpu_to_le32(len << 16) |
00347             cpu_to_le32(TRING_OWN);     /* Pass ownership to the chip. */
00348 
00349     cur_tx++;
00350 
00351     /* Trigger an immediate transmit demand. */
00352     outl(CR_QUEUE_TX, command);
00353 
00354     ct = currticks();
00355     /* timeout 10 ms for transmit */
00356     while ((le32_to_cpu(tx_ring[entry].status) & (TRING_OWN)) &&
00357                 ct + 10*1000 < currticks())
00358         /* Wait */;
00359 
00360     if ((le32_to_cpu(tx_ring[entry].status) & TRING_OWN) != 0)
00361         printf("Oops, transmitter timeout, status=%4.4lX\n",
00362             tx_ring[entry].status);
00363 }

static int mii_read ( int  phy_id,
int  location 
) [static]

Definition at line 502 of file epic100.c.

References inl, inw, MII_READOP, mmctl, mmdata, and outl.

Referenced by epic100_open(), and epic100_probe().

00503 {
00504     int i;
00505 
00506     outl((phy_id << 9) | (location << 4) | MII_READOP, mmctl);
00507     /* Typical operation takes < 50 ticks. */
00508 
00509     for (i = 4000; i > 0; i--)
00510         if ((inl(mmctl) & MII_READOP) == 0)
00511             break;
00512     return inw(mmdata);
00513 }

static void epic100_irq ( struct nic nic,
irq_action_t  action 
) [static]

static int epic100_probe ( struct nic nic,
struct pci_device pci 
) [static]

Definition at line 109 of file epic100.c.

References COMMAND, DBG, EECTL, eectl, epic100_open(), epic100_operations, eth_ntoa(), ETHTHR, eththr, GC_SOFT_RESET, GENCTL, genctl, INTMASK, intmask, INTR_DISABLE, INTSTAT, intstat, inw, nic::ioaddr, ioaddr, pci_device::ioaddr, nic::irqno, LAN0, lan0, MC0, mc0, mii_read(), MMCTL, mmctl, MMDATA, mmdata, nic::nic_op, nic::node_addr, outl, phys, PRCDAR, prcdar, printf(), PTCDAR, ptcdar, read_eeprom(), RXCON, rxcon, TEST, test, TXCON, and txcon.

00109                                                           {
00110 
00111     int i;
00112     unsigned short* ap;
00113     unsigned int phy, phy_idx;
00114 
00115     if (pci->ioaddr == 0)
00116         return 0;
00117 
00118     /* Ideally we would detect all network cards in slot order.  That would
00119        be best done a central PCI probe dispatch, which wouldn't work
00120        well with the current structure.  So instead we detect just the
00121        Epic cards in slot order. */
00122 
00123     ioaddr = pci->ioaddr;
00124 
00125     nic->irqno  = 0;
00126     nic->ioaddr = pci->ioaddr & ~3;
00127 
00128     /* compute all used static epic100 registers address */
00129     command = ioaddr + COMMAND;         /* Control Register */
00130     intstat = ioaddr + INTSTAT;         /* Interrupt Status */
00131     intmask = ioaddr + INTMASK;         /* Interrupt Mask */
00132     genctl  = ioaddr + GENCTL;          /* General Control */
00133     eectl   = ioaddr + EECTL;           /* EEPROM Control  */
00134     test    = ioaddr + TEST;            /* Test register (clocks) */
00135     mmctl   = ioaddr + MMCTL;           /* MII Management Interface Control */
00136     mmdata  = ioaddr + MMDATA;          /* MII Management Interface Data */
00137     lan0    = ioaddr + LAN0;            /* MAC address. (0x40-0x48) */
00138     mc0     = ioaddr + MC0;             /* Multicast Control */
00139     rxcon   = ioaddr + RXCON;           /* Receive Control */
00140     txcon   = ioaddr + TXCON;           /* Transmit Control */
00141     prcdar  = ioaddr + PRCDAR;          /* PCI Receive Current Descr Address */
00142     ptcdar  = ioaddr + PTCDAR;          /* PCI Transmit Current Descr Address */
00143     eththr  = ioaddr + ETHTHR;          /* Early Transmit Threshold */
00144 
00145     /* Reset the chip & bring it out of low-power mode. */
00146     outl(GC_SOFT_RESET, genctl);
00147 
00148     /* Disable ALL interrupts by setting the interrupt mask. */
00149     outl(INTR_DISABLE, intmask);
00150 
00151     /*
00152      * set the internal clocks:
00153      * Application Note 7.15 says:
00154      *    In order to set the CLOCK TEST bit in the TEST register,
00155      *    perform the following:
00156      *
00157      *        Write 0x0008 to the test register at least sixteen
00158      *        consecutive times.
00159      *
00160      * The CLOCK TEST bit is Write-Only. Writing it several times
00161      * consecutively insures a successful write to the bit...
00162      */
00163 
00164     for (i = 0; i < 16; i++) {
00165         outl(0x00000008, test);
00166     }
00167 
00168 #ifdef  DEBUG_EEPROM
00169 {
00170     unsigned short sum = 0;
00171     unsigned short value;
00172     for (i = 0; i < 64; i++) {
00173         value = read_eeprom(i);
00174         eeprom[i] = value;
00175         sum += value;
00176     }
00177 }
00178 
00179 #if     (EPIC_DEBUG > 1)
00180     printf("EEPROM contents\n");
00181     for (i = 0; i < 64; i++) {
00182         printf(" %hhX%s", eeprom[i], i % 16 == 15 ? "\n" : "");
00183     }
00184 #endif
00185 #endif
00186 
00187     /* This could also be read from the EEPROM. */
00188     ap = (unsigned short*)nic->node_addr;
00189     for (i = 0; i < 3; i++)
00190         *ap++ = inw(lan0 + i*4);
00191 
00192     DBG ( " I/O %4.4x %s ", ioaddr, eth_ntoa ( nic->node_addr ) );
00193 
00194     /* Find the connected MII xcvrs. */
00195     for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(phys); phy++) {
00196         int mii_status = mii_read(phy, 0);
00197 
00198         if (mii_status != 0xffff  && mii_status != 0x0000) {
00199             phys[phy_idx++] = phy;
00200 #if     (EPIC_DEBUG > 1)
00201             printf("MII transceiver found at address %d.\n", phy);
00202 #endif
00203         }
00204     }
00205     if (phy_idx == 0) {
00206 #if     (EPIC_DEBUG > 1)
00207         printf("***WARNING***: No MII transceiver found!\n");
00208 #endif
00209         /* Use the known PHY address of the EPII. */
00210         phys[0] = 3;
00211     }
00212 
00213     epic100_open();
00214     nic->nic_op = &epic100_operations;
00215 
00216     return 1;
00217 }

static void set_rx_mode ( void   )  [static]

Definition at line 219 of file epic100.c.

References mc0, memset(), outl, outw, and rxcon.

Referenced by epic100_open(), mtd_reset(), rhine_reset(), sundance_reset(), tulip_reset(), and w89c840_reset().

00220 {
00221         unsigned char mc_filter[8];
00222         int i;
00223         memset(mc_filter, 0xff, sizeof(mc_filter));
00224         outl(0x0C, rxcon);
00225         for(i = 0; i < 4; i++)
00226                 outw(((unsigned short *)mc_filter)[i], mc0 + i*4);
00227         return;
00228 }

static void epic100_disable ( struct nic *nic  __unused  )  [static]

Definition at line 425 of file epic100.c.

References GC_SOFT_RESET, genctl, and outl.

00425                                                          {
00426         /* Soft reset the chip. */
00427         outl(GC_SOFT_RESET, genctl);
00428 }

static void epic100_irq ( struct nic *nic  __unused,
irq_action_t action  __unused 
) [static]

Definition at line 430 of file epic100.c.

References DISABLE, ENABLE, and FORCE.

00431 {
00432   switch ( action ) {
00433   case DISABLE :
00434     break;
00435   case ENABLE :
00436     break;
00437   case FORCE :
00438     break;
00439   }
00440 }

PCI_DRIVER ( epic100_driver  ,
epic100_nics  ,
PCI_NO_CLASS   
)

DRIVER ( "EPIC100"  ,
nic_driver  ,
pci_driver  ,
epic100_driver  ,
epic100_probe  ,
epic100_disable   
)


Variable Documentation

static struct nic_operations epic100_operations [static, read]

Initial value:

 {
        .connect        = dummy_connect,
        .poll           = epic100_poll,
        .transmit       = epic100_transmit,
        .irq            = epic100_irq,

}

Definition at line 65 of file epic100.c.

Referenced by epic100_probe().

int ioaddr [static]

Definition at line 67 of file epic100.c.

int command [static]

Definition at line 69 of file epic100.c.

int intstat [static]

Definition at line 70 of file epic100.c.

Referenced by epic100_poll(), and epic100_probe().

int intmask [static]

Definition at line 71 of file epic100.c.

Referenced by epic100_probe().

int genctl [static]

Definition at line 72 of file epic100.c.

Referenced by epic100_disable(), epic100_open(), and epic100_probe().

int eectl [static]

Definition at line 73 of file epic100.c.

Referenced by epic100_probe().

int test [static]

int mmctl [static]

Definition at line 75 of file epic100.c.

Referenced by epic100_probe(), and mii_read().

int mmdata [static]

Definition at line 76 of file epic100.c.

Referenced by epic100_probe(), and mii_read().

int lan0 [static]

Definition at line 77 of file epic100.c.

Referenced by epic100_probe().

int mc0 [static]

Definition at line 78 of file epic100.c.

Referenced by epic100_probe(), and set_rx_mode().

int rxcon [static]

Definition at line 79 of file epic100.c.

Referenced by epic100_probe(), and set_rx_mode().

int txcon [static]

Definition at line 80 of file epic100.c.

Referenced by epic100_open(), and epic100_probe().

int prcdar [static]

Definition at line 81 of file epic100.c.

Referenced by epic100_open(), and epic100_probe().

int ptcdar [static]

Definition at line 82 of file epic100.c.

Referenced by epic100_open(), and epic100_probe().

int eththr [static]

Definition at line 83 of file epic100.c.

Referenced by epic100_open(), and epic100_probe().

unsigned int cur_rx [static]

unsigned int cur_tx [static]

Definition at line 85 of file epic100.c.

Referenced by epic100_init_ring(), epic100_transmit(), and ns83820_transmit().

signed char phys[4] [static]

Definition at line 89 of file epic100.c.

Referenced by epic100_open(), and epic100_probe().

struct epic_rx_desc rx_ring[RX_RING_SIZE]

Definition at line 91 of file epic100.c.

struct epic_tx_desc tx_ring[TX_RING_SIZE]

Definition at line 93 of file epic100.c.

unsigned char rx_packet[PKT_BUF_SZ *RX_RING_SIZE]

Definition at line 95 of file epic100.c.

unsigned char tx_packet[PKT_BUF_SZ *TX_RING_SIZE]

Definition at line 96 of file epic100.c.

struct { ... } __shared

struct pci_device_id epic100_nics[] [static]

Initial value:

 {
PCI_ROM(0x10b8, 0x0005, "epic100",    "SMC EtherPowerII", 0),           
PCI_ROM(0x10b8, 0x0006, "smc-83c175", "SMC EPIC/C 83c175", 0),
}

Definition at line 523 of file epic100.c.


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