#include "etherboot.h"#include "nic.h"#include <gpxe/pci.h>#include <gpxe/ethernet.h>#include "mii.h"Go to the source code of this file.
Data Structures | |
| struct | pcnet32_rx_head |
| struct | pcnet32_tx_head |
| struct | pcnet32_init_block |
| struct | pcnet32_access |
| struct | pcnet32_private |
Defines | |
| #define | drv_version "v1.3" |
| #define | drv_date "03-29-2004" |
| #define | dprintf(x) |
| #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 | PCNET32_PORT_AUI 0x00 |
| #define | PCNET32_PORT_10BT 0x01 |
| #define | PCNET32_PORT_GPSI 0x02 |
| #define | PCNET32_PORT_MII 0x03 |
| #define | PCNET32_PORT_PORTSEL 0x03 |
| #define | PCNET32_PORT_ASEL 0x04 |
| #define | PCNET32_PORT_100 0x40 |
| #define | PCNET32_PORT_FD 0x80 |
| #define | PCNET32_DMA_MASK 0xffffffff |
| #define | MAX_UNITS 8 |
| #define | PCNET32_LOG_TX_BUFFERS 1 |
| #define | PCNET32_LOG_RX_BUFFERS 2 |
| #define | TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS)) |
| #define | TX_RING_MOD_MASK (TX_RING_SIZE - 1) |
| #define | TX_RING_LEN_BITS 0x0000 |
| #define | RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS)) |
| #define | RX_RING_MOD_MASK (RX_RING_SIZE - 1) |
| #define | RX_RING_LEN_BITS ((PCNET32_LOG_RX_BUFFERS) << 4) |
| #define | PKT_BUF_SZ 1544 |
| #define | PCNET32_WIO_RDP 0x10 |
| #define | PCNET32_WIO_RAP 0x12 |
| #define | PCNET32_WIO_RESET 0x14 |
| #define | PCNET32_WIO_BDP 0x16 |
| #define | PCNET32_DWIO_RDP 0x10 |
| #define | PCNET32_DWIO_RAP 0x14 |
| #define | PCNET32_DWIO_RESET 0x18 |
| #define | PCNET32_DWIO_BDP 0x1C |
| #define | PCNET32_TOTAL_SIZE 0x20 |
| #define | MII_CNT 4 |
Enumerations | |
| enum | pci_flags_bit { PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, PCI_ADDR0 = 0x10 << 0, PCI_ADDR1 = 0x10 << 1, PCI_ADDR2, PCI_ADDR3 = 0x10 << 3 } |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static int | mdio_read (struct nic *nic __unused, int phy_id, int reg_num) |
| static u16 | pcnet32_wio_read_csr (unsigned long addr, int index) |
| static void | pcnet32_wio_write_csr (unsigned long addr, int index, u16 val) |
| static u16 | pcnet32_wio_read_bcr (unsigned long addr, int index) |
| static void | pcnet32_wio_write_bcr (unsigned long addr, int index, u16 val) |
| static u16 | pcnet32_wio_read_rap (unsigned long addr) |
| static void | pcnet32_wio_write_rap (unsigned long addr, u16 val) |
| static void | pcnet32_wio_reset (unsigned long addr) |
| static int | pcnet32_wio_check (unsigned long addr) |
| static u16 | pcnet32_dwio_read_csr (unsigned long addr, int index) |
| static void | pcnet32_dwio_write_csr (unsigned long addr, int index, u16 val) |
| static u16 | pcnet32_dwio_read_bcr (unsigned long addr, int index) |
| static void | pcnet32_dwio_write_bcr (unsigned long addr, int index, u16 val) |
| static u16 | pcnet32_dwio_read_rap (unsigned long addr) |
| static void | pcnet32_dwio_write_rap (unsigned long addr, u16 val) |
| static void | pcnet32_dwio_reset (unsigned long addr) |
| static int | pcnet32_dwio_check (unsigned long addr) |
| static int | pcnet32_init_ring (struct nic *nic) |
| static void | pcnet32_reset (struct nic *nic) |
| static int | pcnet32_poll (struct nic *nic __unused, int retrieve) |
| static void | pcnet32_transmit (struct nic *nic __unused, const char *d, unsigned int t, unsigned int s, const char *p) |
| static void | pcnet32_disable (struct nic *nic __unused) |
| static void | pcnet32_irq (struct nic *nic __unused, irq_action_t action __unused) |
| static int | pcnet32_probe (struct nic *nic, struct pci_device *pci) |
| PCI_DRIVER (pcnet32_driver, pcnet32_nics, PCI_NO_CLASS) | |
| DRIVER ("PCNET32/PCI", nic_driver, pci_driver, pcnet32_driver, pcnet32_probe, pcnet32_disable) | |
Variables | |
| static u32 | ioaddr |
| static struct nic_operations | pcnet32_operations |
| static int | cards_found = 0 |
| static unsigned char | options_mapping [] |
| static int | options [MAX_UNITS] |
| static int | full_duplex [MAX_UNITS] |
| struct { | |
| struct pcnet32_tx_head tx_ring [TX_RING_SIZE] | |
| struct pcnet32_rx_head rx_ring [RX_RING_SIZE] | |
| unsigned char txb [TX_RING_SIZE][PKT_BUF_SZ] | |
| unsigned char rxb [RX_RING_SIZE][PKT_BUF_SZ] | |
| } | __shared |
| struct pcnet32_private | lpx |
| static struct pcnet32_private * | lp |
| static struct pcnet32_access | pcnet32_wio |
| static struct pcnet32_access | pcnet32_dwio |
| static struct pci_device_id | pcnet32_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 PCNET32_PORT_AUI 0x00 |
| #define PCNET32_PORT_GPSI 0x02 |
| #define PCNET32_PORT_PORTSEL 0x03 |
| #define PCNET32_PORT_ASEL 0x04 |
| #define PCNET32_PORT_100 0x40 |
| #define PCNET32_PORT_FD 0x80 |
| #define MAX_UNITS 8 |
| #define TX_RING_LEN_BITS 0x0000 |
| #define RX_RING_MOD_MASK (RX_RING_SIZE - 1) |
| #define RX_RING_LEN_BITS ((PCNET32_LOG_RX_BUFFERS) << 4) |
| #define PCNET32_WIO_RDP 0x10 |
Definition at line 164 of file pcnet32.c.
Referenced by pcnet32_wio_read_csr(), and pcnet32_wio_write_csr().
| #define PCNET32_WIO_RAP 0x12 |
Definition at line 165 of file pcnet32.c.
Referenced by pcnet32_wio_check(), pcnet32_wio_read_bcr(), pcnet32_wio_read_csr(), pcnet32_wio_read_rap(), pcnet32_wio_write_bcr(), pcnet32_wio_write_csr(), and pcnet32_wio_write_rap().
| #define PCNET32_WIO_RESET 0x14 |
| #define PCNET32_WIO_BDP 0x16 |
Definition at line 167 of file pcnet32.c.
Referenced by pcnet32_wio_read_bcr(), and pcnet32_wio_write_bcr().
| #define PCNET32_DWIO_RDP 0x10 |
Definition at line 169 of file pcnet32.c.
Referenced by pcnet32_dwio_read_csr(), and pcnet32_dwio_write_csr().
| #define PCNET32_DWIO_RAP 0x14 |
Definition at line 170 of file pcnet32.c.
Referenced by pcnet32_dwio_check(), pcnet32_dwio_read_bcr(), pcnet32_dwio_read_csr(), pcnet32_dwio_read_rap(), pcnet32_dwio_write_bcr(), pcnet32_dwio_write_csr(), and pcnet32_dwio_write_rap().
| #define PCNET32_DWIO_RESET 0x18 |
| #define PCNET32_DWIO_BDP 0x1C |
Definition at line 172 of file pcnet32.c.
Referenced by pcnet32_dwio_read_bcr(), and pcnet32_dwio_write_bcr().
| #define MII_CNT 4 |
| enum pci_flags_bit |
Definition at line 259 of file pcnet32.c.
00259 { 00260 PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, 00261 PCI_ADDR0 = 0x10 << 0, PCI_ADDR1 = 0x10 << 1, PCI_ADDR2 = 00262 0x10 << 2, PCI_ADDR3 = 0x10 << 3, 00263 };
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
Definition at line 960 of file pcnet32.c.
References pcnet32_private::a, 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, pcnet32_private::mii, outl, pcnet32_access::read_bcr, u16, whereami(), and pcnet32_access::write_bcr.
00961 { 00962 u16 val_out; 00963 int phyaddr; 00964 00965 if (!lp->mii) 00966 return 0; 00967 00968 phyaddr = lp->a.read_bcr(ioaddr, 33); 00969 00970 lp->a.write_bcr(ioaddr, 33, 00971 ((phy_id & 0x1f) << 5) | (reg_num & 0x1f)); 00972 val_out = lp->a.read_bcr(ioaddr, 34); 00973 lp->a.write_bcr(ioaddr, 33, phyaddr); 00974 00975 return val_out; 00976 }
| static u16 pcnet32_wio_read_csr | ( | unsigned long | addr, | |
| int | index | |||
| ) | [static] |
Definition at line 266 of file pcnet32.c.
References inw, outw, PCNET32_WIO_RAP, and PCNET32_WIO_RDP.
Referenced by pcnet32_probe().
00267 { 00268 outw(index, addr + PCNET32_WIO_RAP); 00269 return inw(addr + PCNET32_WIO_RDP); 00270 }
| static void pcnet32_wio_write_csr | ( | unsigned long | addr, | |
| int | index, | |||
| u16 | val | |||
| ) | [static] |
Definition at line 272 of file pcnet32.c.
References outw, PCNET32_WIO_RAP, and PCNET32_WIO_RDP.
00273 { 00274 outw(index, addr + PCNET32_WIO_RAP); 00275 outw(val, addr + PCNET32_WIO_RDP); 00276 }
| static u16 pcnet32_wio_read_bcr | ( | unsigned long | addr, | |
| int | index | |||
| ) | [static] |
Definition at line 278 of file pcnet32.c.
References inw, outw, PCNET32_WIO_BDP, and PCNET32_WIO_RAP.
00279 { 00280 outw(index, addr + PCNET32_WIO_RAP); 00281 return inw(addr + PCNET32_WIO_BDP); 00282 }
| static void pcnet32_wio_write_bcr | ( | unsigned long | addr, | |
| int | index, | |||
| u16 | val | |||
| ) | [static] |
Definition at line 284 of file pcnet32.c.
References outw, PCNET32_WIO_BDP, and PCNET32_WIO_RAP.
00285 { 00286 outw(index, addr + PCNET32_WIO_RAP); 00287 outw(val, addr + PCNET32_WIO_BDP); 00288 }
| static u16 pcnet32_wio_read_rap | ( | unsigned long | addr | ) | [static] |
Definition at line 290 of file pcnet32.c.
References inw, and PCNET32_WIO_RAP.
00291 { 00292 return inw(addr + PCNET32_WIO_RAP); 00293 }
| static void pcnet32_wio_write_rap | ( | unsigned long | addr, | |
| u16 | val | |||
| ) | [static] |
Definition at line 295 of file pcnet32.c.
References outw, and PCNET32_WIO_RAP.
00296 { 00297 outw(val, addr + PCNET32_WIO_RAP); 00298 }
| static void pcnet32_wio_reset | ( | unsigned long | addr | ) | [static] |
Definition at line 300 of file pcnet32.c.
References inw, and PCNET32_WIO_RESET.
Referenced by pcnet32_probe().
00301 { 00302 inw(addr + PCNET32_WIO_RESET); 00303 }
| static int pcnet32_wio_check | ( | unsigned long | addr | ) | [static] |
Definition at line 305 of file pcnet32.c.
References inw, outw, and PCNET32_WIO_RAP.
Referenced by pcnet32_probe().
00306 { 00307 outw(88, addr + PCNET32_WIO_RAP); 00308 return (inw(addr + PCNET32_WIO_RAP) == 88); 00309 }
| static u16 pcnet32_dwio_read_csr | ( | unsigned long | addr, | |
| int | index | |||
| ) | [static] |
Definition at line 321 of file pcnet32.c.
References inl, outl, PCNET32_DWIO_RAP, and PCNET32_DWIO_RDP.
Referenced by pcnet32_probe().
00322 { 00323 outl(index, addr + PCNET32_DWIO_RAP); 00324 return (inl(addr + PCNET32_DWIO_RDP) & 0xffff); 00325 }
| static void pcnet32_dwio_write_csr | ( | unsigned long | addr, | |
| int | index, | |||
| u16 | val | |||
| ) | [static] |
Definition at line 327 of file pcnet32.c.
References outl, PCNET32_DWIO_RAP, and PCNET32_DWIO_RDP.
00328 { 00329 outl(index, addr + PCNET32_DWIO_RAP); 00330 outl(val, addr + PCNET32_DWIO_RDP); 00331 }
| static u16 pcnet32_dwio_read_bcr | ( | unsigned long | addr, | |
| int | index | |||
| ) | [static] |
Definition at line 333 of file pcnet32.c.
References inl, outl, PCNET32_DWIO_BDP, and PCNET32_DWIO_RAP.
00334 { 00335 outl(index, addr + PCNET32_DWIO_RAP); 00336 return (inl(addr + PCNET32_DWIO_BDP) & 0xffff); 00337 }
| static void pcnet32_dwio_write_bcr | ( | unsigned long | addr, | |
| int | index, | |||
| u16 | val | |||
| ) | [static] |
Definition at line 339 of file pcnet32.c.
References outl, PCNET32_DWIO_BDP, and PCNET32_DWIO_RAP.
00340 { 00341 outl(index, addr + PCNET32_DWIO_RAP); 00342 outl(val, addr + PCNET32_DWIO_BDP); 00343 }
| static u16 pcnet32_dwio_read_rap | ( | unsigned long | addr | ) | [static] |
Definition at line 345 of file pcnet32.c.
References inl, and PCNET32_DWIO_RAP.
00346 { 00347 return (inl(addr + PCNET32_DWIO_RAP) & 0xffff); 00348 }
| static void pcnet32_dwio_write_rap | ( | unsigned long | addr, | |
| u16 | val | |||
| ) | [static] |
Definition at line 350 of file pcnet32.c.
References outl, and PCNET32_DWIO_RAP.
00351 { 00352 outl(val, addr + PCNET32_DWIO_RAP); 00353 }
| static void pcnet32_dwio_reset | ( | unsigned long | addr | ) | [static] |
Definition at line 355 of file pcnet32.c.
References inl, and PCNET32_DWIO_RESET.
Referenced by pcnet32_probe().
00356 { 00357 inl(addr + PCNET32_DWIO_RESET); 00358 }
| static int pcnet32_dwio_check | ( | unsigned long | addr | ) | [static] |
Definition at line 360 of file pcnet32.c.
References inl, outl, and PCNET32_DWIO_RAP.
Referenced by pcnet32_probe().
00361 { 00362 outl(88, addr + PCNET32_DWIO_RAP); 00363 return ((inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88); 00364 }
| static int pcnet32_init_ring | ( | struct nic * | nic | ) | [static] |
Definition at line 378 of file pcnet32.c.
References pcnet32_private::cur_rx, pcnet32_private::cur_tx, pcnet32_private::init_block, le16_to_cpu, nic::node_addr, pcnet32_init_block::phys_addr, PKT_BUF_SZ, pcnet32_init_block::rx_ring, RX_RING_LEN_BITS, RX_RING_SIZE, pcnet32_init_block::tlen_rlen, pcnet32_private::tx_full, pcnet32_init_block::tx_ring, TX_RING_LEN_BITS, TX_RING_SIZE, and virt_to_le32desc.
Referenced by pcnet32_reset().
00379 { 00380 int i; 00381 00382 lp->tx_full = 0; 00383 lp->cur_rx = lp->cur_tx = 0; 00384 00385 for (i = 0; i < RX_RING_SIZE; i++) { 00386 pcnet32_bufs.rx_ring[i].base = 00387 virt_to_le32desc(&pcnet32_bufs.rxb[i]); 00388 pcnet32_bufs.rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ); 00389 pcnet32_bufs.rx_ring[i].status = le16_to_cpu(0x8000); 00390 } 00391 00392 /* The Tx buffer address is filled in as needed, but we do need to clear 00393 the upper ownership bit. */ 00394 for (i = 0; i < TX_RING_SIZE; i++) { 00395 pcnet32_bufs.tx_ring[i].base = 0; 00396 pcnet32_bufs.tx_ring[i].status = 0; 00397 } 00398 00399 00400 lp->init_block.tlen_rlen = 00401 le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); 00402 for (i = 0; i < 6; i++) 00403 lp->init_block.phys_addr[i] = nic->node_addr[i]; 00404 lp->init_block.rx_ring = virt_to_le32desc(&pcnet32_bufs.rx_ring[0]); 00405 lp->init_block.tx_ring = virt_to_le32desc(&pcnet32_bufs.tx_ring[0]); 00406 return 0; 00407 }
| static void pcnet32_reset | ( | struct nic * | nic | ) | [static] |
Definition at line 412 of file pcnet32.c.
References pcnet32_private::a, dprintf, pcnet32_private::dxsuflo, pcnet32_init_block::filter, pcnet32_private::full_duplex, pcnet32_private::init_block, ioaddr, le16_to_cpu, pcnet32_private::ltint, pcnet32_private::mii, pcnet32_init_block::mode, pcnet32_private::options, pcnet32_init_ring(), PCNET32_PORT_100, PCNET32_PORT_ASEL, PCNET32_PORT_AUI, PCNET32_PORT_FD, PCNET32_PORT_GPSI, PCNET32_PORT_PORTSEL, pcnet32_access::read_bcr, pcnet32_access::read_csr, pcnet32_access::reset, u16, virt_to_bus(), pcnet32_access::write_bcr, and pcnet32_access::write_csr.
Referenced by pcnet32_probe().
00413 { 00414 /* put the card in its initial state */ 00415 u16 val; 00416 int i; 00417 00418 /* Reset the PCNET32 */ 00419 lp->a.reset(ioaddr); 00420 00421 /* switch pcnet32 to 32bit mode */ 00422 lp->a.write_bcr(ioaddr, 20, 2); 00423 00424 /* set/reset autoselect bit */ 00425 val = lp->a.read_bcr(ioaddr, 2) & ~2; 00426 if (lp->options & PCNET32_PORT_ASEL) 00427 val |= 2; 00428 lp->a.write_bcr(ioaddr, 2, val); 00429 00430 /* handle full duplex setting */ 00431 if (lp->full_duplex) { 00432 val = lp->a.read_bcr(ioaddr, 9) & ~3; 00433 if (lp->options & PCNET32_PORT_FD) { 00434 val |= 1; 00435 if (lp->options == 00436 (PCNET32_PORT_FD | PCNET32_PORT_AUI)) 00437 val |= 2; 00438 } else if (lp->options & PCNET32_PORT_ASEL) { 00439 /* workaround of xSeries250, turn on for 79C975 only */ 00440 i = ((lp->a. 00441 read_csr(ioaddr, 00442 88) | (lp->a.read_csr(ioaddr, 00443 89) << 16)) >> 00444 12) & 0xffff; 00445 if (i == 0x2627) 00446 val |= 3; 00447 } 00448 lp->a.write_bcr(ioaddr, 9, val); 00449 } 00450 00451 /* set/reset GPSI bit in test register */ 00452 val = lp->a.read_csr(ioaddr, 124) & ~0x10; 00453 if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI) 00454 val |= 0x10; 00455 lp->a.write_csr(ioaddr, 124, val); 00456 00457 if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) { 00458 val = lp->a.read_bcr(ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */ 00459 if (lp->options & PCNET32_PORT_FD) 00460 val |= 0x10; 00461 if (lp->options & PCNET32_PORT_100) 00462 val |= 0x08; 00463 lp->a.write_bcr(ioaddr, 32, val); 00464 } else { 00465 if (lp->options & PCNET32_PORT_ASEL) { /* enable auto negotiate, setup, disable fd */ 00466 val = lp->a.read_bcr(ioaddr, 32) & ~0x98; 00467 val |= 0x20; 00468 lp->a.write_bcr(ioaddr, 32, val); 00469 } 00470 } 00471 00472 #ifdef DO_DXSUFLO 00473 if (lp->dxsuflo) { /* Disable transmit stop on underflow */ 00474 val = lp->a.read_csr(ioaddr, 3); 00475 val |= 0x40; 00476 lp->a.write_csr(ioaddr, 3, val); 00477 } 00478 #endif 00479 if (1) 00480 { 00481 //disable interrupts 00482 val = lp->a.read_csr(ioaddr, 3); 00483 val = val 00484 | (1 << 14) //BABLM intr disabled 00485 | (1 << 12) //MISSM missed frame mask intr disabled 00486 | (1 << 10) //RINTM receive intr disabled 00487 | (1 << 9) //TINTM transmit intr disabled 00488 | (1 << 8) //IDONM init done intr disabled 00489 ; 00490 lp->a.write_csr(ioaddr, 3, val); 00491 } 00492 00493 if (lp->ltint) { /* Enable TxDone-intr inhibitor */ 00494 val = lp->a.read_csr(ioaddr, 5); 00495 val |= (1 << 14); 00496 lp->a.write_csr(ioaddr, 5, val); 00497 } 00498 lp->init_block.mode = 00499 le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); 00500 lp->init_block.filter[0] = 0xffffffff; 00501 lp->init_block.filter[1] = 0xffffffff; 00502 00503 pcnet32_init_ring(nic); 00504 00505 00506 /* Re-initialize the PCNET32, and start it when done. */ 00507 lp->a.write_csr(ioaddr, 1, 00508 (virt_to_bus(&lp->init_block)) & 0xffff); 00509 lp->a.write_csr(ioaddr, 2, (virt_to_bus(&lp->init_block)) >> 16); 00510 lp->a.write_csr(ioaddr, 4, 0x0915); 00511 lp->a.write_csr(ioaddr, 0, 0x0001); 00512 00513 00514 i = 0; 00515 while (i++ < 100) 00516 if (lp->a.read_csr(ioaddr, 0) & 0x0100) 00517 break; 00518 /* 00519 * We used to clear the InitDone bit, 0x0100, here but Mark Stockton 00520 * reports that doing so triggers a bug in the '974. 00521 */ 00522 lp->a.write_csr(ioaddr, 0, 0x0042); 00523 00524 dprintf(("pcnet32 open, csr0 %hX.\n", lp->a.read_csr(ioaddr, 0))); 00525 00526 }
Definition at line 531 of file pcnet32.c.
References pcnet32_private::cur_rx, entry, le16_to_cpu, le32_to_cpu, memcpy, PKT_BUF_SZ, and RX_RING_MOD_MASK.
00532 { 00533 /* return true if there's an ethernet packet ready to read */ 00534 /* nic->packet should contain data on return */ 00535 /* nic->packetlen should contain length of data */ 00536 00537 signed char status; 00538 int entry; 00539 00540 entry = lp->cur_rx & RX_RING_MOD_MASK; 00541 status = (le16_to_cpu(pcnet32_bufs.rx_ring[entry].status) >> 8); 00542 00543 if (status < 0) 00544 return 0; 00545 00546 if ( ! retrieve ) return 1; 00547 00548 if (status == 0x03) { 00549 nic->packetlen = 00550 (le32_to_cpu(pcnet32_bufs.rx_ring[entry].msg_length) 00551 & 0xfff) - 4; 00552 memcpy(nic->packet, &pcnet32_bufs.rxb[entry], nic->packetlen); 00553 00554 /* Andrew Boyd of QNX reports that some revs of the 79C765 00555 * clear the buffer length */ 00556 pcnet32_bufs.rx_ring[entry].buf_length 00557 = le16_to_cpu(-PKT_BUF_SZ); 00558 /* prime for next receive */ 00559 pcnet32_bufs.rx_ring[entry].status |= le16_to_cpu(0x8000); 00560 /* Switch to the next Rx ring buffer */ 00561 lp->cur_rx++; 00562 00563 } else { 00564 return 0; 00565 } 00566 00567 return 1; 00568 }
| static void pcnet32_transmit | ( | struct nic *nic | __unused, | |
| const char * | d, | |||
| unsigned int | t, | |||
| unsigned int | s, | |||
| const char * | p | |||
| ) | [static] |
Definition at line 573 of file pcnet32.c.
References pcnet32_private::a, pcnet32_private::cur_tx, currticks(), entry, ETH_ALEN, ETH_HLEN, ETH_ZLEN, htons, ioaddr, le16_to_cpu, memcpy, printf(), TICKS_PER_SEC, time(), u16, u32, u8, virt_to_le32desc, and pcnet32_access::write_csr.
00577 { /* Packet */ 00578 /* send the packet to destination */ 00579 unsigned long time; 00580 u8 *ptxb; 00581 u16 nstype; 00582 u16 status; 00583 int entry = 0; /*lp->cur_tx & TX_RING_MOD_MASK; */ 00584 00585 status = 0x8300; 00586 /* point to the current txb incase multiple tx_rings are used */ 00587 ptxb = pcnet32_bufs.txb[lp->cur_tx]; 00588 00589 /* copy the packet to ring buffer */ 00590 memcpy(ptxb, d, ETH_ALEN); /* dst */ 00591 memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ 00592 nstype = htons((u16) t); /* type */ 00593 memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */ 00594 memcpy(ptxb + ETH_HLEN, p, s); 00595 00596 s += ETH_HLEN; 00597 while (s < ETH_ZLEN) /* pad to min length */ 00598 ptxb[s++] = '\0'; 00599 00600 pcnet32_bufs.tx_ring[entry].length = le16_to_cpu(-s); 00601 pcnet32_bufs.tx_ring[entry].misc = 0x00000000; 00602 pcnet32_bufs.tx_ring[entry].base = (u32) virt_to_le32desc(ptxb); 00603 00604 /* we set the top byte as the very last thing */ 00605 pcnet32_bufs.tx_ring[entry].status = le16_to_cpu(status); 00606 00607 00608 /* Trigger an immediate send poll */ 00609 lp->a.write_csr(ioaddr, 0, 0x0048); 00610 00611 /* wait for transmit complete */ 00612 lp->cur_tx = 0; /* (lp->cur_tx + 1); */ 00613 time = currticks() + TICKS_PER_SEC; /* wait one second */ 00614 while (currticks() < time && 00615 ((short) le16_to_cpu(pcnet32_bufs.tx_ring[entry].status) < 0)); 00616 00617 if ((short) le16_to_cpu(pcnet32_bufs.tx_ring[entry].status) < 0) 00618 printf("PCNET32 timed out on transmit\n"); 00619 00620 /* Stop pointing at the current txb 00621 * otherwise the card continues to send the packet */ 00622 pcnet32_bufs.tx_ring[entry].base = 0; 00623 00624 }
Definition at line 629 of file pcnet32.c.
References pcnet32_private::a, ioaddr, pcnet32_access::write_bcr, and pcnet32_access::write_csr.
00629 { 00630 /* Stop the PCNET32 here -- it ocassionally polls memory if we don't */ 00631 lp->a.write_csr(ioaddr, 0, 0x0004); 00632 00633 /* 00634 * Switch back to 16-bit mode to avoid problems with dumb 00635 * DOS packet driver after a warm reboot 00636 */ 00637 lp->a.write_bcr(ioaddr, 20, 0); 00638 }
| static void pcnet32_irq | ( | struct nic *nic | __unused, | |
| irq_action_t action | __unused | |||
| ) | [static] |
| static int pcnet32_probe | ( | struct nic * | nic, | |
| struct pci_device * | pci | |||
| ) | [static] |
Definition at line 660 of file pcnet32.c.
References pcnet32_private::a, adjust_pci_device(), ADVERTISE_100FULL, ADVERTISE_100HALF, ADVERTISE_10FULL, ADVERTISE_10HALF, mii_if_info::advertising, cards_found, DBG, pci_device::device, dprintf, pci_device::driver_name, pcnet32_private::dxsuflo, ETH_ALEN, eth_ntoa(), pcnet32_init_block::filter, full_duplex, pcnet32_private::full_duplex, inb, pcnet32_private::init_block, nic::ioaddr, ioaddr, pci_device::ioaddr, nic::irqno, le16_to_cpu, lpx, pcnet32_private::ltint, MAX_UNITS, mdio_read(), media, memcpy, pcnet32_private::mii, mii, MII_ADVERTISE, MII_BMSR, MII_CNT, pcnet32_private::mii_if, MII_LPA, pcnet32_init_block::mode, pcnet32_private::name, nic::nic_op, nic::node_addr, NULL, pcnet32_private::options, options, options_mapping, pcnet32_dwio_check(), pcnet32_dwio_read_csr(), pcnet32_dwio_reset(), pcnet32_operations, PCNET32_PORT_ASEL, PCNET32_PORT_FD, PCNET32_PORT_GPSI, pcnet32_reset(), pcnet32_wio_check(), pcnet32_wio_read_csr(), pcnet32_wio_reset(), mii_if_info::phy_id, pcnet32_private::phys, pcnet32_init_block::phys_addr, printf(), pcnet32_access::read_bcr, pcnet32_access::read_csr, pcnet32_init_block::rx_ring, RX_RING_LEN_BITS, pcnet32_private::shared_irq, pcnet32_init_block::tlen_rlen, pcnet32_init_block::tx_ring, TX_RING_LEN_BITS, u16, u8, pci_device::vendor, virt_to_bus(), pcnet32_access::write_bcr, and pcnet32_access::write_csr.
00660 { 00661 00662 int i, media; 00663 int fdx, mii, fset, dxsuflo, ltint; 00664 int chip_version; 00665 struct pcnet32_access *a = NULL; 00666 char *chipname; 00667 u8 promaddr[6]; 00668 int shared = 1; 00669 00670 if (pci->ioaddr == 0) 00671 return 0; 00672 00673 /* BASE is used throughout to address the card */ 00674 ioaddr = pci->ioaddr; 00675 printf("pcnet32.c: Found %s, Vendor=0x%hX Device=0x%hX\n", 00676 pci->driver_name, pci->vendor, pci->device); 00677 00678 nic->irqno = 0; 00679 nic->ioaddr = pci->ioaddr & ~3; 00680 00681 /* reset the chip */ 00682 pcnet32_wio_reset(ioaddr); 00683 00684 /* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */ 00685 if (pcnet32_wio_read_csr(ioaddr, 0) == 4 00686 && pcnet32_wio_check(ioaddr)) { 00687 a = &pcnet32_wio; 00688 } else { 00689 pcnet32_dwio_reset(ioaddr); 00690 if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 00691 && pcnet32_dwio_check(ioaddr)) { 00692 a = &pcnet32_dwio; 00693 } else 00694 return 0; 00695 } 00696 00697 chip_version = 00698 a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr, 89) << 16); 00699 00700 dprintf(("PCnet chip version is 0x%X\n", chip_version)); 00701 if ((chip_version & 0xfff) != 0x003) 00702 return 0; 00703 00704 /* initialize variables */ 00705 fdx = mii = fset = dxsuflo = ltint = 0; 00706 chip_version = (chip_version >> 12) & 0xffff; 00707 00708 switch (chip_version) { 00709 case 0x2420: 00710 chipname = "PCnet/PCI 79C970"; /* PCI */ 00711 break; 00712 case 0x2430: 00713 if (shared) 00714 chipname = "PCnet/PCI 79C970"; /* 970 gives the wrong chip id back */ 00715 else 00716 chipname = "PCnet/32 79C965"; /* 486/VL bus */ 00717 break; 00718 case 0x2621: 00719 chipname = "PCnet/PCI II 79C970A"; /* PCI */ 00720 fdx = 1; 00721 break; 00722 case 0x2623: 00723 chipname = "PCnet/FAST 79C971"; /* PCI */ 00724 fdx = 1; 00725 mii = 1; 00726 fset = 1; 00727 ltint = 1; 00728 break; 00729 case 0x2624: 00730 chipname = "PCnet/FAST+ 79C972"; /* PCI */ 00731 fdx = 1; 00732 mii = 1; 00733 fset = 1; 00734 break; 00735 case 0x2625: 00736 chipname = "PCnet/FAST III 79C973"; /* PCI */ 00737 fdx = 1; 00738 mii = 1; 00739 break; 00740 case 0x2626: 00741 chipname = "PCnet/Home 79C978"; /* PCI */ 00742 fdx = 1; 00743 /* 00744 * This is based on specs published at www.amd.com. This section 00745 * assumes that a card with a 79C978 wants to go into 1Mb HomePNA 00746 * mode. The 79C978 can also go into standard ethernet, and there 00747 * probably should be some sort of module option to select the 00748 * mode by which the card should operate 00749 */ 00750 /* switch to home wiring mode */ 00751 media = a->read_bcr(ioaddr, 49); 00752 00753 printf("media reset to %#x.\n", media); 00754 a->write_bcr(ioaddr, 49, media); 00755 break; 00756 case 0x2627: 00757 chipname = "PCnet/FAST III 79C975"; /* PCI */ 00758 fdx = 1; 00759 mii = 1; 00760 break; 00761 default: 00762 chipname = "UNKNOWN"; 00763 printf("PCnet version %#x, no PCnet32 chip.\n", 00764 chip_version); 00765 return 0; 00766 } 00767 00768 /* 00769 * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit 00770 * starting until the packet is loaded. Strike one for reliability, lose 00771 * one for latency - although on PCI this isnt a big loss. Older chips 00772 * have FIFO's smaller than a packet, so you can't do this. 00773 */ 00774 00775 if (fset) { 00776 a->write_bcr(ioaddr, 18, 00777 (a->read_bcr(ioaddr, 18) | 0x0800)); 00778 a->write_csr(ioaddr, 80, 00779 (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00); 00780 dxsuflo = 1; 00781 ltint = 1; 00782 } 00783 00784 DBG ( "%s at %hX,", chipname, (unsigned int) ioaddr ); 00785 00786 /* read PROM address */ 00787 for (i = 0; i < 6; i++) 00788 promaddr[i] = inb(ioaddr + i); 00789 00790 /* Update the nic structure with the MAC Address */ 00791 for (i = 0; i < ETH_ALEN; i++) { 00792 nic->node_addr[i] = promaddr[i]; 00793 } 00794 00795 /* Print out some hardware info */ 00796 DBG ( "%s: IO Addr 0x%hX, MAC Addr %s\n ", chipname, (unsigned int) ioaddr, 00797 eth_ntoa ( nic->node_addr ) ); 00798 00799 /* Set to pci bus master */ 00800 adjust_pci_device(pci); 00801 00802 /* point to private storage */ 00803 lp = &lpx; 00804 00805 #if EBDEBUG 00806 if (((chip_version + 1) & 0xfffe) == 0x2624) { /* Version 0x2623 or 0x2624 */ 00807 i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */ 00808 dprintf((" tx_start_pt(0x%hX):", i)); 00809 switch (i >> 10) { 00810 case 0: 00811 dprintf((" 20 bytes,")); 00812 break; 00813 case 1: 00814 dprintf((" 64 bytes,")); 00815 break; 00816 case 2: 00817 dprintf((" 128 bytes,")); 00818 break; 00819 case 3: 00820 dprintf(("~220 bytes,")); 00821 break; 00822 } 00823 i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */ 00824 dprintf((" BCR18(%hX):", i & 0xffff)); 00825 if (i & (1 << 5)) 00826 dprintf(("BurstWrEn ")); 00827 if (i & (1 << 6)) 00828 dprintf(("BurstRdEn ")); 00829 if (i & (1 << 7)) 00830 dprintf(("DWordIO ")); 00831 if (i & (1 << 11)) 00832 dprintf(("NoUFlow ")); 00833 i = a->read_bcr(ioaddr, 25); 00834 dprintf((" SRAMSIZE=0x%hX,", i << 8)); 00835 i = a->read_bcr(ioaddr, 26); 00836 dprintf((" SRAM_BND=0x%hX,", i << 8)); 00837 i = a->read_bcr(ioaddr, 27); 00838 if (i & (1 << 14)) 00839 dprintf(("LowLatRx")); 00840 } 00841 #endif 00842 lp->name = chipname; 00843 lp->shared_irq = shared; 00844 lp->full_duplex = fdx; 00845 lp->dxsuflo = dxsuflo; 00846 lp->ltint = ltint; 00847 lp->mii = mii; 00848 /* FIXME: Fix Options for only one card */ 00849 if ((cards_found >= MAX_UNITS) 00850 || ((unsigned int) options[cards_found] > sizeof(options_mapping))) 00851 lp->options = PCNET32_PORT_ASEL; 00852 else 00853 lp->options = options_mapping[options[cards_found]]; 00854 00855 if (fdx && !(lp->options & PCNET32_PORT_ASEL) && 00856 ((cards_found >= MAX_UNITS) || full_duplex[cards_found])) 00857 lp->options |= PCNET32_PORT_FD; 00858 00859 if (!a) { 00860 printf("No access methods\n"); 00861 return 0; 00862 } 00863 00864 // lp->a = *a; 00865 // Causes a loader: 00866 // bin/blib.a(pcnet32.o)(.text+0x6b6): In function `pcnet32_probe': 00867 // drivers/net/pcnet32.c:871: undefined reference to `memcpy' 00868 // make: *** [bin/pcnet32.dsk.tmp] Error 1 00869 // So we do: 00870 memcpy ( &lp->a, a, sizeof ( lp->a ) ); 00871 // To explicity call memcpy. 00872 00873 /* detect special T1/E1 WAN card by checking for MAC address */ 00874 if (nic->node_addr[0] == 0x00 && nic->node_addr[1] == 0xe0 00875 && nic->node_addr[2] == 0x75) 00876 lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI; 00877 00878 lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */ 00879 lp->init_block.tlen_rlen = 00880 le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); 00881 for (i = 0; i < 6; i++) 00882 lp->init_block.phys_addr[i] = nic->node_addr[i]; 00883 lp->init_block.filter[0] = 0xffffffff; 00884 lp->init_block.filter[1] = 0xffffffff; 00885 lp->init_block.rx_ring = virt_to_bus(&pcnet32_bufs.rx_ring); 00886 lp->init_block.tx_ring = virt_to_bus(&pcnet32_bufs.tx_ring); 00887 00888 /* switch pcnet32 to 32bit mode */ 00889 a->write_bcr(ioaddr, 20, 2); 00890 00891 a->write_csr(ioaddr, 1, (virt_to_bus(&lp->init_block)) & 0xffff); 00892 a->write_csr(ioaddr, 2, (virt_to_bus(&lp->init_block)) >> 16); 00893 00894 /* 00895 * To auto-IRQ we enable the initialization-done and DMA error 00896 * interrupts. For ISA boards we get a DMA error, but VLB and PCI 00897 * boards will work. 00898 */ 00899 /* Trigger an initialization just for the interrupt. */ 00900 00901 00902 // a->write_csr(ioaddr, 0, 0x41); 00903 // mdelay(1); 00904 00905 cards_found++; 00906 00907 /* point to NIC specific routines */ 00908 pcnet32_reset(nic); 00909 if (mii) { 00910 int tmp; 00911 int phy, phy_idx = 0; 00912 u16 mii_lpa; 00913 lp->phys[0] = 1; /* Default Setting */ 00914 for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) { 00915 int mii_status = mdio_read(nic, phy, MII_BMSR); 00916 if (mii_status != 0xffff && mii_status != 0x0000) { 00917 lp->phys[phy_idx++] = phy; 00918 lp->mii_if.advertising = 00919 mdio_read(nic, phy, MII_ADVERTISE); 00920 if ((mii_status & 0x0040) == 0) { 00921 tmp = phy; 00922 dprintf (("MII PHY found at address %d, status " 00923 "%hX advertising %hX\n", phy, mii_status, 00924 lp->mii_if.advertising)); 00925 } 00926 } 00927 } 00928 if (phy_idx == 0) 00929 printf("No MII transceiver found!\n"); 00930 lp->mii_if.phy_id = lp->phys[0]; 00931 00932 lp->mii_if.advertising = 00933 mdio_read(nic, lp->phys[0], MII_ADVERTISE); 00934 00935 mii_lpa = mdio_read(nic, lp->phys[0], MII_LPA); 00936 lp->mii_if.advertising &= mii_lpa; 00937 if (lp->mii_if.advertising & ADVERTISE_100FULL) 00938 printf("100Mbps Full-Duplex\n"); 00939 else if (lp->mii_if.advertising & ADVERTISE_100HALF) 00940 printf("100Mbps Half-Duplex\n"); 00941 else if (lp->mii_if.advertising & ADVERTISE_10FULL) 00942 printf("10Mbps Full-Duplex\n"); 00943 else if (lp->mii_if.advertising & ADVERTISE_10HALF) 00944 printf("10Mbps Half-Duplex\n"); 00945 else 00946 printf("\n"); 00947 } else { 00948 /* The older chips are fixed 10Mbps, and some support full duplex, 00949 * although not via autonegotiation, but only via configuration. */ 00950 if (fdx) 00951 printf("10Mbps Full-Duplex\n"); 00952 else 00953 printf("10Mbps Half-Duplex\n"); 00954 } 00955 00956 nic->nic_op = &pcnet32_operations; 00957 00958 return 1; 00959 }
| PCI_DRIVER | ( | pcnet32_driver | , | |
| pcnet32_nics | , | |||
| PCI_NO_CLASS | ||||
| ) |
| DRIVER | ( | "PCNET32/PCI" | , | |
| nic_driver | , | |||
| pci_driver | , | |||
| pcnet32_driver | , | |||
| pcnet32_probe | , | |||
| pcnet32_disable | ||||
| ) |
static struct nic_operations pcnet32_operations [static, read] |
Initial value:
{
.connect = dummy_connect,
.poll = pcnet32_poll,
.transmit = pcnet32_transmit,
.irq = pcnet32_irq,
}
Definition at line 57 of file pcnet32.c.
Referenced by pcnet32_probe().
int cards_found = 0 [static] |
unsigned char options_mapping[] [static] |
Initial value:
{
PCNET32_PORT_ASEL,
PCNET32_PORT_AUI,
PCNET32_PORT_AUI,
PCNET32_PORT_ASEL,
PCNET32_PORT_10BT | PCNET32_PORT_FD,
PCNET32_PORT_ASEL,
PCNET32_PORT_ASEL,
PCNET32_PORT_ASEL,
PCNET32_PORT_ASEL,
PCNET32_PORT_MII,
PCNET32_PORT_MII | PCNET32_PORT_FD,
PCNET32_PORT_MII,
PCNET32_PORT_10BT,
PCNET32_PORT_MII | PCNET32_PORT_100,
PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD,
PCNET32_PORT_ASEL
}
Definition at line 107 of file pcnet32.c.
Referenced by pcnet32_probe().
int full_duplex[MAX_UNITS] [static] |
Definition at line 128 of file pcnet32.c.
Referenced by epic100_open(), mentormac_init(), and pcnet32_probe().
| struct pcnet32_tx_head tx_ring[TX_RING_SIZE] |
| struct pcnet32_rx_head rx_ring[RX_RING_SIZE] |
| struct { ... } __shared |
| struct pcnet32_private lpx |
Referenced by pcnet32_probe().
struct pcnet32_private* lp [static] |
struct pcnet32_access pcnet32_wio [static] |
struct pcnet32_access pcnet32_dwio [static] |
struct pci_device_id pcnet32_nics[] [static] |
1.5.7.1