Lines Matching +full:100 +full:base +full:- +full:tx
9 * tlan.c -- Etherboot device driver for the Texas Instruments ThunderLAN
10 * Written 2003-2003 by Timothy Legge <tlegge@rogers.com>
31 * (C) 1997-1998 Caldera, Inc.
33 * (C) 1999-2001 Torben Mathiasen
38 * v1.0 07-08-2003 timlegge Initial not quite working version
39 * v1.1 07-27-2003 timlegge Sync 5.0 and 5.1 versions
40 * v1.2 08-19-2003 timlegge Implement Multicast Support
41 * v1.3 08-23-2003 timlegge Fix the transmit Function
42 * v1.4 01-17-2004 timlegge Initial driver output cleanup
44 * Indent Options: indent -kr -i8
57 #define drv_date "01-17-2004"
60 #define HZ 100
109 "10BaseT-HD ", "10BaseT-FD ", "100baseTx-HD ",
110 "100baseTx-FD", "100baseT4", 0
137 {"Compaq Netelligent 10/100 TX PCI UTP", NETEL100,
140 {"Compaq Integrated NetFlex-3/P", NETFLEX3I,
143 {"Compaq NetFlex-3/P", THUNDER,
146 {"Compaq NetFlex-3/P", NETFLEX3B,
149 {"Compaq Netelligent Integrated 10/100 TX UTP", NETEL100PI,
152 {"Compaq Netelligent Dual 10/100 TX PCI UTP", NETEL100D,
155 {"Compaq Netelligent 10/100 TX Embedded UTP", NETEL100I,
158 {"Olicom OC-2183/2185", OC2183,
161 {"Olicom OC-2325", OC2325,
164 {"Olicom OC-2326", OC2326,
167 {"Compaq Netelligent 10/100 TX UTP", NETELLIGENT_10_100_WS_5100,
173 {"Compaq NetFlex-3/E", 0, /* EISA card */
177 {"Compaq NetFlex-3/E", 0, /* EISA card */
255 u32 BASE; variable
278 priv->txHead = 0; in TLan_ResetLists()
279 priv->txTail = 0; in TLan_ResetLists()
283 list->cStat = TLAN_CSTAT_UNUSED; in TLan_ResetLists()
284 /* list->buffer[0].address = 0; */ in TLan_ResetLists()
285 list->buffer[0].address = virt_to_bus(txb + in TLan_ResetLists()
287 list->buffer[2].count = 0; in TLan_ResetLists()
288 list->buffer[2].address = 0; in TLan_ResetLists()
289 list->buffer[9].address = 0; in TLan_ResetLists()
290 /* list->forward = 0; */ in TLan_ResetLists()
293 priv->cur_rx = 0; in TLan_ResetLists()
294 priv->rx_buf_sz = (TLAN_MAX_FRAME_SIZE); in TLan_ResetLists()
295 priv->rx_head_desc = &rx_ring[0]; in TLan_ResetLists()
311 rx_ring[i - 1].forward = virt_to_le32desc(&rx_ring[0]); in TLan_ResetLists()
312 priv->dirty_rx = (unsigned int) (i - TLAN_NUM_RX_LISTS); in TLan_ResetLists()
326 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
340 priv->tlanFullDuplex = FALSE; in TLan_ResetAdapter()
341 priv->phyOnline = 0; in TLan_ResetAdapter()
344 data = inl(BASE + TLAN_HOST_CMD); in TLan_ResetAdapter()
346 outl(data, BASE + TLAN_HOST_CMD); in TLan_ResetAdapter()
352 data = inl(BASE + TLAN_HOST_CMD); in TLan_ResetAdapter()
354 outl(data, BASE + TLAN_HOST_CMD); in TLan_ResetAdapter()
358 TLan_DioWrite32(BASE, (u16) i, 0); in TLan_ResetAdapter()
365 TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data); in TLan_ResetAdapter()
369 outl(TLAN_HC_LD_TMR | 0x3f, BASE + TLAN_HOST_CMD); in TLan_ResetAdapter()
370 outl(TLAN_HC_LD_THR | 0x0, BASE + TLAN_HOST_CMD); in TLan_ResetAdapter()
374 outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR); in TLan_ResetAdapter()
375 addr = BASE + TLAN_DIO_DATA + TLAN_NET_SIO; in TLan_ResetAdapter()
380 if (priv->tlanRev >= 0x30) { in TLan_ResetAdapter()
382 TLan_DioWrite8(BASE, TLAN_INT_DIS, data8); in TLan_ResetAdapter()
389 if (priv->aui == 1) { in TLan_ResetAdapter()
390 TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x0a); in TLan_ResetAdapter()
391 } else if (priv->duplex == TLAN_DUPLEX_FULL) { in TLan_ResetAdapter()
392 TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x00); in TLan_ResetAdapter()
393 priv->tlanFullDuplex = TRUE; in TLan_ResetAdapter()
395 TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x08); in TLan_ResetAdapter()
399 if (priv->phyNum == 0) { in TLan_ResetAdapter()
402 TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data); in TLan_ResetAdapter()
425 phy = priv->phy[priv->phyNum]; in TLan_FinishReset()
428 if (priv->tlanFullDuplex) { in TLan_FinishReset()
431 TLan_DioWrite8(BASE, TLAN_NET_CMD, data); in TLan_FinishReset()
433 if (priv->phyNum == 0) { in TLan_FinishReset()
436 TLan_DioWrite8(BASE, TLAN_NET_MASK, data); in TLan_FinishReset()
437 TLan_DioWrite16(BASE, TLAN_MAX_RX, ((1536) + 7) & ~7); in TLan_FinishReset()
442 || (priv->aui)) { in TLan_FinishReset()
444 printf("TLAN: %s: Link forced.\n", priv->nic_name); in TLan_FinishReset()
457 priv->nic_name); in TLan_FinishReset()
459 printf("forced 10%sMbps %s-Duplex\n", in TLan_FinishReset()
466 ("AutoNegotiation enabled, at 10%sMbps %s-Duplex\n", in TLan_FinishReset()
474 printf("%s", media[i - 5]); in TLan_FinishReset()
478 TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK); in TLan_FinishReset()
481 priv->link = 1; in TLan_FinishReset()
488 printf("TLAN: %s: Link active\n", priv->nic_name); in TLan_FinishReset()
489 TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK); in TLan_FinishReset()
493 if (priv->phyNum == 0) { in TLan_FinishReset()
497 sio = TLan_DioRead8(BASE, TLAN_NET_SIO); in TLan_FinishReset()
499 TLan_DioWrite8(BASE, TLAN_NET_SIO, sio); in TLan_FinishReset()
503 TLan_SetMac(nic, 0, nic->node_addr); in TLan_FinishReset()
504 priv->phyOnline = 1; in TLan_FinishReset()
505 outb((TLAN_HC_INT_ON >> 8), BASE + TLAN_HOST_CMD + 1); in TLan_FinishReset()
507 outb( ( TLAN_HC_REQ_INT >> 8 ), BASE + TLAN_HOST_CMD + 1 ); in TLan_FinishReset()
511 outl(virt_to_bus(&rx_ring), BASE + TLAN_CH_PARM); in TLan_FinishReset()
512 outl(TLAN_HC_GO | TLAN_HC_RT, BASE + TLAN_HOST_CMD); in TLan_FinishReset()
516 priv->nic_name); in TLan_FinishReset()
527 POLL - Wait for a frame
532 /* nic->packet should contain data on return */ in tlan_poll()
533 /* nic->packetlen should contain length of data */ in tlan_poll()
538 int entry = priv->cur_rx % TLAN_NUM_RX_LISTS; in tlan_poll()
540 u16 host_int = inw(BASE + TLAN_HOST_INT); in tlan_poll()
545 outw(host_int, BASE + TLAN_HOST_INT); in tlan_poll()
550 /* printf("PI-1: 0x%hX\n", host_int); */ in tlan_poll()
556 nic->packetlen = framesize; in tlan_poll()
562 memcpy(nic->packet, rxb + in tlan_poll()
563 (priv->cur_rx * TLAN_MAX_FRAME_SIZE), nic->packetlen); in tlan_poll()
567 hex_dump(nic->packet, nic->packetlen); in tlan_poll()
571 priv->cur_rx = entry; in tlan_poll()
577 outl(host_cmd, BASE + TLAN_HOST_CMD); in tlan_poll()
581 outl(host_cmd, BASE + TLAN_HOST_CMD); in tlan_poll()
583 printf("AC: 0x%hX\n", inw(BASE + TLAN_CH_PARM)); in tlan_poll()
584 host_int = inw(BASE + TLAN_HOST_INT); in tlan_poll()
585 printf("PI-2: 0x%hX\n", host_int); in tlan_poll()
597 (priv->cur_rx - priv->dirty_rx + in refill_rx()
599 priv->dirty_rx = (priv->dirty_rx + 1) % TLAN_NUM_RX_LISTS) { in refill_rx()
600 entry = priv->dirty_rx % TLAN_NUM_TX_LISTS; in refill_rx()
609 TRANSMIT - Transmit a frame
626 u16 host_int = inw(BASE + TLAN_HOST_INT); in tlan_transmit()
631 printf("INT0-0x%hX\n", host_int); in tlan_transmit()
634 if (!priv->phyOnline) { in tlan_transmit()
635 printf("TRANSMIT: %s PHY is not ready\n", priv->nic_name); in tlan_transmit()
639 tail_list = priv->txList + priv->txTail; in tlan_transmit()
641 if (tail_list->cStat != TLAN_CSTAT_UNUSED) { in tlan_transmit()
643 priv->nic_name, priv->txList, priv->txTail); in tlan_transmit()
645 priv->txBusyCount++; in tlan_transmit()
649 tail_list->forward = 0; in tlan_transmit()
651 tail_buffer = txb + (priv->txTail * TLAN_MAX_FRAME_SIZE); in tlan_transmit()
655 memcpy(tail_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN); in tlan_transmit()
684 tail_list->frameSize = (u16) s; in tlan_transmit()
685 tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) s; in tlan_transmit()
686 tail_list->buffer[1].count = 0; in tlan_transmit()
687 tail_list->buffer[1].address = 0; in tlan_transmit()
689 tail_list->cStat = TLAN_CSTAT_READY; in tlan_transmit()
692 host_int = inw(BASE + TLAN_HOST_INT); in tlan_transmit()
693 printf("INT1-0x%hX\n", host_int); in tlan_transmit()
696 if (!priv->txInProgress) { in tlan_transmit()
697 priv->txInProgress = 1; in tlan_transmit()
698 outl(virt_to_le32desc(tail_list), BASE + TLAN_CH_PARM); in tlan_transmit()
699 outl(TLAN_HC_GO, BASE + TLAN_HOST_CMD); in tlan_transmit()
701 if (priv->txTail == 0) { in tlan_transmit()
705 (priv->txList + (TLAN_NUM_TX_LISTS - 1))->forward = in tlan_transmit()
711 (priv->txList + (priv->txTail - 1))->forward = in tlan_transmit()
716 CIRC_INC(priv->txTail, TLAN_NUM_TX_LISTS); in tlan_transmit()
719 host_int = inw(BASE + TLAN_HOST_INT); in tlan_transmit()
720 printf("INT2-0x%hX\n", host_int); in tlan_transmit()
724 while ((tail_list->cStat == TLAN_CSTAT_READY) && currticks() < to); in tlan_transmit()
726 head_list = priv->txList + priv->txHead; in tlan_transmit()
727 while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) in tlan_transmit()
732 head_list->cStat = TLAN_CSTAT_UNUSED; in tlan_transmit()
733 CIRC_INC(priv->txHead, TLAN_NUM_TX_LISTS); in tlan_transmit()
734 head_list = priv->txList + priv->txHead; in tlan_transmit()
738 printf("Incomplete TX Frame\n"); in tlan_transmit()
741 head_list = priv->txList + priv->txHead; in tlan_transmit()
742 if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) { in tlan_transmit()
743 outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM); in tlan_transmit()
746 priv->txInProgress = 0; in tlan_transmit()
751 outl(host_cmd, BASE + TLAN_HOST_CMD); in tlan_transmit()
754 if(priv->tlanRev < 0x30 ) { in tlan_transmit()
756 head_list = priv->txList + priv->txHead; in tlan_transmit()
757 if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) { in tlan_transmit()
758 outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM); in tlan_transmit()
761 priv->txInProgress = 0; in tlan_transmit()
764 outl(host_cmd, BASE + TLAN_HOST_CMD); in tlan_transmit()
769 printf("TX Time Out"); in tlan_transmit()
774 DISABLE - Turn off ethernet interface
793 outl(TLAN_HC_AD_RST, BASE + TLAN_HOST_CMD); in tlan_disable()
797 IRQ - Enable, Disable, or Force interrupts
816 tmp = TLan_DioRead8(BASE, TLAN_NET_CMD); in TLan_SetMulticastList()
817 TLan_DioWrite8(BASE, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF); in TLan_SetMulticastList()
822 TLan_DioWrite32(BASE, TLAN_HASH_1, 0xFFFFFFFF); in TLan_SetMulticastList()
823 TLan_DioWrite32(BASE, TLAN_HASH_2, 0xFFFFFFFF); in TLan_SetMulticastList()
828 PROBE - Look for an adapter, this routine's visible to the outside
845 if (pci->ioaddr == 0)
848 nic->irqno = 0;
849 nic->ioaddr = pci->ioaddr & ~3;
851 BASE = pci->ioaddr;
855 pci->name, pci->vendor, pci->dev_id);
865 chip_idx = -1;
868 if ((((u32) pci->dev_id << 16) | pci->vendor) ==
876 priv->vendor_id = pci->vendor;
877 priv->dev_id = pci->dev_id;
878 priv->nic_name = pci->name;
879 priv->eoc = 0;
883 err |= TLan_EeReadByte(BASE,
886 (u8 *) & nic->node_addr[i]);
889 pci->name, err);
891 printf("\nAddress: %!\n", nic->node_addr);
893 priv->tlanRev = TLan_DioRead8(BASE, TLAN_DEF_REVISION);
894 printf("\nRevision = 0x%hX\n", priv->tlanRev);
899 data = inl(BASE + TLAN_HOST_CMD);
901 outw(data, BASE + TLAN_HOST_CMD);
904 data = inl(BASE + TLAN_HOST_CMD);
906 outw(data, BASE + TLAN_HOST_CMD);
909 udelay(100);
910 priv->txList = tx_ring;
911 priv->rxList = rx_ring;
916 dev->disable = tlan_disable;
917 nic->poll = tlan_poll;
918 nic->transmit = tlan_transmit;
919 nic->irq = tlan_irq;
922 nic->disable = tlan_disable;
923 nic->poll = tlan_poll;
924 nic->transmit = tlan_transmit;
925 nic->irq = tlan_irq;
936 The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A
951 * io_base The IO port base address for the
983 * Parms: io_base The IO port base address for the
1009 /* Assume clock is low, tx is enabled; */
1043 * io_base The IO port base address for the
1070 /* Assume clock is low, tx is enabled; */
1104 * io_base The IO port base address for the
1155 "ThunderLAN Programmer's Guide", pp. 15-24.
1180 * and then reads the 16-bit register value from the MII bus via
1194 outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);
1195 sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;
1197 TLan_MiiSync(BASE);
1203 TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */
1204 TLan_MiiSendData(BASE, 0x2, 2); /* Read ( 10b ) */
1205 TLan_MiiSendData(BASE, phy, 5); /* Device # */
1206 TLan_MiiSendData(BASE, reg, 5); /* Register # */
1252 * base_port The base IO port of the adapter in
1276 for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {
1298 * base_port The base IO port of the adapter in
1340 * writes the 16-bit register value from the MII configuration bus
1350 outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);
1351 sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;
1353 TLan_MiiSync(BASE);
1359 TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */
1360 TLan_MiiSendData(BASE, 0x1, 2); /* Write ( 01b ) */
1361 TLan_MiiSendData(BASE, phy, 5); /* Device # */
1362 TLan_MiiSendData(BASE, reg, 5); /* Register # */
1364 TLan_MiiSendData(BASE, 0x2, 2); /* Send ACK */
1365 TLan_MiiSendData(BASE, val, 16); /* Send Data */
1384 * areg The AREG to set the address in (0 - 3).
1405 TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i,
1409 TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i, 0);
1439 priv->phyNum = 0xFFFF;
1446 priv->phy[0] = TLAN_PHY_MAX_ADDR;
1448 priv->phy[0] = TLAN_PHY_NONE;
1451 priv->phy[1] = TLAN_PHY_NONE;
1460 if ((priv->phy[1] == TLAN_PHY_NONE)
1462 priv->phy[1] = phy;
1467 if (priv->phy[1] != TLAN_PHY_NONE) {
1468 priv->phyNum = 1;
1469 } else if (priv->phy[0] != TLAN_PHY_NONE) {
1470 priv->phyNum = 0;
1482 printf("%s: Powering down PHY(s).\n", priv->nic_name);
1484 TLan_MiiSync(BASE);
1485 TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_GEN_CTL, value);
1486 if ((priv->phyNum == 0) && (priv->phy[1] != TLAN_PHY_NONE)
1490 TLan_MiiSync(BASE);
1491 TLan_MiiWriteReg(nic, priv->phy[1], MII_GEN_CTL, value);
1509 printf("%s: Powering up PHY.\n", priv->nic_name);
1510 TLan_MiiSync(BASE);
1512 TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_GEN_CTL, value);
1513 TLan_MiiSync(BASE);
1529 phy = priv->phy[priv->phyNum];
1531 printf("%s: Reseting PHY.\n", priv->nic_name);
1532 TLan_MiiSync(BASE);
1561 phy = priv->phy[priv->phyNum];
1562 printf("%s: Trying to activate link.\n", priv->nic_name);
1566 if ((status & MII_GS_AUTONEG) && (!priv->aui)) {
1568 if (priv->speed == TLAN_SPEED_10 &&
1569 priv->duplex == TLAN_DUPLEX_HALF) {
1571 } else if (priv->speed == TLAN_SPEED_10 &&
1572 priv->duplex == TLAN_DUPLEX_FULL) {
1573 priv->tlanFullDuplex = TRUE;
1575 } else if (priv->speed == TLAN_SPEED_100 &&
1576 priv->duplex == TLAN_DUPLEX_HALF) {
1578 } else if (priv->speed == TLAN_SPEED_100 &&
1579 priv->duplex == TLAN_DUPLEX_FULL) {
1580 priv->tlanFullDuplex = TRUE;
1584 /* Set Auto-Neg advertisement */
1587 /* Enablee Auto-Neg */
1589 /* Restart Auto-Neg */
1597 priv->nic_name);
1606 if ((priv->aui) && (priv->phyNum != 0)) {
1607 priv->phyNum = 0;
1611 TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data);
1616 } else if (priv->phyNum == 0) {
1619 if (priv->aui) {
1623 if (priv->duplex == TLAN_DUPLEX_FULL) {
1625 priv->tlanFullDuplex = TRUE;
1627 if (priv->speed == TLAN_SPEED_100) {
1654 phy = priv->phy[priv->phyNum];
1664 if (!priv->neg_be_verbose++) {
1680 printf("TLAN: %s: Autonegotiation complete.\n", priv->nic_name);
1686 priv->tlanFullDuplex = TRUE;
1688 priv->tlanFullDuplex = TRUE;
1694 && (priv->phyNum != 0)) {
1695 priv->phyNum = 0;
1699 TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data);
1706 if (priv->phyNum == 0) {
1707 if ((priv->duplex == TLAN_DUPLEX_FULL)
1712 ("TLAN: Starting internal PHY with FULL-DUPLEX\n");
1717 ("TLAN: Starting internal PHY with HALF-DUPLEX\n");
1721 /* Wait for 100 ms. No reason in partiticular.
1724 mdelay(100);
1751 TLanPrivateInfo *priv = dev->priv;
1755 phy = priv->phy[priv->phyNum];
1762 if (priv->link) {
1763 priv->link = 0;
1764 printf("TLAN: %s has lost link\n", priv->nic_name);
1765 priv->flags &= ~IFF_RUNNING;
1774 if ((phy_status & MII_GS_LINK) && !priv->link) {
1775 priv->link = 1;
1777 priv->nic_name);
1778 priv->flags |= IFF_RUNNING;
1792 PCI_ROM(0x0e11, 0xae32, "netel100","Compaq Netelligent 10/100 TX PCI UTP"),
1793 PCI_ROM(0x0e11, 0xae35, "netflex3i", "Compaq Integrated NetFlex-3/P"),
1794 PCI_ROM(0x0e11, 0xf130, "thunder", "Compaq NetFlex-3/P"),
1795 PCI_ROM(0x0e11, 0xf150, "netflex3b", "Compaq NetFlex-3/P"),
1796 PCI_ROM(0x0e11, 0xae43, "netel100pi", "Compaq Netelligent Integrated 10/100 TX UTP"),
1797 PCI_ROM(0x0e11, 0xae40, "netel100d", "Compaq Netelligent Dual 10/100 TX PCI UTP"),
1798 PCI_ROM(0x0e11, 0xb011, "netel100i", "Compaq Netelligent 10/100 TX Embedded UTP"),
1799 PCI_ROM(0x108d, 0x0013, "oc2183", "Olicom OC-2183/2185"),
1800 PCI_ROM(0x108d, 0x0012, "oc2325", "Olicom OC-2325"),
1801 PCI_ROM(0x108d, 0x0014, "oc2326", "Olicom OC-2326"),
1802 PCI_ROM(0x0e11, 0xb030, "netelligent_10_100_ws_5100", "Compaq Netelligent 10/100 TX UTP"),