#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 virt_to_le32desc | ( | addr | ) | cpu_to_le32(virt_to_bus(addr)) |
| #define le32desc_to_virt | ( | addr | ) | bus_to_virt(le32_to_cpu(addr)) |
| #define TD_STDFLAGS TD_LASTDESC |
| #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().
| #define rx_ring epic100_bufs.rx_ring |
Definition at line 98 of file epic100.c.
Referenced by alloc_rx(), atl1e_clean_rx_irq(), atl1e_clean_rx_ring(), atl1e_configure_des_ring(), atl1e_init_ring_ptrs(), atl1e_init_ring_resources(), atl1e_setup_ring_resources(), epic100_init_ring(), epic100_open(), epic100_poll(), forcedeth_poll(), forcedeth_reset(), init_ring(), ns83820_check_intr(), ns83820_poll(), ns83820_setup_rx(), refill_rx(), sundance_poll(), sundance_reset(), TLan_FinishReset(), tlan_poll(), TLan_ResetLists(), tulip_init_ring(), tulip_poll(), tulip_reset(), and velocity_open().
| #define tx_ring epic100_bufs.tx_ring |
Definition at line 99 of file epic100.c.
Referenced by atl1e_clean_tx_irq(), atl1e_clean_tx_ring(), atl1e_configure_des_ring(), atl1e_get_tpd(), atl1e_get_tx_buffer(), atl1e_init_ring_ptrs(), atl1e_init_ring_resources(), atl1e_setup_ring_resources(), atl1e_tpd_avail(), atl1e_tx_queue(), epic100_init_ring(), epic100_open(), epic100_transmit(), forcedeth_reset(), forcedeth_transmit(), init_ring(), ns83820_reset(), ns83820_transmit(), sundance_transmit(), tlan_probe(), TLan_ResetLists(), tlan_transmit(), tulip_init_ring(), tulip_reset(), tulip_transmit(), and velocity_open().
| #define rx_packet epic100_bufs.rx_packet |
| #define tx_packet epic100_bufs.tx_packet |
Definition at line 101 of file epic100.c.
Referenced by epic100_init_ring(), and epic100_transmit().
| #define MII_READOP 1 |
| 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 }
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] |
| PCI_DRIVER | ( | epic100_driver | , | |
| epic100_nics | , | |||
| PCI_NO_CLASS | ||||
| ) |
| DRIVER | ( | "EPIC100" | , | |
| nic_driver | , | |||
| pci_driver | , | |||
| epic100_driver | , | |||
| epic100_probe | , | |||
| epic100_disable | ||||
| ) |
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 intstat [static] |
int intmask [static] |
int genctl [static] |
Definition at line 72 of file epic100.c.
Referenced by epic100_disable(), epic100_open(), and epic100_probe().
int eectl [static] |
int test [static] |
Definition at line 74 of file epic100.c.
Referenced by check_region(), epic100_probe(), eth_probe(), exp_bit_is_one(), find_max_exp_index(), ne_probe(), and script_load().
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] |
Definition at line 85 of file epic100.c.
Referenced by epic100_init_ring(), epic100_poll(), ifec_refill_rx_ring(), ifec_reprime_ru(), ifec_rx_process(), sis190_process_rx(), sis900_init_rxd(), and sis900_poll().
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] |
| struct epic_rx_desc rx_ring[RX_RING_SIZE] |
| struct epic_tx_desc tx_ring[TX_RING_SIZE] |
| struct { ... } __shared |
struct pci_device_id epic100_nics[] [static] |
1.5.7.1