|
|
1.1 ! root 1: /************************************************************************** ! 2: * ! 3: * dmfe.c -- Etherboot device driver for the Davicom ! 4: * DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 NIC fast ethernet card ! 5: * ! 6: * Written 2003-2003 by Timothy Legge <[email protected]> ! 7: * ! 8: * This program is free software; you can redistribute it and/or modify ! 9: * it under the terms of the GNU General Public License as published by ! 10: * the Free Software Foundation; either version 2 of the License, or ! 11: * (at your option) any later version. ! 12: * ! 13: * This program is distributed in the hope that it will be useful, ! 14: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 16: * GNU General Public License for more details. ! 17: * ! 18: * You should have received a copy of the GNU General Public License ! 19: * along with this program; if not, write to the Free Software ! 20: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 21: * ! 22: * Portions of this code based on: ! 23: * ! 24: * dmfe.c: A Davicom DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 ! 25: * NIC fast ethernet driver for Linux. ! 26: * Copyright (C) 1997 Sten Wang ! 27: * (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. ! 28: * ! 29: * ! 30: * REVISION HISTORY: ! 31: * ================ ! 32: * v1.0 10-02-2004 timlegge Boots ltsp needs cleanup ! 33: * ! 34: * Indent Options: indent -kr -i8 ! 35: * ! 36: * ! 37: ***************************************************************************/ ! 38: ! 39: FILE_LICENCE ( GPL2_OR_LATER ); ! 40: ! 41: /* to get some global routines like printf */ ! 42: #include "etherboot.h" ! 43: /* to get the interface to the body of the program */ ! 44: #include "nic.h" ! 45: /* to get the PCI support functions, if this is a PCI NIC */ ! 46: #include <ipxe/pci.h> ! 47: #include <ipxe/ethernet.h> ! 48: ! 49: /* #define EDEBUG 1 */ ! 50: #ifdef EDEBUG ! 51: #define dprintf(x) printf x ! 52: #else ! 53: #define dprintf(x) ! 54: #endif ! 55: ! 56: /* Condensed operations for readability. */ ! 57: #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) ! 58: #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) ! 59: ! 60: /* Board/System/Debug information/definition ---------------- */ ! 61: #define PCI_DM9132_ID 0x91321282 /* Davicom DM9132 ID */ ! 62: #define PCI_DM9102_ID 0x91021282 /* Davicom DM9102 ID */ ! 63: #define PCI_DM9100_ID 0x91001282 /* Davicom DM9100 ID */ ! 64: #define PCI_DM9009_ID 0x90091282 /* Davicom DM9009 ID */ ! 65: ! 66: #define DM9102_IO_SIZE 0x80 ! 67: #define DM9102A_IO_SIZE 0x100 ! 68: #define TX_MAX_SEND_CNT 0x1 /* Maximum tx packet per time */ ! 69: #define TX_DESC_CNT 0x10 /* Allocated Tx descriptors */ ! 70: #define RX_DESC_CNT 0x20 /* Allocated Rx descriptors */ ! 71: #define TX_FREE_DESC_CNT (TX_DESC_CNT - 2) /* Max TX packet count */ ! 72: #define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3) /* TX wakeup count */ ! 73: #define DESC_ALL_CNT (TX_DESC_CNT + RX_DESC_CNT) ! 74: #define TX_BUF_ALLOC 0x600 ! 75: #define RX_ALLOC_SIZE 0x620 ! 76: #define DM910X_RESET 1 ! 77: #define CR0_DEFAULT 0x00E00000 /* TX & RX burst mode */ ! 78: #define CR6_DEFAULT 0x00080000 /* HD */ ! 79: #define CR7_DEFAULT 0x180c1 ! 80: #define CR15_DEFAULT 0x06 /* TxJabber RxWatchdog */ ! 81: #define TDES0_ERR_MASK 0x4302 /* TXJT, LC, EC, FUE */ ! 82: #define MAX_PACKET_SIZE 1514 ! 83: #define DMFE_MAX_MULTICAST 14 ! 84: #define RX_COPY_SIZE 100 ! 85: #define MAX_CHECK_PACKET 0x8000 ! 86: #define DM9801_NOISE_FLOOR 8 ! 87: #define DM9802_NOISE_FLOOR 5 ! 88: ! 89: #define DMFE_10MHF 0 ! 90: #define DMFE_100MHF 1 ! 91: #define DMFE_10MFD 4 ! 92: #define DMFE_100MFD 5 ! 93: #define DMFE_AUTO 8 ! 94: #define DMFE_1M_HPNA 0x10 ! 95: ! 96: #define DMFE_TXTH_72 0x400000 /* TX TH 72 byte */ ! 97: #define DMFE_TXTH_96 0x404000 /* TX TH 96 byte */ ! 98: #define DMFE_TXTH_128 0x0000 /* TX TH 128 byte */ ! 99: #define DMFE_TXTH_256 0x4000 /* TX TH 256 byte */ ! 100: #define DMFE_TXTH_512 0x8000 /* TX TH 512 byte */ ! 101: #define DMFE_TXTH_1K 0xC000 /* TX TH 1K byte */ ! 102: ! 103: #define DMFE_TIMER_WUT (jiffies + HZ * 1) /* timer wakeup time : 1 second */ ! 104: #define DMFE_TX_TIMEOUT ((3*HZ)/2) /* tx packet time-out time 1.5 s" */ ! 105: #define DMFE_TX_KICK (HZ/2) /* tx packet Kick-out time 0.5 s" */ ! 106: ! 107: #define DMFE_DBUG(dbug_now, msg, value) if (dmfe_debug || (dbug_now)) printk(KERN_ERR DRV_NAME ": %s %lx\n", (msg), (long) (value)) ! 108: ! 109: #define SHOW_MEDIA_TYPE(mode) printk(KERN_ERR DRV_NAME ": Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half"); ! 110: ! 111: ! 112: /* CR9 definition: SROM/MII */ ! 113: #define CR9_SROM_READ 0x4800 ! 114: #define CR9_SRCS 0x1 ! 115: #define CR9_SRCLK 0x2 ! 116: #define CR9_CRDOUT 0x8 ! 117: #define SROM_DATA_0 0x0 ! 118: #define SROM_DATA_1 0x4 ! 119: #define PHY_DATA_1 0x20000 ! 120: #define PHY_DATA_0 0x00000 ! 121: #define MDCLKH 0x10000 ! 122: ! 123: #define PHY_POWER_DOWN 0x800 ! 124: ! 125: #define SROM_V41_CODE 0x14 ! 126: ! 127: #define SROM_CLK_WRITE(data, ioaddr) outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5); ! 128: ! 129: #define __CHK_IO_SIZE(pci_id, dev_rev) ( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x02000030) ) ? DM9102A_IO_SIZE: DM9102_IO_SIZE ! 130: #define CHK_IO_SIZE(pci_dev, dev_rev) __CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, dev_rev) ! 131: ! 132: /* Sten Check */ ! 133: #define DEVICE net_device ! 134: ! 135: /* Structure/enum declaration ------------------------------- */ ! 136: struct tx_desc { ! 137: u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */ ! 138: void * tx_buf_ptr; /* Data for us */ ! 139: struct tx_desc * next_tx_desc; ! 140: } __attribute__ ((aligned(32))); ! 141: ! 142: struct rx_desc { ! 143: u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */ ! 144: void * rx_skb_ptr; /* Data for us */ ! 145: struct rx_desc * next_rx_desc; ! 146: } __attribute__ ((aligned(32))); ! 147: ! 148: static struct dmfe_private { ! 149: u32 chip_id; /* Chip vendor/Device ID */ ! 150: u32 chip_revision; /* Chip revision */ ! 151: u32 cr0_data; ! 152: // u32 cr5_data; ! 153: u32 cr6_data; ! 154: u32 cr7_data; ! 155: u32 cr15_data; ! 156: ! 157: u16 HPNA_command; /* For HPNA register 16 */ ! 158: u16 HPNA_timer; /* For HPNA remote device check */ ! 159: u16 NIC_capability; /* NIC media capability */ ! 160: u16 PHY_reg4; /* Saved Phyxcer register 4 value */ ! 161: ! 162: u8 HPNA_present; /* 0:none, 1:DM9801, 2:DM9802 */ ! 163: u8 chip_type; /* Keep DM9102A chip type */ ! 164: u8 media_mode; /* user specify media mode */ ! 165: u8 op_mode; /* real work media mode */ ! 166: u8 phy_addr; ! 167: u8 dm910x_chk_mode; /* Operating mode check */ ! 168: ! 169: /* NIC SROM data */ ! 170: unsigned char srom[128]; ! 171: /* Etherboot Only */ ! 172: u8 cur_tx; ! 173: u8 cur_rx; ! 174: } dfx; ! 175: ! 176: static struct dmfe_private *db; ! 177: ! 178: enum dmfe_offsets { ! 179: DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20, ! 180: DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48, ! 181: DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = ! 182: 0x70, ! 183: DCR15 = 0x78 ! 184: }; ! 185: ! 186: enum dmfe_CR6_bits { ! 187: CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80, ! 188: CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000, ! 189: CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000 ! 190: }; ! 191: ! 192: /* Global variable declaration ----------------------------- */ ! 193: static struct nic_operations dmfe_operations; ! 194: ! 195: static unsigned char dmfe_media_mode = DMFE_AUTO; ! 196: static u32 dmfe_cr6_user_set; ! 197: ! 198: /* For module input parameter */ ! 199: static u8 chkmode = 1; ! 200: static u8 HPNA_mode; /* Default: Low Power/High Speed */ ! 201: static u8 HPNA_rx_cmd; /* Default: Disable Rx remote command */ ! 202: static u8 HPNA_tx_cmd; /* Default: Don't issue remote command */ ! 203: static u8 HPNA_NoiseFloor; /* Default: HPNA NoiseFloor */ ! 204: static u8 SF_mode; /* Special Function: 1:VLAN, 2:RX Flow Control ! 205: 4: TX pause packet */ ! 206: ! 207: ! 208: /********************************************** ! 209: * Descriptor Ring and Buffer defination ! 210: ***********************************************/ ! 211: struct { ! 212: struct tx_desc txd[TX_DESC_CNT] __attribute__ ((aligned(32))); ! 213: unsigned char txb[TX_BUF_ALLOC * TX_DESC_CNT] ! 214: __attribute__ ((aligned(32))); ! 215: struct rx_desc rxd[RX_DESC_CNT] __attribute__ ((aligned(32))); ! 216: unsigned char rxb[RX_ALLOC_SIZE * RX_DESC_CNT] ! 217: __attribute__ ((aligned(32))); ! 218: } dmfe_bufs __shared; ! 219: #define txd dmfe_bufs.txd ! 220: #define txb dmfe_bufs.txb ! 221: #define rxd dmfe_bufs.rxd ! 222: #define rxb dmfe_bufs.rxb ! 223: ! 224: /* NIC specific static variables go here */ ! 225: static long int BASE; ! 226: ! 227: static u16 read_srom_word(long ioaddr, int offset); ! 228: static void dmfe_init_dm910x(struct nic *nic); ! 229: static void dmfe_descriptor_init(struct nic *, unsigned long ioaddr); ! 230: static void update_cr6(u32, unsigned long); ! 231: static void send_filter_frame(struct nic *nic); ! 232: static void dm9132_id_table(struct nic *nic); ! 233: ! 234: static u16 phy_read(unsigned long, u8, u8, u32); ! 235: static void phy_write(unsigned long, u8, u8, u16, u32); ! 236: static void phy_write_1bit(unsigned long, u32); ! 237: static u16 phy_read_1bit(unsigned long); ! 238: static void dmfe_set_phyxcer(struct nic *nic); ! 239: ! 240: static void dmfe_parse_srom(struct nic *nic); ! 241: static void dmfe_program_DM9801(struct nic *nic, int); ! 242: static void dmfe_program_DM9802(struct nic *nic); ! 243: ! 244: static void dmfe_reset(struct nic *nic) ! 245: { ! 246: /* system variable init */ ! 247: db->cr6_data = CR6_DEFAULT | dmfe_cr6_user_set; ! 248: ! 249: db->NIC_capability = 0xf; /* All capability */ ! 250: db->PHY_reg4 = 0x1e0; ! 251: ! 252: /* CR6 operation mode decision */ ! 253: if (!chkmode || (db->chip_id == PCI_DM9132_ID) || ! 254: (db->chip_revision >= 0x02000030)) { ! 255: db->cr6_data |= DMFE_TXTH_256; ! 256: db->cr0_data = CR0_DEFAULT; ! 257: db->dm910x_chk_mode = 4; /* Enter the normal mode */ ! 258: } else { ! 259: db->cr6_data |= CR6_SFT; /* Store & Forward mode */ ! 260: db->cr0_data = 0; ! 261: db->dm910x_chk_mode = 1; /* Enter the check mode */ ! 262: } ! 263: /* Initilize DM910X board */ ! 264: dmfe_init_dm910x(nic); ! 265: ! 266: return; ! 267: } ! 268: ! 269: /* Initilize DM910X board ! 270: * Reset DM910X board ! 271: * Initilize TX/Rx descriptor chain structure ! 272: * Send the set-up frame ! 273: * Enable Tx/Rx machine ! 274: */ ! 275: ! 276: static void dmfe_init_dm910x(struct nic *nic) ! 277: { ! 278: unsigned long ioaddr = BASE; ! 279: ! 280: /* Reset DM910x MAC controller */ ! 281: outl(DM910X_RESET, ioaddr + DCR0); /* RESET MAC */ ! 282: udelay(100); ! 283: outl(db->cr0_data, ioaddr + DCR0); ! 284: udelay(5); ! 285: ! 286: /* Phy addr : DM910(A)2/DM9132/9801, phy address = 1 */ ! 287: db->phy_addr = 1; ! 288: ! 289: /* Parser SROM and media mode */ ! 290: dmfe_parse_srom(nic); ! 291: db->media_mode = dmfe_media_mode; ! 292: ! 293: /* RESET Phyxcer Chip by GPR port bit 7 */ ! 294: outl(0x180, ioaddr + DCR12); /* Let bit 7 output port */ ! 295: if (db->chip_id == PCI_DM9009_ID) { ! 296: outl(0x80, ioaddr + DCR12); /* Issue RESET signal */ ! 297: mdelay(300); /* Delay 300 ms */ ! 298: } ! 299: outl(0x0, ioaddr + DCR12); /* Clear RESET signal */ ! 300: ! 301: /* Process Phyxcer Media Mode */ ! 302: if (!(db->media_mode & 0x10)) /* Force 1M mode */ ! 303: dmfe_set_phyxcer(nic); ! 304: ! 305: /* Media Mode Process */ ! 306: if (!(db->media_mode & DMFE_AUTO)) ! 307: db->op_mode = db->media_mode; /* Force Mode */ ! 308: ! 309: /* Initiliaze Transmit/Receive decriptor and CR3/4 */ ! 310: dmfe_descriptor_init(nic, ioaddr); ! 311: ! 312: /* tx descriptor start pointer */ ! 313: outl(virt_to_le32desc(&txd[0]), ioaddr + DCR4); /* TX DESC address */ ! 314: ! 315: /* rx descriptor start pointer */ ! 316: outl(virt_to_le32desc(&rxd[0]), ioaddr + DCR3); /* RX DESC address */ ! 317: ! 318: /* Init CR6 to program DM910x operation */ ! 319: update_cr6(db->cr6_data, ioaddr); ! 320: ! 321: /* Send setup frame */ ! 322: if (db->chip_id == PCI_DM9132_ID) { ! 323: dm9132_id_table(nic); /* DM9132 */ ! 324: } else { ! 325: send_filter_frame(nic); /* DM9102/DM9102A */ ! 326: } ! 327: ! 328: /* Init CR7, interrupt active bit */ ! 329: db->cr7_data = CR7_DEFAULT; ! 330: outl(db->cr7_data, ioaddr + DCR7); ! 331: /* Init CR15, Tx jabber and Rx watchdog timer */ ! 332: outl(db->cr15_data, ioaddr + DCR15); ! 333: /* Enable DM910X Tx/Rx function */ ! 334: db->cr6_data |= CR6_RXSC | CR6_TXSC | 0x40000; ! 335: update_cr6(db->cr6_data, ioaddr); ! 336: } ! 337: #ifdef EDEBUG ! 338: void hex_dump(const char *data, const unsigned int len); ! 339: #endif ! 340: /************************************************************************** ! 341: POLL - Wait for a frame ! 342: ***************************************************************************/ ! 343: static int dmfe_poll(struct nic *nic, int retrieve) ! 344: { ! 345: u32 rdes0; ! 346: int entry = db->cur_rx % RX_DESC_CNT; ! 347: int rxlen; ! 348: rdes0 = le32_to_cpu(rxd[entry].rdes0); ! 349: if (rdes0 & 0x80000000) ! 350: return 0; ! 351: ! 352: if (!retrieve) ! 353: return 1; ! 354: ! 355: if ((rdes0 & 0x300) != 0x300) { ! 356: /* A packet without First/Last flag */ ! 357: printf("strange Packet\n"); ! 358: rxd[entry].rdes0 = cpu_to_le32(0x80000000); ! 359: return 0; ! 360: } else { ! 361: /* A packet with First/Last flag */ ! 362: rxlen = ((rdes0 >> 16) & 0x3fff) - 4; ! 363: /* error summary bit check */ ! 364: if (rdes0 & 0x8000) { ! 365: printf("Error\n"); ! 366: return 0; ! 367: } ! 368: if (!(rdes0 & 0x8000) || ! 369: ((db->cr6_data & CR6_PM) && (rxlen > 6))) { ! 370: if (db->dm910x_chk_mode & 1) ! 371: printf("Silly check mode\n"); ! 372: ! 373: nic->packetlen = rxlen; ! 374: memcpy(nic->packet, rxb + (entry * RX_ALLOC_SIZE), ! 375: nic->packetlen); ! 376: } ! 377: } ! 378: rxd[entry].rdes0 = cpu_to_le32(0x80000000); ! 379: db->cur_rx++; ! 380: return 1; ! 381: } ! 382: ! 383: static void dmfe_irq(struct nic *nic __unused, irq_action_t action __unused) ! 384: { ! 385: switch ( action ) { ! 386: case DISABLE : ! 387: break; ! 388: case ENABLE : ! 389: break; ! 390: case FORCE : ! 391: break; ! 392: } ! 393: } ! 394: ! 395: /************************************************************************** ! 396: TRANSMIT - Transmit a frame ! 397: ***************************************************************************/ ! 398: static void dmfe_transmit(struct nic *nic, ! 399: const char *dest, /* Destination */ ! 400: unsigned int type, /* Type */ ! 401: unsigned int size, /* size */ ! 402: const char *packet) /* Packet */ ! 403: { ! 404: u16 nstype; ! 405: u8 *ptxb; ! 406: ! 407: ptxb = &txb[db->cur_tx]; ! 408: ! 409: /* Stop Tx */ ! 410: outl(0, BASE + DCR7); ! 411: memcpy(ptxb, dest, ETH_ALEN); ! 412: memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); ! 413: nstype = htons((u16) type); ! 414: memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); ! 415: memcpy(ptxb + ETH_HLEN, packet, size); ! 416: ! 417: size += ETH_HLEN; ! 418: while (size < ETH_ZLEN) ! 419: ptxb[size++] = '\0'; ! 420: ! 421: /* setup the transmit descriptor */ ! 422: txd[db->cur_tx].tdes1 = cpu_to_le32(0xe1000000 | size); ! 423: txd[db->cur_tx].tdes0 = cpu_to_le32(0x80000000); /* give ownership to device */ ! 424: ! 425: /* immediate transmit demand */ ! 426: outl(0x1, BASE + DCR1); ! 427: outl(db->cr7_data, BASE + DCR7); ! 428: ! 429: /* Point to next TX descriptor */ ! 430: db->cur_tx++; ! 431: db->cur_tx = db->cur_tx % TX_DESC_CNT; ! 432: } ! 433: ! 434: /************************************************************************** ! 435: DISABLE - Turn off ethernet interface ! 436: ***************************************************************************/ ! 437: static void dmfe_disable ( struct nic *nic __unused ) { ! 438: /* Reset & stop DM910X board */ ! 439: outl(DM910X_RESET, BASE + DCR0); ! 440: udelay(5); ! 441: phy_write(BASE, db->phy_addr, 0, 0x8000, db->chip_id); ! 442: ! 443: } ! 444: ! 445: /************************************************************************** ! 446: PROBE - Look for an adapter, this routine's visible to the outside ! 447: ***************************************************************************/ ! 448: ! 449: #define board_found 1 ! 450: #define valid_link 0 ! 451: static int dmfe_probe ( struct nic *nic, struct pci_device *pci ) { ! 452: ! 453: uint32_t dev_rev, pci_pmr; ! 454: int i; ! 455: ! 456: if (pci->ioaddr == 0) ! 457: return 0; ! 458: ! 459: BASE = pci->ioaddr; ! 460: printf("dmfe.c: Found %s Vendor=0x%hX Device=0x%hX\n", ! 461: pci->id->name, pci->vendor, pci->device); ! 462: ! 463: /* Read Chip revision */ ! 464: pci_read_config_dword(pci, PCI_REVISION_ID, &dev_rev); ! 465: dprintf(("Revision %lX\n", dev_rev)); ! 466: ! 467: /* point to private storage */ ! 468: db = &dfx; ! 469: ! 470: db->chip_id = ((u32) pci->device << 16) | pci->vendor; ! 471: BASE = pci_bar_start(pci, PCI_BASE_ADDRESS_0); ! 472: db->chip_revision = dev_rev; ! 473: ! 474: pci_read_config_dword(pci, 0x50, &pci_pmr); ! 475: pci_pmr &= 0x70000; ! 476: if ((pci_pmr == 0x10000) && (dev_rev == 0x02000031)) ! 477: db->chip_type = 1; /* DM9102A E3 */ ! 478: else ! 479: db->chip_type = 0; ! 480: ! 481: dprintf(("Chip type : %d\n", db->chip_type)); ! 482: ! 483: /* read 64 word srom data */ ! 484: for (i = 0; i < 64; i++) ! 485: ((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(BASE, i)); ! 486: ! 487: /* Set Node address */ ! 488: for (i = 0; i < 6; i++) ! 489: nic->node_addr[i] = db->srom[20 + i]; ! 490: ! 491: /* Print out some hardware info */ ! 492: DBG ( "%s: %s at ioaddr %4.4lx\n", ! 493: pci->id->name, eth_ntoa ( nic->node_addr ), BASE ); ! 494: ! 495: /* Set the card as PCI Bus Master */ ! 496: adjust_pci_device(pci); ! 497: ! 498: dmfe_reset(nic); ! 499: ! 500: nic->irqno = 0; ! 501: nic->ioaddr = pci->ioaddr; ! 502: ! 503: /* point to NIC specific routines */ ! 504: nic->nic_op = &dmfe_operations; ! 505: ! 506: return 1; ! 507: } ! 508: ! 509: /* ! 510: * Initialize transmit/Receive descriptor ! 511: * Using Chain structure, and allocate Tx/Rx buffer ! 512: */ ! 513: ! 514: static void dmfe_descriptor_init(struct nic *nic __unused, unsigned long ioaddr) ! 515: { ! 516: int i; ! 517: db->cur_tx = 0; ! 518: db->cur_rx = 0; ! 519: ! 520: /* tx descriptor start pointer */ ! 521: outl(virt_to_le32desc(&txd[0]), ioaddr + DCR4); /* TX DESC address */ ! 522: ! 523: /* rx descriptor start pointer */ ! 524: outl(virt_to_le32desc(&rxd[0]), ioaddr + DCR3); /* RX DESC address */ ! 525: ! 526: /* Init Transmit chain */ ! 527: for (i = 0; i < TX_DESC_CNT; i++) { ! 528: txd[i].tx_buf_ptr = &txb[i]; ! 529: txd[i].tdes0 = cpu_to_le32(0); ! 530: txd[i].tdes1 = cpu_to_le32(0x81000000); /* IC, chain */ ! 531: txd[i].tdes2 = cpu_to_le32(virt_to_bus(&txb[i])); ! 532: txd[i].tdes3 = cpu_to_le32(virt_to_bus(&txd[i + 1])); ! 533: txd[i].next_tx_desc = &txd[i + 1]; ! 534: } ! 535: /* Mark the last entry as wrapping the ring */ ! 536: txd[i - 1].tdes3 = virt_to_le32desc(&txd[0]); ! 537: txd[i - 1].next_tx_desc = &txd[0]; ! 538: ! 539: /* receive descriptor chain */ ! 540: for (i = 0; i < RX_DESC_CNT; i++) { ! 541: rxd[i].rx_skb_ptr = &rxb[i * RX_ALLOC_SIZE]; ! 542: rxd[i].rdes0 = cpu_to_le32(0x80000000); ! 543: rxd[i].rdes1 = cpu_to_le32(0x01000600); ! 544: rxd[i].rdes2 = ! 545: cpu_to_le32(virt_to_bus(&rxb[i * RX_ALLOC_SIZE])); ! 546: rxd[i].rdes3 = cpu_to_le32(virt_to_bus(&rxd[i + 1])); ! 547: rxd[i].next_rx_desc = &rxd[i + 1]; ! 548: } ! 549: /* Mark the last entry as wrapping the ring */ ! 550: rxd[i - 1].rdes3 = cpu_to_le32(virt_to_bus(&rxd[0])); ! 551: rxd[i - 1].next_rx_desc = &rxd[0]; ! 552: ! 553: } ! 554: ! 555: /* ! 556: * Update CR6 value ! 557: * Firstly stop DM910X , then written value and start ! 558: */ ! 559: ! 560: static void update_cr6(u32 cr6_data, unsigned long ioaddr) ! 561: { ! 562: u32 cr6_tmp; ! 563: ! 564: cr6_tmp = cr6_data & ~0x2002; /* stop Tx/Rx */ ! 565: outl(cr6_tmp, ioaddr + DCR6); ! 566: udelay(5); ! 567: outl(cr6_data, ioaddr + DCR6); ! 568: udelay(5); ! 569: } ! 570: ! 571: ! 572: /* ! 573: * Send a setup frame for DM9132 ! 574: * This setup frame initilize DM910X addres filter mode ! 575: */ ! 576: ! 577: static void dm9132_id_table(struct nic *nic __unused) ! 578: { ! 579: #ifdef LINUX ! 580: u16 *addrptr; ! 581: u8 dmi_addr[8]; ! 582: unsigned long ioaddr = BASE + 0xc0; /* ID Table */ ! 583: u32 hash_val; ! 584: u16 i, hash_table[4]; ! 585: #endif ! 586: dprintf(("dm9132_id_table\n")); ! 587: ! 588: printf("FIXME: This function is broken. If you have this card contact " ! 589: "Timothy Legge at the etherboot-user list\n"); ! 590: ! 591: #ifdef LINUX ! 592: //DMFE_DBUG(0, "dm9132_id_table()", 0); ! 593: ! 594: /* Node address */ ! 595: addrptr = (u16 *) nic->node_addr; ! 596: outw(addrptr[0], ioaddr); ! 597: ioaddr += 4; ! 598: outw(addrptr[1], ioaddr); ! 599: ioaddr += 4; ! 600: outw(addrptr[2], ioaddr); ! 601: ioaddr += 4; ! 602: ! 603: /* Clear Hash Table */ ! 604: for (i = 0; i < 4; i++) ! 605: hash_table[i] = 0x0; ! 606: ! 607: /* broadcast address */ ! 608: hash_table[3] = 0x8000; ! 609: ! 610: /* the multicast address in Hash Table : 64 bits */ ! 611: for (mcptr = mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { ! 612: hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f; ! 613: hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); ! 614: } ! 615: ! 616: /* Write the hash table to MAC MD table */ ! 617: for (i = 0; i < 4; i++, ioaddr += 4) ! 618: outw(hash_table[i], ioaddr); ! 619: #endif ! 620: } ! 621: ! 622: ! 623: /* ! 624: * Send a setup frame for DM9102/DM9102A ! 625: * This setup frame initilize DM910X addres filter mode ! 626: */ ! 627: ! 628: static void send_filter_frame(struct nic *nic) ! 629: { ! 630: ! 631: u8 *ptxb; ! 632: int i; ! 633: ! 634: dprintf(("send_filter_frame\n")); ! 635: /* point to the current txb incase multiple tx_rings are used */ ! 636: ptxb = &txb[db->cur_tx]; ! 637: ! 638: /* construct perfect filter frame with mac address as first match ! 639: and broadcast address for all others */ ! 640: for (i = 0; i < 192; i++) ! 641: ptxb[i] = 0xFF; ! 642: ptxb[0] = nic->node_addr[0]; ! 643: ptxb[1] = nic->node_addr[1]; ! 644: ptxb[4] = nic->node_addr[2]; ! 645: ptxb[5] = nic->node_addr[3]; ! 646: ptxb[8] = nic->node_addr[4]; ! 647: ptxb[9] = nic->node_addr[5]; ! 648: ! 649: /* prepare the setup frame */ ! 650: txd[db->cur_tx].tdes1 = cpu_to_le32(0x890000c0); ! 651: txd[db->cur_tx].tdes0 = cpu_to_le32(0x80000000); ! 652: update_cr6(db->cr6_data | 0x2000, BASE); ! 653: outl(0x1, BASE + DCR1); /* Issue Tx polling */ ! 654: update_cr6(db->cr6_data, BASE); ! 655: db->cur_tx++; ! 656: } ! 657: ! 658: /* ! 659: * Read one word data from the serial ROM ! 660: */ ! 661: ! 662: static u16 read_srom_word(long ioaddr, int offset) ! 663: { ! 664: int i; ! 665: u16 srom_data = 0; ! 666: long cr9_ioaddr = ioaddr + DCR9; ! 667: ! 668: outl(CR9_SROM_READ, cr9_ioaddr); ! 669: outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); ! 670: ! 671: /* Send the Read Command 110b */ ! 672: SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); ! 673: SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); ! 674: SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr); ! 675: ! 676: /* Send the offset */ ! 677: for (i = 5; i >= 0; i--) { ! 678: srom_data = ! 679: (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0; ! 680: SROM_CLK_WRITE(srom_data, cr9_ioaddr); ! 681: } ! 682: ! 683: outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); ! 684: ! 685: for (i = 16; i > 0; i--) { ! 686: outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr); ! 687: udelay(5); ! 688: srom_data = ! 689: (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 ! 690: : 0); ! 691: outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); ! 692: udelay(5); ! 693: } ! 694: ! 695: outl(CR9_SROM_READ, cr9_ioaddr); ! 696: return srom_data; ! 697: } ! 698: ! 699: ! 700: /* ! 701: * Auto sense the media mode ! 702: */ ! 703: ! 704: #if 0 /* not used */ ! 705: static u8 dmfe_sense_speed(struct nic *nic __unused) ! 706: { ! 707: u8 ErrFlag = 0; ! 708: u16 phy_mode; ! 709: ! 710: /* CR6 bit18=0, select 10/100M */ ! 711: update_cr6((db->cr6_data & ~0x40000), BASE); ! 712: ! 713: phy_mode = phy_read(BASE, db->phy_addr, 1, db->chip_id); ! 714: phy_mode = phy_read(BASE, db->phy_addr, 1, db->chip_id); ! 715: ! 716: if ((phy_mode & 0x24) == 0x24) { ! 717: if (db->chip_id == PCI_DM9132_ID) /* DM9132 */ ! 718: phy_mode = ! 719: phy_read(BASE, db->phy_addr, 7, ! 720: db->chip_id) & 0xf000; ! 721: else /* DM9102/DM9102A */ ! 722: phy_mode = ! 723: phy_read(BASE, db->phy_addr, 17, ! 724: db->chip_id) & 0xf000; ! 725: /* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */ ! 726: switch (phy_mode) { ! 727: case 0x1000: ! 728: db->op_mode = DMFE_10MHF; ! 729: break; ! 730: case 0x2000: ! 731: db->op_mode = DMFE_10MFD; ! 732: break; ! 733: case 0x4000: ! 734: db->op_mode = DMFE_100MHF; ! 735: break; ! 736: case 0x8000: ! 737: db->op_mode = DMFE_100MFD; ! 738: break; ! 739: default: ! 740: db->op_mode = DMFE_10MHF; ! 741: ErrFlag = 1; ! 742: break; ! 743: } ! 744: } else { ! 745: db->op_mode = DMFE_10MHF; ! 746: //DMFE_DBUG(0, "Link Failed :", phy_mode); ! 747: ErrFlag = 1; ! 748: } ! 749: ! 750: return ErrFlag; ! 751: } ! 752: #endif ! 753: ! 754: /* ! 755: * Set 10/100 phyxcer capability ! 756: * AUTO mode : phyxcer register4 is NIC capability ! 757: * Force mode: phyxcer register4 is the force media ! 758: */ ! 759: ! 760: static void dmfe_set_phyxcer(struct nic *nic __unused) ! 761: { ! 762: u16 phy_reg; ! 763: ! 764: /* Select 10/100M phyxcer */ ! 765: db->cr6_data &= ~0x40000; ! 766: update_cr6(db->cr6_data, BASE); ! 767: ! 768: /* DM9009 Chip: Phyxcer reg18 bit12=0 */ ! 769: if (db->chip_id == PCI_DM9009_ID) { ! 770: phy_reg = ! 771: phy_read(BASE, db->phy_addr, 18, ! 772: db->chip_id) & ~0x1000; ! 773: phy_write(BASE, db->phy_addr, 18, phy_reg, db->chip_id); ! 774: } ! 775: ! 776: /* Phyxcer capability setting */ ! 777: phy_reg = phy_read(BASE, db->phy_addr, 4, db->chip_id) & ~0x01e0; ! 778: ! 779: if (db->media_mode & DMFE_AUTO) { ! 780: /* AUTO Mode */ ! 781: phy_reg |= db->PHY_reg4; ! 782: } else { ! 783: /* Force Mode */ ! 784: switch (db->media_mode) { ! 785: case DMFE_10MHF: ! 786: phy_reg |= 0x20; ! 787: break; ! 788: case DMFE_10MFD: ! 789: phy_reg |= 0x40; ! 790: break; ! 791: case DMFE_100MHF: ! 792: phy_reg |= 0x80; ! 793: break; ! 794: case DMFE_100MFD: ! 795: phy_reg |= 0x100; ! 796: break; ! 797: } ! 798: if (db->chip_id == PCI_DM9009_ID) ! 799: phy_reg &= 0x61; ! 800: } ! 801: ! 802: /* Write new capability to Phyxcer Reg4 */ ! 803: if (!(phy_reg & 0x01e0)) { ! 804: phy_reg |= db->PHY_reg4; ! 805: db->media_mode |= DMFE_AUTO; ! 806: } ! 807: phy_write(BASE, db->phy_addr, 4, phy_reg, db->chip_id); ! 808: ! 809: /* Restart Auto-Negotiation */ ! 810: if (db->chip_type && (db->chip_id == PCI_DM9102_ID)) ! 811: phy_write(BASE, db->phy_addr, 0, 0x1800, db->chip_id); ! 812: if (!db->chip_type) ! 813: phy_write(BASE, db->phy_addr, 0, 0x1200, db->chip_id); ! 814: } ! 815: ! 816: ! 817: /* ! 818: * Process op-mode ! 819: * AUTO mode : PHY controller in Auto-negotiation Mode ! 820: * Force mode: PHY controller in force mode with HUB ! 821: * N-way force capability with SWITCH ! 822: */ ! 823: ! 824: #if 0 /* not used */ ! 825: static void dmfe_process_mode(struct nic *nic __unused) ! 826: { ! 827: u16 phy_reg; ! 828: ! 829: /* Full Duplex Mode Check */ ! 830: if (db->op_mode & 0x4) ! 831: db->cr6_data |= CR6_FDM; /* Set Full Duplex Bit */ ! 832: else ! 833: db->cr6_data &= ~CR6_FDM; /* Clear Full Duplex Bit */ ! 834: ! 835: /* Transciver Selection */ ! 836: if (db->op_mode & 0x10) /* 1M HomePNA */ ! 837: db->cr6_data |= 0x40000; /* External MII select */ ! 838: else ! 839: db->cr6_data &= ~0x40000; /* Internal 10/100 transciver */ ! 840: ! 841: update_cr6(db->cr6_data, BASE); ! 842: ! 843: /* 10/100M phyxcer force mode need */ ! 844: if (!(db->media_mode & 0x18)) { ! 845: /* Forece Mode */ ! 846: phy_reg = phy_read(BASE, db->phy_addr, 6, db->chip_id); ! 847: if (!(phy_reg & 0x1)) { ! 848: /* parter without N-Way capability */ ! 849: phy_reg = 0x0; ! 850: switch (db->op_mode) { ! 851: case DMFE_10MHF: ! 852: phy_reg = 0x0; ! 853: break; ! 854: case DMFE_10MFD: ! 855: phy_reg = 0x100; ! 856: break; ! 857: case DMFE_100MHF: ! 858: phy_reg = 0x2000; ! 859: break; ! 860: case DMFE_100MFD: ! 861: phy_reg = 0x2100; ! 862: break; ! 863: } ! 864: phy_write(BASE, db->phy_addr, 0, phy_reg, ! 865: db->chip_id); ! 866: if (db->chip_type ! 867: && (db->chip_id == PCI_DM9102_ID)) ! 868: mdelay(20); ! 869: phy_write(BASE, db->phy_addr, 0, phy_reg, ! 870: db->chip_id); ! 871: } ! 872: } ! 873: } ! 874: #endif ! 875: ! 876: /* ! 877: * Write a word to Phy register ! 878: */ ! 879: ! 880: static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, ! 881: u16 phy_data, u32 chip_id) ! 882: { ! 883: u16 i; ! 884: unsigned long ioaddr; ! 885: ! 886: if (chip_id == PCI_DM9132_ID) { ! 887: ioaddr = iobase + 0x80 + offset * 4; ! 888: outw(phy_data, ioaddr); ! 889: } else { ! 890: /* DM9102/DM9102A Chip */ ! 891: ioaddr = iobase + DCR9; ! 892: ! 893: /* Send 33 synchronization clock to Phy controller */ ! 894: for (i = 0; i < 35; i++) ! 895: phy_write_1bit(ioaddr, PHY_DATA_1); ! 896: ! 897: /* Send start command(01) to Phy */ ! 898: phy_write_1bit(ioaddr, PHY_DATA_0); ! 899: phy_write_1bit(ioaddr, PHY_DATA_1); ! 900: ! 901: /* Send write command(01) to Phy */ ! 902: phy_write_1bit(ioaddr, PHY_DATA_0); ! 903: phy_write_1bit(ioaddr, PHY_DATA_1); ! 904: ! 905: /* Send Phy addres */ ! 906: for (i = 0x10; i > 0; i = i >> 1) ! 907: phy_write_1bit(ioaddr, ! 908: phy_addr & i ? PHY_DATA_1 : ! 909: PHY_DATA_0); ! 910: ! 911: /* Send register addres */ ! 912: for (i = 0x10; i > 0; i = i >> 1) ! 913: phy_write_1bit(ioaddr, ! 914: offset & i ? PHY_DATA_1 : ! 915: PHY_DATA_0); ! 916: ! 917: /* written trasnition */ ! 918: phy_write_1bit(ioaddr, PHY_DATA_1); ! 919: phy_write_1bit(ioaddr, PHY_DATA_0); ! 920: ! 921: /* Write a word data to PHY controller */ ! 922: for (i = 0x8000; i > 0; i >>= 1) ! 923: phy_write_1bit(ioaddr, ! 924: phy_data & i ? PHY_DATA_1 : ! 925: PHY_DATA_0); ! 926: } ! 927: } ! 928: ! 929: ! 930: /* ! 931: * Read a word data from phy register ! 932: */ ! 933: ! 934: static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, ! 935: u32 chip_id) ! 936: { ! 937: int i; ! 938: u16 phy_data; ! 939: unsigned long ioaddr; ! 940: ! 941: if (chip_id == PCI_DM9132_ID) { ! 942: /* DM9132 Chip */ ! 943: ioaddr = iobase + 0x80 + offset * 4; ! 944: phy_data = inw(ioaddr); ! 945: } else { ! 946: /* DM9102/DM9102A Chip */ ! 947: ioaddr = iobase + DCR9; ! 948: ! 949: /* Send 33 synchronization clock to Phy controller */ ! 950: for (i = 0; i < 35; i++) ! 951: phy_write_1bit(ioaddr, PHY_DATA_1); ! 952: ! 953: /* Send start command(01) to Phy */ ! 954: phy_write_1bit(ioaddr, PHY_DATA_0); ! 955: phy_write_1bit(ioaddr, PHY_DATA_1); ! 956: ! 957: /* Send read command(10) to Phy */ ! 958: phy_write_1bit(ioaddr, PHY_DATA_1); ! 959: phy_write_1bit(ioaddr, PHY_DATA_0); ! 960: ! 961: /* Send Phy addres */ ! 962: for (i = 0x10; i > 0; i = i >> 1) ! 963: phy_write_1bit(ioaddr, ! 964: phy_addr & i ? PHY_DATA_1 : ! 965: PHY_DATA_0); ! 966: ! 967: /* Send register addres */ ! 968: for (i = 0x10; i > 0; i = i >> 1) ! 969: phy_write_1bit(ioaddr, ! 970: offset & i ? PHY_DATA_1 : ! 971: PHY_DATA_0); ! 972: ! 973: /* Skip transition state */ ! 974: phy_read_1bit(ioaddr); ! 975: ! 976: /* read 16bit data */ ! 977: for (phy_data = 0, i = 0; i < 16; i++) { ! 978: phy_data <<= 1; ! 979: phy_data |= phy_read_1bit(ioaddr); ! 980: } ! 981: } ! 982: ! 983: return phy_data; ! 984: } ! 985: ! 986: ! 987: /* ! 988: * Write one bit data to Phy Controller ! 989: */ ! 990: ! 991: static void phy_write_1bit(unsigned long ioaddr, u32 phy_data) ! 992: { ! 993: outl(phy_data, ioaddr); /* MII Clock Low */ ! 994: udelay(1); ! 995: outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */ ! 996: udelay(1); ! 997: outl(phy_data, ioaddr); /* MII Clock Low */ ! 998: udelay(1); ! 999: } ! 1000: ! 1001: ! 1002: /* ! 1003: * Read one bit phy data from PHY controller ! 1004: */ ! 1005: ! 1006: static u16 phy_read_1bit(unsigned long ioaddr) ! 1007: { ! 1008: u16 phy_data; ! 1009: ! 1010: outl(0x50000, ioaddr); ! 1011: udelay(1); ! 1012: phy_data = (inl(ioaddr) >> 19) & 0x1; ! 1013: outl(0x40000, ioaddr); ! 1014: udelay(1); ! 1015: ! 1016: return phy_data; ! 1017: } ! 1018: ! 1019: ! 1020: /* ! 1021: * Parser SROM and media mode ! 1022: */ ! 1023: ! 1024: static void dmfe_parse_srom(struct nic *nic) ! 1025: { ! 1026: unsigned char *srom = db->srom; ! 1027: int dmfe_mode, tmp_reg; ! 1028: ! 1029: /* Init CR15 */ ! 1030: db->cr15_data = CR15_DEFAULT; ! 1031: ! 1032: /* Check SROM Version */ ! 1033: if (((int) srom[18] & 0xff) == SROM_V41_CODE) { ! 1034: /* SROM V4.01 */ ! 1035: /* Get NIC support media mode */ ! 1036: db->NIC_capability = *(u16 *) (srom + 34); ! 1037: db->PHY_reg4 = 0; ! 1038: for (tmp_reg = 1; tmp_reg < 0x10; tmp_reg <<= 1) { ! 1039: switch (db->NIC_capability & tmp_reg) { ! 1040: case 0x1: ! 1041: db->PHY_reg4 |= 0x0020; ! 1042: break; ! 1043: case 0x2: ! 1044: db->PHY_reg4 |= 0x0040; ! 1045: break; ! 1046: case 0x4: ! 1047: db->PHY_reg4 |= 0x0080; ! 1048: break; ! 1049: case 0x8: ! 1050: db->PHY_reg4 |= 0x0100; ! 1051: break; ! 1052: } ! 1053: } ! 1054: ! 1055: /* Media Mode Force or not check */ ! 1056: dmfe_mode = *((int *) srom + 34) & *((int *) srom + 36); ! 1057: switch (dmfe_mode) { ! 1058: case 0x4: ! 1059: dmfe_media_mode = DMFE_100MHF; ! 1060: break; /* 100MHF */ ! 1061: case 0x2: ! 1062: dmfe_media_mode = DMFE_10MFD; ! 1063: break; /* 10MFD */ ! 1064: case 0x8: ! 1065: dmfe_media_mode = DMFE_100MFD; ! 1066: break; /* 100MFD */ ! 1067: case 0x100: ! 1068: case 0x200: ! 1069: dmfe_media_mode = DMFE_1M_HPNA; ! 1070: break; /* HomePNA */ ! 1071: } ! 1072: ! 1073: /* Special Function setting */ ! 1074: /* VLAN function */ ! 1075: if ((SF_mode & 0x1) || (srom[43] & 0x80)) ! 1076: db->cr15_data |= 0x40; ! 1077: ! 1078: /* Flow Control */ ! 1079: if ((SF_mode & 0x2) || (srom[40] & 0x1)) ! 1080: db->cr15_data |= 0x400; ! 1081: ! 1082: /* TX pause packet */ ! 1083: if ((SF_mode & 0x4) || (srom[40] & 0xe)) ! 1084: db->cr15_data |= 0x9800; ! 1085: } ! 1086: ! 1087: /* Parse HPNA parameter */ ! 1088: db->HPNA_command = 1; ! 1089: ! 1090: /* Accept remote command or not */ ! 1091: if (HPNA_rx_cmd == 0) ! 1092: db->HPNA_command |= 0x8000; ! 1093: ! 1094: /* Issue remote command & operation mode */ ! 1095: if (HPNA_tx_cmd == 1) ! 1096: switch (HPNA_mode) { /* Issue Remote Command */ ! 1097: case 0: ! 1098: db->HPNA_command |= 0x0904; ! 1099: break; ! 1100: case 1: ! 1101: db->HPNA_command |= 0x0a00; ! 1102: break; ! 1103: case 2: ! 1104: db->HPNA_command |= 0x0506; ! 1105: break; ! 1106: case 3: ! 1107: db->HPNA_command |= 0x0602; ! 1108: break; ! 1109: } else ! 1110: switch (HPNA_mode) { /* Don't Issue */ ! 1111: case 0: ! 1112: db->HPNA_command |= 0x0004; ! 1113: break; ! 1114: case 1: ! 1115: db->HPNA_command |= 0x0000; ! 1116: break; ! 1117: case 2: ! 1118: db->HPNA_command |= 0x0006; ! 1119: break; ! 1120: case 3: ! 1121: db->HPNA_command |= 0x0002; ! 1122: break; ! 1123: } ! 1124: ! 1125: /* Check DM9801 or DM9802 present or not */ ! 1126: db->HPNA_present = 0; ! 1127: update_cr6(db->cr6_data | 0x40000, BASE); ! 1128: tmp_reg = phy_read(BASE, db->phy_addr, 3, db->chip_id); ! 1129: if ((tmp_reg & 0xfff0) == 0xb900) { ! 1130: /* DM9801 or DM9802 present */ ! 1131: db->HPNA_timer = 8; ! 1132: if (phy_read(BASE, db->phy_addr, 31, db->chip_id) == ! 1133: 0x4404) { ! 1134: /* DM9801 HomeRun */ ! 1135: db->HPNA_present = 1; ! 1136: dmfe_program_DM9801(nic, tmp_reg); ! 1137: } else { ! 1138: /* DM9802 LongRun */ ! 1139: db->HPNA_present = 2; ! 1140: dmfe_program_DM9802(nic); ! 1141: } ! 1142: } ! 1143: ! 1144: } ! 1145: ! 1146: /* ! 1147: * Init HomeRun DM9801 ! 1148: */ ! 1149: ! 1150: static void dmfe_program_DM9801(struct nic *nic __unused, int HPNA_rev) ! 1151: { ! 1152: u32 reg17, reg25; ! 1153: ! 1154: if (!HPNA_NoiseFloor) ! 1155: HPNA_NoiseFloor = DM9801_NOISE_FLOOR; ! 1156: switch (HPNA_rev) { ! 1157: case 0xb900: /* DM9801 E3 */ ! 1158: db->HPNA_command |= 0x1000; ! 1159: reg25 = phy_read(BASE, db->phy_addr, 24, db->chip_id); ! 1160: reg25 = ((reg25 + HPNA_NoiseFloor) & 0xff) | 0xf000; ! 1161: reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id); ! 1162: break; ! 1163: case 0xb901: /* DM9801 E4 */ ! 1164: reg25 = phy_read(BASE, db->phy_addr, 25, db->chip_id); ! 1165: reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor; ! 1166: reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id); ! 1167: reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor + 3; ! 1168: break; ! 1169: case 0xb902: /* DM9801 E5 */ ! 1170: case 0xb903: /* DM9801 E6 */ ! 1171: default: ! 1172: db->HPNA_command |= 0x1000; ! 1173: reg25 = phy_read(BASE, db->phy_addr, 25, db->chip_id); ! 1174: reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor - 5; ! 1175: reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id); ! 1176: reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor; ! 1177: break; ! 1178: } ! 1179: phy_write(BASE, db->phy_addr, 16, db->HPNA_command, db->chip_id); ! 1180: phy_write(BASE, db->phy_addr, 17, reg17, db->chip_id); ! 1181: phy_write(BASE, db->phy_addr, 25, reg25, db->chip_id); ! 1182: } ! 1183: ! 1184: ! 1185: /* ! 1186: * Init HomeRun DM9802 ! 1187: */ ! 1188: ! 1189: static void dmfe_program_DM9802(struct nic *nic __unused) ! 1190: { ! 1191: u32 phy_reg; ! 1192: ! 1193: if (!HPNA_NoiseFloor) ! 1194: HPNA_NoiseFloor = DM9802_NOISE_FLOOR; ! 1195: phy_write(BASE, db->phy_addr, 16, db->HPNA_command, db->chip_id); ! 1196: phy_reg = phy_read(BASE, db->phy_addr, 25, db->chip_id); ! 1197: phy_reg = (phy_reg & 0xff00) + HPNA_NoiseFloor; ! 1198: phy_write(BASE, db->phy_addr, 25, phy_reg, db->chip_id); ! 1199: } ! 1200: ! 1201: static struct nic_operations dmfe_operations = { ! 1202: .connect = dummy_connect, ! 1203: .poll = dmfe_poll, ! 1204: .transmit = dmfe_transmit, ! 1205: .irq = dmfe_irq, ! 1206: ! 1207: }; ! 1208: ! 1209: static struct pci_device_id dmfe_nics[] = { ! 1210: PCI_ROM(0x1282, 0x9100, "dmfe9100", "Davicom 9100", 0), ! 1211: PCI_ROM(0x1282, 0x9102, "dmfe9102", "Davicom 9102", 0), ! 1212: PCI_ROM(0x1282, 0x9009, "dmfe9009", "Davicom 9009", 0), ! 1213: PCI_ROM(0x1282, 0x9132, "dmfe9132", "Davicom 9132", 0), /* Needs probably some fixing */ ! 1214: }; ! 1215: ! 1216: PCI_DRIVER ( dmfe_driver, dmfe_nics, PCI_NO_CLASS ); ! 1217: ! 1218: DRIVER ( "DMFE/PCI", nic_driver, pci_driver, dmfe_driver, ! 1219: dmfe_probe, dmfe_disable ); ! 1220: ! 1221: /* ! 1222: * Local variables: ! 1223: * c-basic-offset: 8 ! 1224: * c-indent-level: 8 ! 1225: * tab-width: 8 ! 1226: * End: ! 1227: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.