|
|
1.1 ! root 1: /************************************************************************** ! 2: * ! 3: * tlan.c -- Etherboot device driver for the Texas Instruments ThunderLAN ! 4: * Written 2003-2003 by Timothy Legge <[email protected]> ! 5: * ! 6: * This program is free software; you can redistribute it and/or modify ! 7: * it under the terms of the GNU General Public License as published by ! 8: * the Free Software Foundation; either version 2 of the License, or ! 9: * (at your option) any later version. ! 10: * ! 11: * This program is distributed in the hope that it will be useful, ! 12: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: * GNU General Public License for more details. ! 15: * ! 16: * You should have received a copy of the GNU General Public License ! 17: * along with this program; if not, write to the Free Software ! 18: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 19: * ! 20: * Portions of this code based on: ! 21: * lan.c: Linux ThunderLan Driver: ! 22: * ! 23: * by James Banks ! 24: * ! 25: * (C) 1997-1998 Caldera, Inc. ! 26: * (C) 1998 James Banks ! 27: * (C) 1999-2001 Torben Mathiasen ! 28: * (C) 2002 Samuel Chessman ! 29: * ! 30: * REVISION HISTORY: ! 31: * ================ ! 32: * v1.0 07-08-2003 timlegge Initial not quite working version ! 33: * v1.1 07-27-2003 timlegge Sync 5.0 and 5.1 versions ! 34: * v1.2 08-19-2003 timlegge Implement Multicast Support ! 35: * v1.3 08-23-2003 timlegge Fix the transmit Function ! 36: * v1.4 01-17-2004 timlegge Initial driver output cleanup ! 37: * ! 38: * Indent Options: indent -kr -i8 ! 39: ***************************************************************************/ ! 40: ! 41: FILE_LICENCE ( GPL2_OR_LATER ); ! 42: ! 43: #include "etherboot.h" ! 44: #include "nic.h" ! 45: #include <ipxe/pci.h> ! 46: #include <ipxe/ethernet.h> ! 47: #include <mii.h> ! 48: #include "tlan.h" ! 49: ! 50: #define drv_version "v1.4" ! 51: #define drv_date "01-17-2004" ! 52: ! 53: /* NIC specific static variables go here */ ! 54: #define HZ 100 ! 55: #define TX_TIME_OUT (6*HZ) ! 56: ! 57: /* Condensed operations for readability. */ ! 58: #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) ! 59: #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) ! 60: ! 61: static void TLan_ResetLists(struct nic *nic __unused); ! 62: static void TLan_ResetAdapter(struct nic *nic __unused); ! 63: static void TLan_FinishReset(struct nic *nic __unused); ! 64: ! 65: static void TLan_EeSendStart(u16); ! 66: static int TLan_EeSendByte(u16, u8, int); ! 67: static void TLan_EeReceiveByte(u16, u8 *, int); ! 68: static int TLan_EeReadByte(u16 io_base, u8, u8 *); ! 69: ! 70: static void TLan_PhyDetect(struct nic *nic); ! 71: static void TLan_PhyPowerDown(struct nic *nic); ! 72: static void TLan_PhyPowerUp(struct nic *nic); ! 73: ! 74: ! 75: static void TLan_SetMac(struct nic *nic __unused, int areg, unsigned char *mac); ! 76: ! 77: static void TLan_PhyReset(struct nic *nic); ! 78: static void TLan_PhyStartLink(struct nic *nic); ! 79: static void TLan_PhyFinishAutoNeg(struct nic *nic); ! 80: ! 81: #ifdef MONITOR ! 82: static void TLan_PhyMonitor(struct nic *nic); ! 83: #endif ! 84: ! 85: ! 86: static void refill_rx(struct nic *nic __unused); ! 87: ! 88: static int TLan_MiiReadReg(struct nic *nic __unused, u16, u16, u16 *); ! 89: static void TLan_MiiSendData(u16, u32, unsigned); ! 90: static void TLan_MiiSync(u16); ! 91: static void TLan_MiiWriteReg(struct nic *nic __unused, u16, u16, u16); ! 92: ! 93: ! 94: static const char *media[] = { ! 95: "10BaseT-HD ", "10BaseT-FD ", "100baseTx-HD ", ! 96: "100baseTx-FD", "100baseT4", 0 ! 97: }; ! 98: ! 99: /* This much match tlan_pci_tbl[]! */ ! 100: enum tlan_nics { ! 101: NETEL10 = 0, NETEL100 = 1, NETFLEX3I = 2, THUNDER = 3, NETFLEX3B = ! 102: 4, NETEL100PI = 5, ! 103: NETEL100D = 6, NETEL100I = 7, OC2183 = 8, OC2325 = 9, OC2326 = ! 104: 10, NETELLIGENT_10_100_WS_5100 = 11, ! 105: NETELLIGENT_10_T2 = 12 ! 106: }; ! 107: ! 108: struct pci_id_info { ! 109: const char *name; ! 110: int nic_id; ! 111: struct match_info { ! 112: u32 pci, pci_mask, subsystem, subsystem_mask; ! 113: u32 revision, revision_mask; /* Only 8 bits. */ ! 114: } id; ! 115: u32 flags; ! 116: u16 addrOfs; /* Address Offset */ ! 117: }; ! 118: ! 119: static const struct pci_id_info tlan_pci_tbl[] = { ! 120: {"Compaq Netelligent 10 T PCI UTP", NETEL10, ! 121: {0xae340e11, 0xffffffff, 0, 0, 0, 0}, ! 122: TLAN_ADAPTER_ACTIVITY_LED, 0x83}, ! 123: {"Compaq Netelligent 10/100 TX PCI UTP", NETEL100, ! 124: {0xae320e11, 0xffffffff, 0, 0, 0, 0}, ! 125: TLAN_ADAPTER_ACTIVITY_LED, 0x83}, ! 126: {"Compaq Integrated NetFlex-3/P", NETFLEX3I, ! 127: {0xae350e11, 0xffffffff, 0, 0, 0, 0}, ! 128: TLAN_ADAPTER_NONE, 0x83}, ! 129: {"Compaq NetFlex-3/P", THUNDER, ! 130: {0xf1300e11, 0xffffffff, 0, 0, 0, 0}, ! 131: TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83}, ! 132: {"Compaq NetFlex-3/P", NETFLEX3B, ! 133: {0xf1500e11, 0xffffffff, 0, 0, 0, 0}, ! 134: TLAN_ADAPTER_NONE, 0x83}, ! 135: {"Compaq Netelligent Integrated 10/100 TX UTP", NETEL100PI, ! 136: {0xae430e11, 0xffffffff, 0, 0, 0, 0}, ! 137: TLAN_ADAPTER_ACTIVITY_LED, 0x83}, ! 138: {"Compaq Netelligent Dual 10/100 TX PCI UTP", NETEL100D, ! 139: {0xae400e11, 0xffffffff, 0, 0, 0, 0}, ! 140: TLAN_ADAPTER_NONE, 0x83}, ! 141: {"Compaq Netelligent 10/100 TX Embedded UTP", NETEL100I, ! 142: {0xb0110e11, 0xffffffff, 0, 0, 0, 0}, ! 143: TLAN_ADAPTER_NONE, 0x83}, ! 144: {"Olicom OC-2183/2185", OC2183, ! 145: {0x0013108d, 0xffffffff, 0, 0, 0, 0}, ! 146: TLAN_ADAPTER_USE_INTERN_10, 0x83}, ! 147: {"Olicom OC-2325", OC2325, ! 148: {0x0012108d, 0xffffffff, 0, 0, 0, 0}, ! 149: TLAN_ADAPTER_UNMANAGED_PHY, 0xF8}, ! 150: {"Olicom OC-2326", OC2326, ! 151: {0x0014108d, 0xffffffff, 0, 0, 0, 0}, ! 152: TLAN_ADAPTER_USE_INTERN_10, 0xF8}, ! 153: {"Compaq Netelligent 10/100 TX UTP", NETELLIGENT_10_100_WS_5100, ! 154: {0xb0300e11, 0xffffffff, 0, 0, 0, 0}, ! 155: TLAN_ADAPTER_ACTIVITY_LED, 0x83}, ! 156: {"Compaq Netelligent 10 T/2 PCI UTP/Coax", NETELLIGENT_10_T2, ! 157: {0xb0120e11, 0xffffffff, 0, 0, 0, 0}, ! 158: TLAN_ADAPTER_NONE, 0x83}, ! 159: {"Compaq NetFlex-3/E", 0, /* EISA card */ ! 160: {0, 0, 0, 0, 0, 0}, ! 161: TLAN_ADAPTER_ACTIVITY_LED | TLAN_ADAPTER_UNMANAGED_PHY | ! 162: TLAN_ADAPTER_BIT_RATE_PHY, 0x83}, ! 163: {"Compaq NetFlex-3/E", 0, /* EISA card */ ! 164: {0, 0, 0, 0, 0, 0}, ! 165: TLAN_ADAPTER_ACTIVITY_LED, 0x83}, ! 166: {0, 0, ! 167: {0, 0, 0, 0, 0, 0}, ! 168: 0, 0}, ! 169: }; ! 170: ! 171: struct TLanList { ! 172: u32 forward; ! 173: u16 cStat; ! 174: u16 frameSize; ! 175: struct { ! 176: u32 count; ! 177: u32 address; ! 178: } buffer[TLAN_BUFFERS_PER_LIST]; ! 179: }; ! 180: ! 181: struct { ! 182: struct TLanList tx_ring[TLAN_NUM_TX_LISTS]; ! 183: unsigned char txb[TLAN_MAX_FRAME_SIZE * TLAN_NUM_TX_LISTS]; ! 184: struct TLanList rx_ring[TLAN_NUM_RX_LISTS]; ! 185: unsigned char rxb[TLAN_MAX_FRAME_SIZE * TLAN_NUM_RX_LISTS]; ! 186: } tlan_buffers __shared; ! 187: #define tx_ring tlan_buffers.tx_ring ! 188: #define txb tlan_buffers.txb ! 189: #define rx_ring tlan_buffers.rx_ring ! 190: #define rxb tlan_buffers.rxb ! 191: ! 192: typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE]; ! 193: ! 194: static int chip_idx; ! 195: ! 196: /***************************************************************** ! 197: * TLAN Private Information Structure ! 198: * ! 199: ****************************************************************/ ! 200: static struct tlan_private { ! 201: unsigned short vendor_id; /* PCI Vendor code */ ! 202: unsigned short dev_id; /* PCI Device code */ ! 203: const char *nic_name; ! 204: unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indicies */ ! 205: unsigned rx_buf_sz; /* Based on mtu + Slack */ ! 206: struct TLanList *txList; ! 207: u32 txHead; ! 208: u32 txInProgress; ! 209: u32 txTail; ! 210: int eoc; ! 211: u32 phyOnline; ! 212: u32 aui; ! 213: u32 duplex; ! 214: u32 phy[2]; ! 215: u32 phyNum; ! 216: u32 speed; ! 217: u8 tlanRev; ! 218: u8 tlanFullDuplex; ! 219: u8 link; ! 220: u8 neg_be_verbose; ! 221: } TLanPrivateInfo; ! 222: ! 223: static struct tlan_private *priv; ! 224: ! 225: static u32 BASE; ! 226: ! 227: /*************************************************************** ! 228: * TLan_ResetLists ! 229: * ! 230: * Returns: ! 231: * Nothing ! 232: * Parms: ! 233: * dev The device structure with the list ! 234: * stuctures to be reset. ! 235: * ! 236: * This routine sets the variables associated with managing ! 237: * the TLAN lists to their initial values. ! 238: * ! 239: **************************************************************/ ! 240: ! 241: static void TLan_ResetLists(struct nic *nic __unused) ! 242: { ! 243: ! 244: int i; ! 245: struct TLanList *list; ! 246: priv->txHead = 0; ! 247: priv->txTail = 0; ! 248: ! 249: for (i = 0; i < TLAN_NUM_TX_LISTS; i++) { ! 250: list = &tx_ring[i]; ! 251: list->cStat = TLAN_CSTAT_UNUSED; ! 252: list->buffer[0].address = virt_to_bus(txb + ! 253: (i * TLAN_MAX_FRAME_SIZE)); ! 254: list->buffer[2].count = 0; ! 255: list->buffer[2].address = 0; ! 256: list->buffer[9].address = 0; ! 257: } ! 258: ! 259: priv->cur_rx = 0; ! 260: priv->rx_buf_sz = (TLAN_MAX_FRAME_SIZE); ! 261: // priv->rx_head_desc = &rx_ring[0]; ! 262: ! 263: /* Initialize all the Rx descriptors */ ! 264: for (i = 0; i < TLAN_NUM_RX_LISTS; i++) { ! 265: rx_ring[i].forward = virt_to_le32desc(&rx_ring[i + 1]); ! 266: rx_ring[i].cStat = TLAN_CSTAT_READY; ! 267: rx_ring[i].frameSize = TLAN_MAX_FRAME_SIZE; ! 268: rx_ring[i].buffer[0].count = ! 269: TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER; ! 270: rx_ring[i].buffer[0].address = ! 271: virt_to_le32desc(&rxb[i * TLAN_MAX_FRAME_SIZE]); ! 272: rx_ring[i].buffer[1].count = 0; ! 273: rx_ring[i].buffer[1].address = 0; ! 274: } ! 275: ! 276: /* Mark the last entry as wrapping the ring */ ! 277: rx_ring[i - 1].forward = virt_to_le32desc(&rx_ring[0]); ! 278: priv->dirty_rx = (unsigned int) (i - TLAN_NUM_RX_LISTS); ! 279: ! 280: } /* TLan_ResetLists */ ! 281: ! 282: /*************************************************************** ! 283: * TLan_Reset ! 284: * ! 285: * Returns: ! 286: * 0 ! 287: * Parms: ! 288: * dev Pointer to device structure of adapter ! 289: * to be reset. ! 290: * ! 291: * This function resets the adapter and it's physical ! 292: * device. See Chap. 3, pp. 9-10 of the "ThunderLAN ! 293: * Programmer's Guide" for details. The routine tries to ! 294: * implement what is detailed there, though adjustments ! 295: * have been made. ! 296: * ! 297: **************************************************************/ ! 298: ! 299: void TLan_ResetAdapter(struct nic *nic __unused) ! 300: { ! 301: int i; ! 302: u32 addr; ! 303: u32 data; ! 304: u8 data8; ! 305: ! 306: priv->tlanFullDuplex = FALSE; ! 307: priv->phyOnline = 0; ! 308: /* 1. Assert reset bit. */ ! 309: ! 310: data = inl(BASE + TLAN_HOST_CMD); ! 311: data |= TLAN_HC_AD_RST; ! 312: outl(data, BASE + TLAN_HOST_CMD); ! 313: ! 314: udelay(1000); ! 315: ! 316: /* 2. Turn off interrupts. ( Probably isn't necessary ) */ ! 317: ! 318: data = inl(BASE + TLAN_HOST_CMD); ! 319: data |= TLAN_HC_INT_OFF; ! 320: outl(data, BASE + TLAN_HOST_CMD); ! 321: /* 3. Clear AREGs and HASHs. */ ! 322: ! 323: for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4) { ! 324: TLan_DioWrite32(BASE, (u16) i, 0); ! 325: } ! 326: ! 327: /* 4. Setup NetConfig register. */ ! 328: ! 329: data = ! 330: TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN; ! 331: TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data); ! 332: ! 333: /* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */ ! 334: ! 335: outl(TLAN_HC_LD_TMR | 0x3f, BASE + TLAN_HOST_CMD); ! 336: outl(TLAN_HC_LD_THR | 0x0, BASE + TLAN_HOST_CMD); ! 337: ! 338: /* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */ ! 339: ! 340: outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR); ! 341: addr = BASE + TLAN_DIO_DATA + TLAN_NET_SIO; ! 342: TLan_SetBit(TLAN_NET_SIO_NMRST, addr); ! 343: ! 344: /* 7. Setup the remaining registers. */ ! 345: ! 346: if (priv->tlanRev >= 0x30) { ! 347: data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC; ! 348: TLan_DioWrite8(BASE, TLAN_INT_DIS, data8); ! 349: } ! 350: TLan_PhyDetect(nic); ! 351: data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN; ! 352: ! 353: if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_BIT_RATE_PHY) { ! 354: data |= TLAN_NET_CFG_BIT; ! 355: if (priv->aui == 1) { ! 356: TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x0a); ! 357: } else if (priv->duplex == TLAN_DUPLEX_FULL) { ! 358: TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x00); ! 359: priv->tlanFullDuplex = TRUE; ! 360: } else { ! 361: TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x08); ! 362: } ! 363: } ! 364: ! 365: if (priv->phyNum == 0) { ! 366: data |= TLAN_NET_CFG_PHY_EN; ! 367: } ! 368: TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data); ! 369: ! 370: if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) { ! 371: TLan_FinishReset(nic); ! 372: } else { ! 373: TLan_PhyPowerDown(nic); ! 374: } ! 375: ! 376: } /* TLan_ResetAdapter */ ! 377: ! 378: void TLan_FinishReset(struct nic *nic) ! 379: { ! 380: ! 381: u8 data; ! 382: u32 phy; ! 383: u8 sio; ! 384: u16 status; ! 385: u16 partner; ! 386: u16 tlphy_ctl; ! 387: u16 tlphy_par; ! 388: u16 tlphy_id1, tlphy_id2; ! 389: int i; ! 390: ! 391: phy = priv->phy[priv->phyNum]; ! 392: ! 393: data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP; ! 394: if (priv->tlanFullDuplex) { ! 395: data |= TLAN_NET_CMD_DUPLEX; ! 396: } ! 397: TLan_DioWrite8(BASE, TLAN_NET_CMD, data); ! 398: data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5; ! 399: if (priv->phyNum == 0) { ! 400: data |= TLAN_NET_MASK_MASK7; ! 401: } ! 402: TLan_DioWrite8(BASE, TLAN_NET_MASK, data); ! 403: TLan_DioWrite16(BASE, TLAN_MAX_RX, ((1536) + 7) & ~7); ! 404: TLan_MiiReadReg(nic, phy, MII_PHYSID1, &tlphy_id1); ! 405: TLan_MiiReadReg(nic, phy, MII_PHYSID2, &tlphy_id2); ! 406: ! 407: if ((tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) ! 408: || (priv->aui)) { ! 409: status = BMSR_LSTATUS; ! 410: DBG ( "TLAN: %s: Link forced.\n", priv->nic_name ); ! 411: } else { ! 412: TLan_MiiReadReg(nic, phy, MII_BMSR, &status); ! 413: udelay(1000); ! 414: TLan_MiiReadReg(nic, phy, MII_BMSR, &status); ! 415: if ((status & BMSR_LSTATUS) && /* We only support link info on Nat.Sem. PHY's */ ! 416: (tlphy_id1 == NAT_SEM_ID1) ! 417: && (tlphy_id2 == NAT_SEM_ID2)) { ! 418: TLan_MiiReadReg(nic, phy, MII_LPA, &partner); ! 419: TLan_MiiReadReg(nic, phy, TLAN_TLPHY_PAR, ! 420: &tlphy_par); ! 421: ! 422: DBG ( "TLAN: %s: Link active with ", ! 423: priv->nic_name ); ! 424: if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) { ! 425: DBG ( "forced 10%sMbps %s-Duplex\n", ! 426: tlphy_par & TLAN_PHY_SPEED_100 ? "" ! 427: : "0", ! 428: tlphy_par & TLAN_PHY_DUPLEX_FULL ? ! 429: "Full" : "Half" ); ! 430: } else { ! 431: DBG ! 432: ( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n", ! 433: tlphy_par & TLAN_PHY_SPEED_100 ? "" : ! 434: "0", ! 435: tlphy_par & TLAN_PHY_DUPLEX_FULL ? ! 436: "Full" : "Half" ); ! 437: DBG ( "TLAN: Partner capability: " ); ! 438: for (i = 5; i <= 10; i++) ! 439: if (partner & (1 << i)) { ! 440: DBG ( "%s", media[i - 5] ); ! 441: } ! 442: DBG ( "\n" ); ! 443: } ! 444: ! 445: TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK); ! 446: #ifdef MONITOR ! 447: /* We have link beat..for now anyway */ ! 448: priv->link = 1; ! 449: /*Enabling link beat monitoring */ ! 450: /* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_LINK_BEAT ); */ ! 451: mdelay(10000); ! 452: TLan_PhyMonitor(nic); ! 453: #endif ! 454: } else if (status & BMSR_LSTATUS) { ! 455: DBG ( "TLAN: %s: Link active\n", priv->nic_name ); ! 456: TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK); ! 457: } ! 458: } ! 459: ! 460: if (priv->phyNum == 0) { ! 461: TLan_MiiReadReg(nic, phy, TLAN_TLPHY_CTL, &tlphy_ctl); ! 462: tlphy_ctl |= TLAN_TC_INTEN; ! 463: TLan_MiiWriteReg(nic, phy, TLAN_TLPHY_CTL, tlphy_ctl); ! 464: sio = TLan_DioRead8(BASE, TLAN_NET_SIO); ! 465: sio |= TLAN_NET_SIO_MINTEN; ! 466: TLan_DioWrite8(BASE, TLAN_NET_SIO, sio); ! 467: } ! 468: ! 469: if (status & BMSR_LSTATUS) { ! 470: TLan_SetMac(nic, 0, nic->node_addr); ! 471: priv->phyOnline = 1; ! 472: outb((TLAN_HC_INT_ON >> 8), BASE + TLAN_HOST_CMD + 1); ! 473: outl(virt_to_bus(&rx_ring), BASE + TLAN_CH_PARM); ! 474: outl(TLAN_HC_GO | TLAN_HC_RT, BASE + TLAN_HOST_CMD); ! 475: } else { ! 476: DBG ! 477: ( "TLAN: %s: Link inactive, will retry in 10 secs...\n", ! 478: priv->nic_name ); ! 479: /* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_FINISH_RESET ); */ ! 480: mdelay(10000); ! 481: TLan_FinishReset(nic); ! 482: return; ! 483: ! 484: } ! 485: ! 486: } /* TLan_FinishReset */ ! 487: ! 488: /************************************************************************** ! 489: POLL - Wait for a frame ! 490: ***************************************************************************/ ! 491: static int tlan_poll(struct nic *nic, int retrieve) ! 492: { ! 493: /* return true if there's an ethernet packet ready to read */ ! 494: /* nic->packet should contain data on return */ ! 495: /* nic->packetlen should contain length of data */ ! 496: u32 framesize; ! 497: u32 host_cmd = 0; ! 498: u32 ack = 1; ! 499: int eoc = 0; ! 500: int entry = priv->cur_rx % TLAN_NUM_RX_LISTS; ! 501: u16 tmpCStat = le32_to_cpu(rx_ring[entry].cStat); ! 502: u16 host_int = inw(BASE + TLAN_HOST_INT); ! 503: ! 504: if ((tmpCStat & TLAN_CSTAT_FRM_CMP) && !retrieve) ! 505: return 1; ! 506: ! 507: outw(host_int, BASE + TLAN_HOST_INT); ! 508: ! 509: if (!(tmpCStat & TLAN_CSTAT_FRM_CMP)) ! 510: return 0; ! 511: ! 512: /* printf("PI-1: 0x%hX\n", host_int); */ ! 513: if (tmpCStat & TLAN_CSTAT_EOC) ! 514: eoc = 1; ! 515: ! 516: framesize = rx_ring[entry].frameSize; ! 517: ! 518: nic->packetlen = framesize; ! 519: ! 520: DBG ( ".%d.", (unsigned int) framesize ); ! 521: ! 522: memcpy(nic->packet, rxb + ! 523: (priv->cur_rx * TLAN_MAX_FRAME_SIZE), nic->packetlen); ! 524: ! 525: rx_ring[entry].cStat = 0; ! 526: ! 527: DBG ( "%d", entry ); ! 528: ! 529: entry = (entry + 1) % TLAN_NUM_RX_LISTS; ! 530: priv->cur_rx = entry; ! 531: if (eoc) { ! 532: if ((rx_ring[entry].cStat & TLAN_CSTAT_READY) == ! 533: TLAN_CSTAT_READY) { ! 534: ack |= TLAN_HC_GO | TLAN_HC_RT; ! 535: host_cmd = TLAN_HC_ACK | ack | 0x001C0000; ! 536: outl(host_cmd, BASE + TLAN_HOST_CMD); ! 537: } ! 538: } else { ! 539: host_cmd = TLAN_HC_ACK | ack | (0x000C0000); ! 540: outl(host_cmd, BASE + TLAN_HOST_CMD); ! 541: ! 542: DBG ( "AC: 0x%hX\n", inw(BASE + TLAN_CH_PARM) ); ! 543: DBG ( "PI-2: 0x%hX\n", inw(BASE + TLAN_HOST_INT) ); ! 544: } ! 545: refill_rx(nic); ! 546: return (1); /* initially as this is called to flush the input */ ! 547: } ! 548: ! 549: static void refill_rx(struct nic *nic __unused) ! 550: { ! 551: int entry = 0; ! 552: ! 553: for (; ! 554: (priv->cur_rx - priv->dirty_rx + ! 555: TLAN_NUM_RX_LISTS) % TLAN_NUM_RX_LISTS > 0; ! 556: priv->dirty_rx = (priv->dirty_rx + 1) % TLAN_NUM_RX_LISTS) { ! 557: entry = priv->dirty_rx % TLAN_NUM_TX_LISTS; ! 558: rx_ring[entry].frameSize = TLAN_MAX_FRAME_SIZE; ! 559: rx_ring[entry].cStat = TLAN_CSTAT_READY; ! 560: } ! 561: ! 562: } ! 563: ! 564: /************************************************************************** ! 565: TRANSMIT - Transmit a frame ! 566: ***************************************************************************/ ! 567: static void tlan_transmit(struct nic *nic, const char *d, /* Destination */ ! 568: unsigned int t, /* Type */ ! 569: unsigned int s, /* size */ ! 570: const char *p) ! 571: { /* Packet */ ! 572: u16 nstype; ! 573: u32 to; ! 574: struct TLanList *tail_list; ! 575: struct TLanList *head_list; ! 576: u8 *tail_buffer; ! 577: u32 ack = 0; ! 578: u32 host_cmd; ! 579: int eoc = 0; ! 580: u16 tmpCStat; ! 581: u16 host_int = inw(BASE + TLAN_HOST_INT); ! 582: ! 583: int entry = 0; ! 584: ! 585: DBG ( "INT0-0x%hX\n", host_int ); ! 586: ! 587: if (!priv->phyOnline) { ! 588: printf("TRANSMIT: %s PHY is not ready\n", priv->nic_name); ! 589: return; ! 590: } ! 591: ! 592: tail_list = priv->txList + priv->txTail; ! 593: ! 594: if (tail_list->cStat != TLAN_CSTAT_UNUSED) { ! 595: printf("TRANSMIT: %s is busy (Head=%p Tail=%x)\n", ! 596: priv->nic_name, priv->txList, (unsigned int) priv->txTail); ! 597: tx_ring[entry].cStat = TLAN_CSTAT_UNUSED; ! 598: // priv->txBusyCount++; ! 599: return; ! 600: } ! 601: ! 602: tail_list->forward = 0; ! 603: ! 604: tail_buffer = txb + (priv->txTail * TLAN_MAX_FRAME_SIZE); ! 605: ! 606: /* send the packet to destination */ ! 607: memcpy(tail_buffer, d, ETH_ALEN); ! 608: memcpy(tail_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN); ! 609: nstype = htons((u16) t); ! 610: memcpy(tail_buffer + 2 * ETH_ALEN, (u8 *) & nstype, 2); ! 611: memcpy(tail_buffer + ETH_HLEN, p, s); ! 612: ! 613: s += ETH_HLEN; ! 614: s &= 0x0FFF; ! 615: while (s < ETH_ZLEN) ! 616: tail_buffer[s++] = '\0'; ! 617: ! 618: /*=====================================================*/ ! 619: /* Receive ! 620: * 0000 0000 0001 1100 ! 621: * 0000 0000 0000 1100 ! 622: * 0000 0000 0000 0011 = 0x0003 ! 623: * ! 624: * 0000 0000 0000 0000 0000 0000 0000 0011 ! 625: * 0000 0000 0000 1100 0000 0000 0000 0000 = 0x000C0000 ! 626: * ! 627: * Transmit ! 628: * 0000 0000 0001 1100 ! 629: * 0000 0000 0000 0100 ! 630: * 0000 0000 0000 0001 = 0x0001 ! 631: * ! 632: * 0000 0000 0000 0000 0000 0000 0000 0001 ! 633: * 0000 0000 0000 0100 0000 0000 0000 0000 = 0x00040000 ! 634: * */ ! 635: ! 636: /* Setup the transmit descriptor */ ! 637: tail_list->frameSize = (u16) s; ! 638: tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) s; ! 639: tail_list->buffer[1].count = 0; ! 640: tail_list->buffer[1].address = 0; ! 641: ! 642: tail_list->cStat = TLAN_CSTAT_READY; ! 643: ! 644: DBG ( "INT1-0x%hX\n", inw(BASE + TLAN_HOST_INT) ); ! 645: ! 646: if (!priv->txInProgress) { ! 647: priv->txInProgress = 1; ! 648: outl(virt_to_le32desc(tail_list), BASE + TLAN_CH_PARM); ! 649: outl(TLAN_HC_GO, BASE + TLAN_HOST_CMD); ! 650: } else { ! 651: if (priv->txTail == 0) { ! 652: DBG ( "Out buffer\n" ); ! 653: (priv->txList + (TLAN_NUM_TX_LISTS - 1))->forward = ! 654: virt_to_le32desc(tail_list); ! 655: } else { ! 656: DBG ( "Fix this \n" ); ! 657: (priv->txList + (priv->txTail - 1))->forward = ! 658: virt_to_le32desc(tail_list); ! 659: } ! 660: } ! 661: ! 662: CIRC_INC(priv->txTail, TLAN_NUM_TX_LISTS); ! 663: ! 664: DBG ( "INT2-0x%hX\n", inw(BASE + TLAN_HOST_INT) ); ! 665: ! 666: to = currticks() + TX_TIME_OUT; ! 667: while ((tail_list->cStat == TLAN_CSTAT_READY) && currticks() < to); ! 668: ! 669: head_list = priv->txList + priv->txHead; ! 670: while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) ! 671: && (ack < 255)) { ! 672: ack++; ! 673: if(tmpCStat & TLAN_CSTAT_EOC) ! 674: eoc =1; ! 675: head_list->cStat = TLAN_CSTAT_UNUSED; ! 676: CIRC_INC(priv->txHead, TLAN_NUM_TX_LISTS); ! 677: head_list = priv->txList + priv->txHead; ! 678: ! 679: } ! 680: if(!ack) ! 681: printf("Incomplete TX Frame\n"); ! 682: ! 683: if(eoc) { ! 684: head_list = priv->txList + priv->txHead; ! 685: if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) { ! 686: outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM); ! 687: ack |= TLAN_HC_GO; ! 688: } else { ! 689: priv->txInProgress = 0; ! 690: } ! 691: } ! 692: if(ack) { ! 693: host_cmd = TLAN_HC_ACK | ack; ! 694: outl(host_cmd, BASE + TLAN_HOST_CMD); ! 695: } ! 696: ! 697: if(priv->tlanRev < 0x30 ) { ! 698: ack = 1; ! 699: head_list = priv->txList + priv->txHead; ! 700: if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) { ! 701: outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM); ! 702: ack |= TLAN_HC_GO; ! 703: } else { ! 704: priv->txInProgress = 0; ! 705: } ! 706: host_cmd = TLAN_HC_ACK | ack | 0x00140000; ! 707: outl(host_cmd, BASE + TLAN_HOST_CMD); ! 708: ! 709: } ! 710: ! 711: if (currticks() >= to) { ! 712: printf("TX Time Out"); ! 713: } ! 714: } ! 715: ! 716: /************************************************************************** ! 717: DISABLE - Turn off ethernet interface ! 718: ***************************************************************************/ ! 719: static void tlan_disable ( struct nic *nic __unused ) { ! 720: /* put the card in its initial state */ ! 721: /* This function serves 3 purposes. ! 722: * This disables DMA and interrupts so we don't receive ! 723: * unexpected packets or interrupts from the card after ! 724: * etherboot has finished. ! 725: * This frees resources so etherboot may use ! 726: * this driver on another interface ! 727: * This allows etherboot to reinitialize the interface ! 728: * if something is something goes wrong. ! 729: * ! 730: */ ! 731: outl(TLAN_HC_AD_RST, BASE + TLAN_HOST_CMD); ! 732: } ! 733: ! 734: /************************************************************************** ! 735: IRQ - Enable, Disable, or Force interrupts ! 736: ***************************************************************************/ ! 737: static void tlan_irq(struct nic *nic __unused, irq_action_t action __unused) ! 738: { ! 739: switch ( action ) { ! 740: case DISABLE : ! 741: break; ! 742: case ENABLE : ! 743: break; ! 744: case FORCE : ! 745: break; ! 746: } ! 747: } ! 748: ! 749: static struct nic_operations tlan_operations = { ! 750: .connect = dummy_connect, ! 751: .poll = tlan_poll, ! 752: .transmit = tlan_transmit, ! 753: .irq = tlan_irq, ! 754: ! 755: }; ! 756: ! 757: static void TLan_SetMulticastList(struct nic *nic) { ! 758: int i; ! 759: u8 tmp; ! 760: ! 761: /* !IFF_PROMISC */ ! 762: tmp = TLan_DioRead8(BASE, TLAN_NET_CMD); ! 763: TLan_DioWrite8(BASE, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF); ! 764: ! 765: /* IFF_ALLMULTI */ ! 766: for(i = 0; i< 3; i++) ! 767: TLan_SetMac(nic, i + 1, NULL); ! 768: TLan_DioWrite32(BASE, TLAN_HASH_1, 0xFFFFFFFF); ! 769: TLan_DioWrite32(BASE, TLAN_HASH_2, 0xFFFFFFFF); ! 770: ! 771: ! 772: } ! 773: /************************************************************************** ! 774: PROBE - Look for an adapter, this routine's visible to the outside ! 775: ***************************************************************************/ ! 776: ! 777: #define board_found 1 ! 778: #define valid_link 0 ! 779: static int tlan_probe ( struct nic *nic, struct pci_device *pci ) { ! 780: ! 781: u16 data = 0; ! 782: int err; ! 783: int i; ! 784: ! 785: if (pci->ioaddr == 0) ! 786: return 0; ! 787: ! 788: nic->irqno = 0; ! 789: nic->ioaddr = pci->ioaddr; ! 790: ! 791: BASE = pci->ioaddr; ! 792: ! 793: /* Set nic as PCI bus master */ ! 794: adjust_pci_device(pci); ! 795: ! 796: /* Point to private storage */ ! 797: priv = &TLanPrivateInfo; ! 798: ! 799: /* Figure out which chip we're dealing with */ ! 800: i = 0; ! 801: chip_idx = -1; ! 802: while (tlan_pci_tbl[i].name) { ! 803: if ((((u32) pci->device << 16) | pci->vendor) == ! 804: (tlan_pci_tbl[i].id.pci & 0xffffffff)) { ! 805: chip_idx = i; ! 806: break; ! 807: } ! 808: i++; ! 809: } ! 810: ! 811: priv->vendor_id = pci->vendor; ! 812: priv->dev_id = pci->device; ! 813: priv->nic_name = pci->id->name; ! 814: priv->eoc = 0; ! 815: ! 816: err = 0; ! 817: for (i = 0; i < 6; i++) ! 818: err |= TLan_EeReadByte(BASE, ! 819: (u8) tlan_pci_tbl[chip_idx]. ! 820: addrOfs + i, ! 821: (u8 *) & nic->node_addr[i]); ! 822: if (err) { ! 823: printf ( "TLAN: %s: Error reading MAC from eeprom: %d\n", ! 824: pci->id->name, err); ! 825: } else { ! 826: DBG ( "%s: %s at ioaddr %#lX, ", ! 827: pci->id->name, eth_ntoa ( nic->node_addr ), pci->ioaddr ); ! 828: } ! 829: ! 830: priv->tlanRev = TLan_DioRead8(BASE, TLAN_DEF_REVISION); ! 831: printf("revision: 0x%hX\n", priv->tlanRev); ! 832: ! 833: TLan_ResetLists(nic); ! 834: TLan_ResetAdapter(nic); ! 835: ! 836: data = inl(BASE + TLAN_HOST_CMD); ! 837: data |= TLAN_HC_INT_OFF; ! 838: outw(data, BASE + TLAN_HOST_CMD); ! 839: ! 840: TLan_SetMulticastList(nic); ! 841: udelay(100); ! 842: priv->txList = tx_ring; ! 843: ! 844: /* if (board_found && valid_link) ! 845: {*/ ! 846: /* point to NIC specific routines */ ! 847: nic->nic_op = &tlan_operations; ! 848: return 1; ! 849: } ! 850: ! 851: ! 852: /***************************************************************************** ! 853: ****************************************************************************** ! 854: ! 855: ThunderLAN Driver Eeprom routines ! 856: ! 857: The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A ! 858: EEPROM. These functions are based on information in Microchip's ! 859: data sheet. I don't know how well this functions will work with ! 860: other EEPROMs. ! 861: ! 862: ****************************************************************************** ! 863: *****************************************************************************/ ! 864: ! 865: ! 866: /*************************************************************** ! 867: * TLan_EeSendStart ! 868: * ! 869: * Returns: ! 870: * Nothing ! 871: * Parms: ! 872: * io_base The IO port base address for the ! 873: * TLAN device with the EEPROM to ! 874: * use. ! 875: * ! 876: * This function sends a start cycle to an EEPROM attached ! 877: * to a TLAN chip. ! 878: * ! 879: **************************************************************/ ! 880: ! 881: void TLan_EeSendStart(u16 io_base) ! 882: { ! 883: u16 sio; ! 884: ! 885: outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR); ! 886: sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO; ! 887: ! 888: TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); ! 889: TLan_SetBit(TLAN_NET_SIO_EDATA, sio); ! 890: TLan_SetBit(TLAN_NET_SIO_ETXEN, sio); ! 891: TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); ! 892: TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); ! 893: ! 894: } /* TLan_EeSendStart */ ! 895: ! 896: /*************************************************************** ! 897: * TLan_EeSendByte ! 898: * ! 899: * Returns: ! 900: * If the correct ack was received, 0, otherwise 1 ! 901: * Parms: io_base The IO port base address for the ! 902: * TLAN device with the EEPROM to ! 903: * use. ! 904: * data The 8 bits of information to ! 905: * send to the EEPROM. ! 906: * stop If TLAN_EEPROM_STOP is passed, a ! 907: * stop cycle is sent after the ! 908: * byte is sent after the ack is ! 909: * read. ! 910: * ! 911: * This function sends a byte on the serial EEPROM line, ! 912: * driving the clock to send each bit. The function then ! 913: * reverses transmission direction and reads an acknowledge ! 914: * bit. ! 915: * ! 916: **************************************************************/ ! 917: ! 918: int TLan_EeSendByte(u16 io_base, u8 data, int stop) ! 919: { ! 920: int err; ! 921: u8 place; ! 922: u16 sio; ! 923: ! 924: outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR); ! 925: sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO; ! 926: ! 927: /* Assume clock is low, tx is enabled; */ ! 928: for (place = 0x80; place != 0; place >>= 1) { ! 929: if (place & data) ! 930: TLan_SetBit(TLAN_NET_SIO_EDATA, sio); ! 931: else ! 932: TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); ! 933: TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); ! 934: TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); ! 935: } ! 936: TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio); ! 937: TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); ! 938: err = TLan_GetBit(TLAN_NET_SIO_EDATA, sio); ! 939: TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); ! 940: TLan_SetBit(TLAN_NET_SIO_ETXEN, sio); ! 941: ! 942: if ((!err) && stop) { ! 943: TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* STOP, raise data while clock is high */ ! 944: TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); ! 945: TLan_SetBit(TLAN_NET_SIO_EDATA, sio); ! 946: } ! 947: ! 948: return (err); ! 949: ! 950: } /* TLan_EeSendByte */ ! 951: ! 952: /*************************************************************** ! 953: * TLan_EeReceiveByte ! 954: * ! 955: * Returns: ! 956: * Nothing ! 957: * Parms: ! 958: * io_base The IO port base address for the ! 959: * TLAN device with the EEPROM to ! 960: * use. ! 961: * data An address to a char to hold the ! 962: * data sent from the EEPROM. ! 963: * stop If TLAN_EEPROM_STOP is passed, a ! 964: * stop cycle is sent after the ! 965: * byte is received, and no ack is ! 966: * sent. ! 967: * ! 968: * This function receives 8 bits of data from the EEPROM ! 969: * over the serial link. It then sends and ack bit, or no ! 970: * ack and a stop bit. This function is used to retrieve ! 971: * data after the address of a byte in the EEPROM has been ! 972: * sent. ! 973: * ! 974: **************************************************************/ ! 975: ! 976: void TLan_EeReceiveByte(u16 io_base, u8 * data, int stop) ! 977: { ! 978: u8 place; ! 979: u16 sio; ! 980: ! 981: outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR); ! 982: sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO; ! 983: *data = 0; ! 984: ! 985: /* Assume clock is low, tx is enabled; */ ! 986: TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio); ! 987: for (place = 0x80; place; place >>= 1) { ! 988: TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); ! 989: if (TLan_GetBit(TLAN_NET_SIO_EDATA, sio)) ! 990: *data |= place; ! 991: TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); ! 992: } ! 993: ! 994: TLan_SetBit(TLAN_NET_SIO_ETXEN, sio); ! 995: if (!stop) { ! 996: TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* Ack = 0 */ ! 997: TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); ! 998: TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); ! 999: } else { ! 1000: TLan_SetBit(TLAN_NET_SIO_EDATA, sio); /* No ack = 1 (?) */ ! 1001: TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); ! 1002: TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio); ! 1003: TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* STOP, raise data while clock is high */ ! 1004: TLan_SetBit(TLAN_NET_SIO_ECLOK, sio); ! 1005: TLan_SetBit(TLAN_NET_SIO_EDATA, sio); ! 1006: } ! 1007: ! 1008: } /* TLan_EeReceiveByte */ ! 1009: ! 1010: /*************************************************************** ! 1011: * TLan_EeReadByte ! 1012: * ! 1013: * Returns: ! 1014: * No error = 0, else, the stage at which the error ! 1015: * occurred. ! 1016: * Parms: ! 1017: * io_base The IO port base address for the ! 1018: * TLAN device with the EEPROM to ! 1019: * use. ! 1020: * ee_addr The address of the byte in the ! 1021: * EEPROM whose contents are to be ! 1022: * retrieved. ! 1023: * data An address to a char to hold the ! 1024: * data obtained from the EEPROM. ! 1025: * ! 1026: * This function reads a byte of information from an byte ! 1027: * cell in the EEPROM. ! 1028: * ! 1029: **************************************************************/ ! 1030: ! 1031: int TLan_EeReadByte(u16 io_base, u8 ee_addr, u8 * data) ! 1032: { ! 1033: int err; ! 1034: int ret = 0; ! 1035: ! 1036: ! 1037: TLan_EeSendStart(io_base); ! 1038: err = TLan_EeSendByte(io_base, 0xA0, TLAN_EEPROM_ACK); ! 1039: if (err) { ! 1040: ret = 1; ! 1041: goto fail; ! 1042: } ! 1043: err = TLan_EeSendByte(io_base, ee_addr, TLAN_EEPROM_ACK); ! 1044: if (err) { ! 1045: ret = 2; ! 1046: goto fail; ! 1047: } ! 1048: TLan_EeSendStart(io_base); ! 1049: err = TLan_EeSendByte(io_base, 0xA1, TLAN_EEPROM_ACK); ! 1050: if (err) { ! 1051: ret = 3; ! 1052: goto fail; ! 1053: } ! 1054: TLan_EeReceiveByte(io_base, data, TLAN_EEPROM_STOP); ! 1055: fail: ! 1056: ! 1057: return ret; ! 1058: ! 1059: } /* TLan_EeReadByte */ ! 1060: ! 1061: ! 1062: /***************************************************************************** ! 1063: ****************************************************************************** ! 1064: ! 1065: ThunderLAN Driver MII Routines ! 1066: ! 1067: These routines are based on the information in Chap. 2 of the ! 1068: "ThunderLAN Programmer's Guide", pp. 15-24. ! 1069: ! 1070: ****************************************************************************** ! 1071: *****************************************************************************/ ! 1072: ! 1073: ! 1074: /*************************************************************** ! 1075: * TLan_MiiReadReg ! 1076: * ! 1077: * Returns: ! 1078: * 0 if ack received ok ! 1079: * 1 otherwise. ! 1080: * ! 1081: * Parms: ! 1082: * dev The device structure containing ! 1083: * The io address and interrupt count ! 1084: * for this device. ! 1085: * phy The address of the PHY to be queried. ! 1086: * reg The register whose contents are to be ! 1087: * retreived. ! 1088: * val A pointer to a variable to store the ! 1089: * retrieved value. ! 1090: * ! 1091: * This function uses the TLAN's MII bus to retreive the contents ! 1092: * of a given register on a PHY. It sends the appropriate info ! 1093: * and then reads the 16-bit register value from the MII bus via ! 1094: * the TLAN SIO register. ! 1095: * ! 1096: **************************************************************/ ! 1097: ! 1098: int TLan_MiiReadReg(struct nic *nic __unused, u16 phy, u16 reg, u16 * val) ! 1099: { ! 1100: u8 nack; ! 1101: u16 sio, tmp; ! 1102: u32 i; ! 1103: int err; ! 1104: int minten; ! 1105: ! 1106: err = FALSE; ! 1107: outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR); ! 1108: sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO; ! 1109: ! 1110: TLan_MiiSync(BASE); ! 1111: ! 1112: minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio); ! 1113: if (minten) ! 1114: TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio); ! 1115: ! 1116: TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */ ! 1117: TLan_MiiSendData(BASE, 0x2, 2); /* Read ( 10b ) */ ! 1118: TLan_MiiSendData(BASE, phy, 5); /* Device # */ ! 1119: TLan_MiiSendData(BASE, reg, 5); /* Register # */ ! 1120: ! 1121: ! 1122: TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); /* Change direction */ ! 1123: ! 1124: TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Clock Idle bit */ ! 1125: TLan_SetBit(TLAN_NET_SIO_MCLK, sio); ! 1126: TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Wait 300ns */ ! 1127: ! 1128: nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio); /* Check for ACK */ ! 1129: TLan_SetBit(TLAN_NET_SIO_MCLK, sio); /* Finish ACK */ ! 1130: if (nack) { /* No ACK, so fake it */ ! 1131: for (i = 0; i < 16; i++) { ! 1132: TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); ! 1133: TLan_SetBit(TLAN_NET_SIO_MCLK, sio); ! 1134: } ! 1135: tmp = 0xffff; ! 1136: err = TRUE; ! 1137: } else { /* ACK, so read data */ ! 1138: for (tmp = 0, i = 0x8000; i; i >>= 1) { ! 1139: TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); ! 1140: if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio)) ! 1141: tmp |= i; ! 1142: TLan_SetBit(TLAN_NET_SIO_MCLK, sio); ! 1143: } ! 1144: } ! 1145: ! 1146: ! 1147: TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */ ! 1148: TLan_SetBit(TLAN_NET_SIO_MCLK, sio); ! 1149: ! 1150: if (minten) ! 1151: TLan_SetBit(TLAN_NET_SIO_MINTEN, sio); ! 1152: ! 1153: *val = tmp; ! 1154: ! 1155: return err; ! 1156: ! 1157: } /* TLan_MiiReadReg */ ! 1158: ! 1159: /*************************************************************** ! 1160: * TLan_MiiSendData ! 1161: * ! 1162: * Returns: ! 1163: * Nothing ! 1164: * Parms: ! 1165: * base_port The base IO port of the adapter in ! 1166: * question. ! 1167: * dev The address of the PHY to be queried. ! 1168: * data The value to be placed on the MII bus. ! 1169: * num_bits The number of bits in data that are to ! 1170: * be placed on the MII bus. ! 1171: * ! 1172: * This function sends on sequence of bits on the MII ! 1173: * configuration bus. ! 1174: * ! 1175: **************************************************************/ ! 1176: ! 1177: void TLan_MiiSendData(u16 base_port, u32 data, unsigned num_bits) ! 1178: { ! 1179: u16 sio; ! 1180: u32 i; ! 1181: ! 1182: if (num_bits == 0) ! 1183: return; ! 1184: ! 1185: outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR); ! 1186: sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO; ! 1187: TLan_SetBit(TLAN_NET_SIO_MTXEN, sio); ! 1188: ! 1189: for (i = (0x1 << (num_bits - 1)); i; i >>= 1) { ! 1190: TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); ! 1191: (void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio); ! 1192: if (data & i) ! 1193: TLan_SetBit(TLAN_NET_SIO_MDATA, sio); ! 1194: else ! 1195: TLan_ClearBit(TLAN_NET_SIO_MDATA, sio); ! 1196: TLan_SetBit(TLAN_NET_SIO_MCLK, sio); ! 1197: (void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio); ! 1198: } ! 1199: ! 1200: } /* TLan_MiiSendData */ ! 1201: ! 1202: /*************************************************************** ! 1203: * TLan_MiiSync ! 1204: * ! 1205: * Returns: ! 1206: * Nothing ! 1207: * Parms: ! 1208: * base_port The base IO port of the adapter in ! 1209: * question. ! 1210: * ! 1211: * This functions syncs all PHYs in terms of the MII configuration ! 1212: * bus. ! 1213: * ! 1214: **************************************************************/ ! 1215: ! 1216: void TLan_MiiSync(u16 base_port) ! 1217: { ! 1218: int i; ! 1219: u16 sio; ! 1220: ! 1221: outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR); ! 1222: sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO; ! 1223: ! 1224: TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); ! 1225: for (i = 0; i < 32; i++) { ! 1226: TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); ! 1227: TLan_SetBit(TLAN_NET_SIO_MCLK, sio); ! 1228: } ! 1229: ! 1230: } /* TLan_MiiSync */ ! 1231: ! 1232: /*************************************************************** ! 1233: * TLan_MiiWriteReg ! 1234: * ! 1235: * Returns: ! 1236: * Nothing ! 1237: * Parms: ! 1238: * dev The device structure for the device ! 1239: * to write to. ! 1240: * phy The address of the PHY to be written to. ! 1241: * reg The register whose contents are to be ! 1242: * written. ! 1243: * val The value to be written to the register. ! 1244: * ! 1245: * This function uses the TLAN's MII bus to write the contents of a ! 1246: * given register on a PHY. It sends the appropriate info and then ! 1247: * writes the 16-bit register value from the MII configuration bus ! 1248: * via the TLAN SIO register. ! 1249: * ! 1250: **************************************************************/ ! 1251: ! 1252: void TLan_MiiWriteReg(struct nic *nic __unused, u16 phy, u16 reg, u16 val) ! 1253: { ! 1254: u16 sio; ! 1255: int minten; ! 1256: ! 1257: outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR); ! 1258: sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO; ! 1259: ! 1260: TLan_MiiSync(BASE); ! 1261: ! 1262: minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio); ! 1263: if (minten) ! 1264: TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio); ! 1265: ! 1266: TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */ ! 1267: TLan_MiiSendData(BASE, 0x1, 2); /* Write ( 01b ) */ ! 1268: TLan_MiiSendData(BASE, phy, 5); /* Device # */ ! 1269: TLan_MiiSendData(BASE, reg, 5); /* Register # */ ! 1270: ! 1271: TLan_MiiSendData(BASE, 0x2, 2); /* Send ACK */ ! 1272: TLan_MiiSendData(BASE, val, 16); /* Send Data */ ! 1273: ! 1274: TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */ ! 1275: TLan_SetBit(TLAN_NET_SIO_MCLK, sio); ! 1276: ! 1277: if (minten) ! 1278: TLan_SetBit(TLAN_NET_SIO_MINTEN, sio); ! 1279: ! 1280: ! 1281: } /* TLan_MiiWriteReg */ ! 1282: ! 1283: /*************************************************************** ! 1284: * TLan_SetMac ! 1285: * ! 1286: * Returns: ! 1287: * Nothing ! 1288: * Parms: ! 1289: * dev Pointer to device structure of adapter ! 1290: * on which to change the AREG. ! 1291: * areg The AREG to set the address in (0 - 3). ! 1292: * mac A pointer to an array of chars. Each ! 1293: * element stores one byte of the address. ! 1294: * IE, it isn't in ascii. ! 1295: * ! 1296: * This function transfers a MAC address to one of the ! 1297: * TLAN AREGs (address registers). The TLAN chip locks ! 1298: * the register on writing to offset 0 and unlocks the ! 1299: * register after writing to offset 5. If NULL is passed ! 1300: * in mac, then the AREG is filled with 0's. ! 1301: * ! 1302: **************************************************************/ ! 1303: ! 1304: void TLan_SetMac(struct nic *nic __unused, int areg, unsigned char *mac) ! 1305: { ! 1306: int i; ! 1307: ! 1308: areg *= 6; ! 1309: ! 1310: if (mac != NULL) { ! 1311: for (i = 0; i < 6; i++) ! 1312: TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i, ! 1313: mac[i]); ! 1314: } else { ! 1315: for (i = 0; i < 6; i++) ! 1316: TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i, 0); ! 1317: } ! 1318: ! 1319: } /* TLan_SetMac */ ! 1320: ! 1321: /********************************************************************* ! 1322: * TLan_PhyDetect ! 1323: * ! 1324: * Returns: ! 1325: * Nothing ! 1326: * Parms: ! 1327: * dev A pointer to the device structure of the adapter ! 1328: * for which the PHY needs determined. ! 1329: * ! 1330: * So far I've found that adapters which have external PHYs ! 1331: * may also use the internal PHY for part of the functionality. ! 1332: * (eg, AUI/Thinnet). This function finds out if this TLAN ! 1333: * chip has an internal PHY, and then finds the first external ! 1334: * PHY (starting from address 0) if it exists). ! 1335: * ! 1336: ********************************************************************/ ! 1337: ! 1338: void TLan_PhyDetect(struct nic *nic) ! 1339: { ! 1340: u16 control; ! 1341: u16 hi; ! 1342: u16 lo; ! 1343: u32 phy; ! 1344: ! 1345: if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) { ! 1346: priv->phyNum = 0xFFFF; ! 1347: return; ! 1348: } ! 1349: ! 1350: TLan_MiiReadReg(nic, TLAN_PHY_MAX_ADDR, MII_PHYSID1, &hi); ! 1351: ! 1352: if (hi != 0xFFFF) { ! 1353: priv->phy[0] = TLAN_PHY_MAX_ADDR; ! 1354: } else { ! 1355: priv->phy[0] = TLAN_PHY_NONE; ! 1356: } ! 1357: ! 1358: priv->phy[1] = TLAN_PHY_NONE; ! 1359: for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) { ! 1360: TLan_MiiReadReg(nic, phy, MII_BMCR, &control); ! 1361: TLan_MiiReadReg(nic, phy, MII_PHYSID1, &hi); ! 1362: TLan_MiiReadReg(nic, phy, MII_PHYSID2, &lo); ! 1363: if ((control != 0xFFFF) || (hi != 0xFFFF) ! 1364: || (lo != 0xFFFF)) { ! 1365: printf("PHY found at %hX %hX %hX %hX\n", ! 1366: (unsigned int) phy, control, hi, lo); ! 1367: if ((priv->phy[1] == TLAN_PHY_NONE) ! 1368: && (phy != TLAN_PHY_MAX_ADDR)) { ! 1369: priv->phy[1] = phy; ! 1370: } ! 1371: } ! 1372: } ! 1373: ! 1374: if (priv->phy[1] != TLAN_PHY_NONE) { ! 1375: priv->phyNum = 1; ! 1376: } else if (priv->phy[0] != TLAN_PHY_NONE) { ! 1377: priv->phyNum = 0; ! 1378: } else { ! 1379: printf ! 1380: ("TLAN: Cannot initialize device, no PHY was found!\n"); ! 1381: } ! 1382: ! 1383: } /* TLan_PhyDetect */ ! 1384: ! 1385: void TLan_PhyPowerDown(struct nic *nic) ! 1386: { ! 1387: ! 1388: u16 value; ! 1389: DBG ( "%s: Powering down PHY(s).\n", priv->nic_name ); ! 1390: value = BMCR_PDOWN | BMCR_LOOPBACK | BMCR_ISOLATE; ! 1391: TLan_MiiSync(BASE); ! 1392: TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_BMCR, value); ! 1393: if ((priv->phyNum == 0) && (priv->phy[1] != TLAN_PHY_NONE) ! 1394: && ! 1395: (!(tlan_pci_tbl[chip_idx]. ! 1396: flags & TLAN_ADAPTER_USE_INTERN_10))) { ! 1397: TLan_MiiSync(BASE); ! 1398: TLan_MiiWriteReg(nic, priv->phy[1], MII_BMCR, value); ! 1399: } ! 1400: ! 1401: /* Wait for 50 ms and powerup ! 1402: * This is abitrary. It is intended to make sure the ! 1403: * tranceiver settles. ! 1404: */ ! 1405: /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP ); */ ! 1406: mdelay(50); ! 1407: TLan_PhyPowerUp(nic); ! 1408: ! 1409: } /* TLan_PhyPowerDown */ ! 1410: ! 1411: ! 1412: void TLan_PhyPowerUp(struct nic *nic) ! 1413: { ! 1414: u16 value; ! 1415: ! 1416: DBG ( "%s: Powering up PHY.\n", priv->nic_name ); ! 1417: TLan_MiiSync(BASE); ! 1418: value = BMCR_LOOPBACK; ! 1419: TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_BMCR, value); ! 1420: TLan_MiiSync(BASE); ! 1421: /* Wait for 500 ms and reset the ! 1422: * tranceiver. The TLAN docs say both 50 ms and ! 1423: * 500 ms, so do the longer, just in case. ! 1424: */ ! 1425: mdelay(500); ! 1426: TLan_PhyReset(nic); ! 1427: /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET ); */ ! 1428: ! 1429: } /* TLan_PhyPowerUp */ ! 1430: ! 1431: void TLan_PhyReset(struct nic *nic) ! 1432: { ! 1433: u16 phy; ! 1434: u16 value; ! 1435: ! 1436: phy = priv->phy[priv->phyNum]; ! 1437: ! 1438: DBG ( "%s: Reseting PHY.\n", priv->nic_name ); ! 1439: TLan_MiiSync(BASE); ! 1440: value = BMCR_LOOPBACK | BMCR_RESET; ! 1441: TLan_MiiWriteReg(nic, phy, MII_BMCR, value); ! 1442: TLan_MiiReadReg(nic, phy, MII_BMCR, &value); ! 1443: while (value & BMCR_RESET) { ! 1444: TLan_MiiReadReg(nic, phy, MII_BMCR, &value); ! 1445: } ! 1446: ! 1447: /* Wait for 500 ms and initialize. ! 1448: * I don't remember why I wait this long. ! 1449: * I've changed this to 50ms, as it seems long enough. ! 1450: */ ! 1451: /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK ); */ ! 1452: mdelay(50); ! 1453: TLan_PhyStartLink(nic); ! 1454: ! 1455: } /* TLan_PhyReset */ ! 1456: ! 1457: ! 1458: void TLan_PhyStartLink(struct nic *nic) ! 1459: { ! 1460: ! 1461: u16 ability; ! 1462: u16 control; ! 1463: u16 data; ! 1464: u16 phy; ! 1465: u16 status; ! 1466: u16 tctl; ! 1467: ! 1468: phy = priv->phy[priv->phyNum]; ! 1469: DBG ( "%s: Trying to activate link.\n", priv->nic_name ); ! 1470: TLan_MiiReadReg(nic, phy, MII_BMSR, &status); ! 1471: TLan_MiiReadReg(nic, phy, MII_BMSR, &ability); ! 1472: ! 1473: if ((status & BMSR_ANEGCAPABLE) && (!priv->aui)) { ! 1474: ability = status >> 11; ! 1475: if (priv->speed == TLAN_SPEED_10 && ! 1476: priv->duplex == TLAN_DUPLEX_HALF) { ! 1477: TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x0000); ! 1478: } else if (priv->speed == TLAN_SPEED_10 && ! 1479: priv->duplex == TLAN_DUPLEX_FULL) { ! 1480: priv->tlanFullDuplex = TRUE; ! 1481: TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x0100); ! 1482: } else if (priv->speed == TLAN_SPEED_100 && ! 1483: priv->duplex == TLAN_DUPLEX_HALF) { ! 1484: TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x2000); ! 1485: } else if (priv->speed == TLAN_SPEED_100 && ! 1486: priv->duplex == TLAN_DUPLEX_FULL) { ! 1487: priv->tlanFullDuplex = TRUE; ! 1488: TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x2100); ! 1489: } else { ! 1490: ! 1491: /* Set Auto-Neg advertisement */ ! 1492: TLan_MiiWriteReg(nic, phy, MII_ADVERTISE, ! 1493: (ability << 5) | 1); ! 1494: /* Enablee Auto-Neg */ ! 1495: TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x1000); ! 1496: /* Restart Auto-Neg */ ! 1497: TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x1200); ! 1498: /* Wait for 4 sec for autonegotiation ! 1499: * to complete. The max spec time is less than this ! 1500: * but the card need additional time to start AN. ! 1501: * .5 sec should be plenty extra. ! 1502: */ ! 1503: DBG ( "TLAN: %s: Starting autonegotiation.\n", ! 1504: priv->nic_name ); ! 1505: mdelay(4000); ! 1506: TLan_PhyFinishAutoNeg(nic); ! 1507: /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN ); */ ! 1508: return; ! 1509: } ! 1510: ! 1511: } ! 1512: ! 1513: if ((priv->aui) && (priv->phyNum != 0)) { ! 1514: priv->phyNum = 0; ! 1515: data = ! 1516: TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | ! 1517: TLAN_NET_CFG_PHY_EN; ! 1518: TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data); ! 1519: mdelay(50); ! 1520: /* TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN ); */ ! 1521: TLan_PhyPowerDown(nic); ! 1522: return; ! 1523: } else if (priv->phyNum == 0) { ! 1524: control = 0; ! 1525: TLan_MiiReadReg(nic, phy, TLAN_TLPHY_CTL, &tctl); ! 1526: if (priv->aui) { ! 1527: tctl |= TLAN_TC_AUISEL; ! 1528: } else { ! 1529: tctl &= ~TLAN_TC_AUISEL; ! 1530: if (priv->duplex == TLAN_DUPLEX_FULL) { ! 1531: control |= BMCR_FULLDPLX; ! 1532: priv->tlanFullDuplex = TRUE; ! 1533: } ! 1534: if (priv->speed == TLAN_SPEED_100) { ! 1535: control |= BMCR_SPEED100; ! 1536: } ! 1537: } ! 1538: TLan_MiiWriteReg(nic, phy, MII_BMCR, control); ! 1539: TLan_MiiWriteReg(nic, phy, TLAN_TLPHY_CTL, tctl); ! 1540: } ! 1541: ! 1542: /* Wait for 2 sec to give the tranceiver time ! 1543: * to establish link. ! 1544: */ ! 1545: /* TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET ); */ ! 1546: mdelay(2000); ! 1547: TLan_FinishReset(nic); ! 1548: ! 1549: } /* TLan_PhyStartLink */ ! 1550: ! 1551: void TLan_PhyFinishAutoNeg(struct nic *nic) ! 1552: { ! 1553: ! 1554: u16 an_adv; ! 1555: u16 an_lpa; ! 1556: u16 data; ! 1557: u16 mode; ! 1558: u16 phy; ! 1559: u16 status; ! 1560: ! 1561: phy = priv->phy[priv->phyNum]; ! 1562: ! 1563: TLan_MiiReadReg(nic, phy, MII_BMSR, &status); ! 1564: udelay(1000); ! 1565: TLan_MiiReadReg(nic, phy, MII_BMSR, &status); ! 1566: ! 1567: if (!(status & BMSR_ANEGCOMPLETE)) { ! 1568: /* Wait for 8 sec to give the process ! 1569: * more time. Perhaps we should fail after a while. ! 1570: */ ! 1571: if (!priv->neg_be_verbose++) { ! 1572: printf ! 1573: ("TLAN: Giving autonegotiation more time.\n"); ! 1574: printf ! 1575: ("TLAN: Please check that your adapter has\n"); ! 1576: printf ! 1577: ("TLAN: been properly connected to a HUB or Switch.\n"); ! 1578: printf ! 1579: ("TLAN: Trying to establish link in the background...\n"); ! 1580: } ! 1581: mdelay(8000); ! 1582: TLan_PhyFinishAutoNeg(nic); ! 1583: /* TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN ); */ ! 1584: return; ! 1585: } ! 1586: ! 1587: DBG ( "TLAN: %s: Autonegotiation complete.\n", priv->nic_name ); ! 1588: TLan_MiiReadReg(nic, phy, MII_ADVERTISE, &an_adv); ! 1589: TLan_MiiReadReg(nic, phy, MII_LPA, &an_lpa); ! 1590: mode = an_adv & an_lpa & 0x03E0; ! 1591: if (mode & 0x0100) { ! 1592: printf("Full Duplex\n"); ! 1593: priv->tlanFullDuplex = TRUE; ! 1594: } else if (!(mode & 0x0080) && (mode & 0x0040)) { ! 1595: priv->tlanFullDuplex = TRUE; ! 1596: printf("Full Duplex\n"); ! 1597: } ! 1598: ! 1599: if ((!(mode & 0x0180)) ! 1600: && (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_USE_INTERN_10) ! 1601: && (priv->phyNum != 0)) { ! 1602: priv->phyNum = 0; ! 1603: data = ! 1604: TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | ! 1605: TLAN_NET_CFG_PHY_EN; ! 1606: TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data); ! 1607: /* TLan_SetTimer( nic, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN ); */ ! 1608: mdelay(400); ! 1609: TLan_PhyPowerDown(nic); ! 1610: return; ! 1611: } ! 1612: ! 1613: if (priv->phyNum == 0) { ! 1614: if ((priv->duplex == TLAN_DUPLEX_FULL) ! 1615: || (an_adv & an_lpa & 0x0040)) { ! 1616: TLan_MiiWriteReg(nic, phy, MII_BMCR, ! 1617: BMCR_ANENABLE | BMCR_FULLDPLX); ! 1618: DBG ! 1619: ( "TLAN: Starting internal PHY with FULL-DUPLEX\n" ); ! 1620: } else { ! 1621: TLan_MiiWriteReg(nic, phy, MII_BMCR, ! 1622: BMCR_ANENABLE); ! 1623: DBG ! 1624: ( "TLAN: Starting internal PHY with HALF-DUPLEX\n" ); ! 1625: } ! 1626: } ! 1627: ! 1628: /* Wait for 100 ms. No reason in partiticular. ! 1629: */ ! 1630: /* TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET ); */ ! 1631: mdelay(100); ! 1632: TLan_FinishReset(nic); ! 1633: ! 1634: } /* TLan_PhyFinishAutoNeg */ ! 1635: ! 1636: #ifdef MONITOR ! 1637: ! 1638: /********************************************************************* ! 1639: * ! 1640: * TLan_phyMonitor ! 1641: * ! 1642: * Returns: ! 1643: * None ! 1644: * ! 1645: * Params: ! 1646: * dev The device structure of this device. ! 1647: * ! 1648: * ! 1649: * This function monitors PHY condition by reading the status ! 1650: * register via the MII bus. This can be used to give info ! 1651: * about link changes (up/down), and possible switch to alternate ! 1652: * media. ! 1653: * ! 1654: ********************************************************************/ ! 1655: ! 1656: void TLan_PhyMonitor(struct net_device *dev) ! 1657: { ! 1658: TLanPrivateInfo *priv = dev->priv; ! 1659: u16 phy; ! 1660: u16 phy_status; ! 1661: ! 1662: phy = priv->phy[priv->phyNum]; ! 1663: ! 1664: /* Get PHY status register */ ! 1665: TLan_MiiReadReg(nic, phy, MII_BMSR, &phy_status); ! 1666: ! 1667: /* Check if link has been lost */ ! 1668: if (!(phy_status & BMSR_LSTATUS)) { ! 1669: if (priv->link) { ! 1670: priv->link = 0; ! 1671: printf("TLAN: %s has lost link\n", priv->nic_name); ! 1672: priv->flags &= ~IFF_RUNNING; ! 1673: mdelay(2000); ! 1674: TLan_PhyMonitor(nic); ! 1675: /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); */ ! 1676: return; ! 1677: } ! 1678: } ! 1679: ! 1680: /* Link restablished? */ ! 1681: if ((phy_status & BMSR_LSTATUS) && !priv->link) { ! 1682: priv->link = 1; ! 1683: printf("TLAN: %s has reestablished link\n", ! 1684: priv->nic_name); ! 1685: priv->flags |= IFF_RUNNING; ! 1686: } ! 1687: ! 1688: /* Setup a new monitor */ ! 1689: /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); */ ! 1690: mdelay(2000); ! 1691: TLan_PhyMonitor(nic); ! 1692: } ! 1693: ! 1694: #endif /* MONITOR */ ! 1695: ! 1696: static struct pci_device_id tlan_nics[] = { ! 1697: PCI_ROM(0x0e11, 0xae34, "netel10", "Compaq Netelligent 10 T PCI UTP", 0), ! 1698: PCI_ROM(0x0e11, 0xae32, "netel100","Compaq Netelligent 10/100 TX PCI UTP", 0), ! 1699: PCI_ROM(0x0e11, 0xae35, "netflex3i", "Compaq Integrated NetFlex-3/P", 0), ! 1700: PCI_ROM(0x0e11, 0xf130, "thunder", "Compaq NetFlex-3/P", 0), ! 1701: PCI_ROM(0x0e11, 0xf150, "netflex3b", "Compaq NetFlex-3/P", 0), ! 1702: PCI_ROM(0x0e11, 0xae43, "netel100pi", "Compaq Netelligent Integrated 10/100 TX UTP", 0), ! 1703: PCI_ROM(0x0e11, 0xae40, "netel100d", "Compaq Netelligent Dual 10/100 TX PCI UTP", 0), ! 1704: PCI_ROM(0x0e11, 0xb011, "netel100i", "Compaq Netelligent 10/100 TX Embedded UTP", 0), ! 1705: PCI_ROM(0x108d, 0x0013, "oc2183", "Olicom OC-2183/2185", 0), ! 1706: PCI_ROM(0x108d, 0x0012, "oc2325", "Olicom OC-2325", 0), ! 1707: PCI_ROM(0x108d, 0x0014, "oc2326", "Olicom OC-2326", 0), ! 1708: PCI_ROM(0x0e11, 0xb030, "netelligent_10_100_ws_5100", "Compaq Netelligent 10/100 TX UTP", 0), ! 1709: PCI_ROM(0x0e11, 0xb012, "netelligent_10_t2", "Compaq Netelligent 10 T/2 PCI UTP/Coax", 0), ! 1710: }; ! 1711: ! 1712: PCI_DRIVER ( tlan_driver, tlan_nics, PCI_NO_CLASS ); ! 1713: ! 1714: DRIVER ( "TLAN/PCI", nic_driver, pci_driver, tlan_driver, ! 1715: tlan_probe, tlan_disable ); ! 1716: ! 1717: /* ! 1718: * Local variables: ! 1719: * c-basic-offset: 8 ! 1720: * c-indent-level: 8 ! 1721: * tab-width: 8 ! 1722: * End: ! 1723: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.