From owner-p4-projects@FreeBSD.ORG Wed Aug 27 23:27:03 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0EB1A16A4C1; Wed, 27 Aug 2003 23:27:03 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C5F8B16A4BF for ; Wed, 27 Aug 2003 23:27:02 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2418F43FD7 for ; Wed, 27 Aug 2003 23:27:01 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h7S6R10U063825 for ; Wed, 27 Aug 2003 23:27:01 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h7S6R0bI063812 for perforce@freebsd.org; Wed, 27 Aug 2003 23:27:00 -0700 (PDT) Date: Wed, 27 Aug 2003 23:27:00 -0700 (PDT) Message-Id: <200308280627.h7S6R0bI063812@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 37061 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Aug 2003 06:27:03 -0000 http://perforce.freebsd.org/chv.cgi?CH=37061 Change 37061 by marcel@marcel_nfs on 2003/08/27 23:26:01 IFC @37059 Affected files ... .. //depot/projects/uart/conf/majors#3 integrate .. //depot/projects/uart/dev/ata/ata-all.c#4 integrate .. //depot/projects/uart/dev/ata/ata-lowlevel.c#3 integrate .. //depot/projects/uart/dev/ata/atapi-cam.c#4 integrate .. //depot/projects/uart/dev/em/README#2 integrate .. //depot/projects/uart/dev/em/if_em.c#4 integrate .. //depot/projects/uart/dev/em/if_em.h#6 integrate .. //depot/projects/uart/dev/em/if_em_hw.c#3 integrate .. //depot/projects/uart/dev/em/if_em_hw.h#2 integrate .. //depot/projects/uart/dev/exca/exca.c#3 integrate .. //depot/projects/uart/dev/sio/sio.c#5 integrate .. //depot/projects/uart/fs/specfs/spec_vnops.c#4 integrate .. //depot/projects/uart/gnu/ext2fs/ext2_vfsops.c#3 integrate .. //depot/projects/uart/gnu/ext2fs/fs.h#2 integrate .. //depot/projects/uart/pccard/pcic.c#2 integrate .. //depot/projects/uart/pci/if_dc.c#11 integrate Differences ... ==== //depot/projects/uart/conf/majors#3 (text+ko) ==== @@ -1,4 +1,4 @@ -# $FreeBSD: src/sys/conf/majors,v 1.176 2003/08/15 14:56:05 phk Exp $ +# $FreeBSD: src/sys/conf/majors,v 1.177 2003/08/27 07:35:12 simokawa Exp $ # # This list is semi-obsoleted by DEVFS, but for now it still contains # the current allocation of device major numbers. @@ -174,6 +174,7 @@ 180 nvidia NVIDIA (nvidiaN/nvidiactl) 181 casm HP/Compaq ProLiant Advanced Server Management 183 *smapi SMAPI BIOS interface +184 dcons Dumb console driver 200 ?? entries from 200-252 are reserved for local use 248 *isp dev/isp/isp_freebsd.c 252 ?? entries from 200-252 are reserved for local use ==== //depot/projects/uart/dev/ata/ata-all.c#4 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ata/ata-all.c,v 1.186 2003/08/25 09:01:49 sos Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/ata-all.c,v 1.187 2003/08/27 15:27:56 sos Exp $"); #include "opt_ata.h" #include @@ -437,8 +437,8 @@ ata_queue_request(request); - if (request->error) - iocmd->u.request.error = request->error; + if (request->result) + iocmd->u.request.error = request->result; else { if (iocmd->u.request.flags & ATA_CMD_READ) error = copyout(buf, ==== //depot/projects/uart/dev/ata/ata-lowlevel.c#3 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ata/ata-lowlevel.c,v 1.5 2003/08/25 13:06:13 sos Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/ata-lowlevel.c,v 1.6 2003/08/27 11:21:30 sos Exp $"); #include "opt_ata.h" #include @@ -520,22 +520,22 @@ ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_IDS | ATA_A_RESET); DELAY(10000); ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_IDS); - DELAY(100000); - ATA_IDX_INB(ch, ATA_ERROR); + DELAY(10000); /* wait for BUSY to go inactive */ - for (timeout = 0; timeout < 310000; timeout++) { + for (timeout = 0; timeout < 310; timeout++) { if (stat0 & ATA_S_BUSY) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); DELAY(10); + ATA_IDX_INB(ch, ATA_ERROR); - /* check for ATAPI signature while its still there */ - lsb = ATA_IDX_INB(ch, ATA_CYL_LSB); - msb = ATA_IDX_INB(ch, ATA_CYL_MSB); stat0 = ATA_IDX_INB(ch, ATA_STATUS); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0x00); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, 0x00); if (!(stat0 & ATA_S_BUSY)) { + /* check for ATAPI signature while its still there */ + lsb = ATA_IDX_INB(ch, ATA_CYL_LSB); + msb = ATA_IDX_INB(ch, ATA_CYL_MSB); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0x00); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, 0x00); if (bootverbose) ata_printf(ch, ATA_MASTER, "ATAPI %02x %02x\n", lsb, msb); if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) @@ -545,14 +545,15 @@ if (stat1 & ATA_S_BUSY) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); DELAY(10); + ATA_IDX_INB(ch, ATA_ERROR); - /* check for ATAPI signature while its still there */ - lsb = ATA_IDX_INB(ch, ATA_CYL_LSB); - msb = ATA_IDX_INB(ch, ATA_CYL_MSB); stat1 = ATA_IDX_INB(ch, ATA_STATUS); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0x00); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, 0x00); if (!(stat1 & ATA_S_BUSY)) { + /* check for ATAPI signature while its still there */ + lsb = ATA_IDX_INB(ch, ATA_CYL_LSB); + msb = ATA_IDX_INB(ch, ATA_CYL_MSB); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0x00); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, 0x00); if (bootverbose) ata_printf(ch, ATA_SLAVE, "ATAPI %02x %02x\n", lsb, msb); if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) @@ -568,7 +569,7 @@ if (mask == 0x03) /* wait for both master & slave */ if (!(stat0 & ATA_S_BUSY) && !(stat1 & ATA_S_BUSY)) break; - DELAY(100); + DELAY(100000); } DELAY(10); ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_4BIT); ==== //depot/projects/uart/dev/ata/atapi-cam.c#4 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cam.c,v 1.20 2003/08/24 17:48:05 obrien Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cam.c,v 1.21 2003/08/28 03:56:04 thomas Exp $"); #include #include @@ -465,9 +465,10 @@ if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN && (len & 1)) { /* ATA always transfers an even number of bytes */ if (!(buf = hcb->dxfer_alloc = malloc(++len, M_ATACAM, - M_NOWAIT | M_ZERO))) + M_NOWAIT | M_ZERO))) { printf("cannot allocate ATAPI/CAM buffer\n"); goto action_oom; + } } request->device = dev; request->driver = hcb; ==== //depot/projects/uart/dev/em/README#2 (text+ko) ==== @@ -1,8 +1,8 @@ -$FreeBSD: src/sys/dev/em/README,v 1.7 2003/06/05 17:51:37 pdeuskar Exp $ +$FreeBSD: src/sys/dev/em/README,v 1.8 2003/08/27 21:52:36 pdeuskar Exp $ FreeBSD* Driver for the Intel(R) PRO/1000 Family of Adapters ============================================================ -April 13, 2003 +July 24, 2003 Contents @@ -21,7 +21,7 @@ Overview ======== -This file describes the FreeBSD* driver, version 1.5.x, for the Intel(R) +This file describes the FreeBSD* driver, version 1.7.x, for the Intel(R) PRO/1000 Family of Adapters. This driver has been developed for use with FreeBSD, version 4.7. @@ -51,9 +51,10 @@ 82544 PRO/1000 XF Server Adapter A50484-xxx 82544 PRO/1000 T Desktop Adapter A62947-xxx - + 82540 PRO/1000 MT Desktop Adapter A78408-xxx - 82541 C91016-xxx + + 82541 PRO/1000 MT Desktop Adapter C91016-xxx 82545 PRO/1000 MT Server Adapter A92165-xxx @@ -67,6 +68,7 @@ 82546EB PRO/1000 MT Quad Port Server Adapter C11227-xxx + 82547 PRO/1000 CT Network Connection To verify your Intel adapter is supported, find the board ID number on the @@ -281,8 +283,46 @@ Known Limitations ================= -There are known performance issues with this driver when running UDP traffic -with Jumbo Frames. Intel recommends not using Jumbo Frames for UDP traffic. + There are known performance issues with this driver when running UDP traffic + with Jumbo Frames. Intel recommends not using Jumbo Frames for UDP traffic. + + + 82541/82547 can't link or is slow to link with some link partners + ----------------------------------------------------------------- + + There is a known compatibility issue with 82541/82547 and some switches + where link will not be established, or will be slow to establish. In + particular, these switches are known to be incompatible with 82541/82547: + + Planex FXG-08TE + I-O Data ETG-SH8 + + To workaround the issue, the driver can be compiled with an override of the + PHY's master/slave setting. Forcing master or forcing slave mode will + improve time-to-link. + + Edit ./em.x.x.x/src/if_em.h to remove the #define EM_MASTER_SLAVE + from within the comments. + + /* #define EM_MASTER_SLAVE 2 */ + #define EM_MASTER_SLAVE 2 + + Use one of the following options. + 0 = Hardware default + 1 = Master mode + 2 = Slave mode + 3 = Auto master/slave + + Recompile the module (refer to step 3 above) + a. To compile the module + + cd em-x.x.x + make clean + make + + b. To install the compiled module in system directory: + + make install Support ==== //depot/projects/uart/dev/em/if_em.c#4 (text+ko) ==== @@ -31,7 +31,7 @@ ***************************************************************************/ -/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.28 2003/08/01 17:33:59 jdp Exp $*/ +/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.29 2003/08/27 21:52:36 pdeuskar Exp $*/ #include @@ -51,7 +51,7 @@ * Driver version *********************************************************************/ -char em_driver_version[] = "1.6.6"; +char em_driver_version[] = "1.7.16"; /********************************************************************* @@ -89,6 +89,16 @@ { 0x8086, 0x101A, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x1026, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x1027, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x1028, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x1075, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x1076, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x1077, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x1078, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x1079, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x107A, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, 0x107B, PCI_ANY_ID, PCI_ANY_ID, 0}, /* required last entry */ { 0, 0, 0, 0, 0} }; @@ -163,6 +173,9 @@ static int em_is_valid_ether_addr(u_int8_t *); static int em_sysctl_stats(SYSCTL_HANDLER_ARGS); static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS); +static u_int32_t em_fill_descriptors (u_int64_t address, + u_int32_t length, + PDESC_ARRAY desc_array); static int em_sysctl_int_delay(SYSCTL_HANDLER_ARGS); static void em_add_int_delay_sysctl(struct adapter *, const char *, const char *, struct em_int_delay_info *, @@ -367,7 +380,13 @@ adapter->hw.fc = em_fc_full; adapter->hw.phy_init_script = 1; + adapter->hw.phy_reset_disable = FALSE; +#ifndef EM_MASTER_SLAVE + adapter->hw.master_slave = em_ms_hw_default; +#else + adapter->hw.master_slave = EM_MASTER_SLAVE; +#endif /* * Set the max frame size assuming standard ethernet * sized frames @@ -465,6 +484,15 @@ } else printf("em%d: Speed:N/A Duplex:N/A\n", adapter->unit); + /* Identify 82544 on PCIX */ + em_get_bus_info(&adapter->hw); + if(adapter->hw.bus_type == em_bus_type_pcix && + adapter->hw.mac_type == em_82544) { + adapter->pcix_82544 = TRUE; + } + else { + adapter->pcix_82544 = FALSE; + } INIT_DEBUGOUT("em_attach: end"); splx(s); return(0); @@ -525,6 +553,9 @@ adapter->rx_desc_base = NULL; } + /* Free the sysctl tree */ + sysctl_ctx_free(&adapter->sysctl_ctx); + /* Remove from the adapter list */ if (em_adapter_list == adapter) em_adapter_list = adapter->next; @@ -641,8 +672,11 @@ case SIOCSIFFLAGS: IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)"); if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_flags & IFF_RUNNING)) + if (!(ifp->if_flags & IFF_RUNNING)) { + bcopy(IF_LLADDR(ifp), adapter->hw.mac_addr, + ETHER_ADDR_LEN); em_init(adapter); + } em_disable_promisc(adapter); em_set_promisc(adapter); @@ -685,7 +719,7 @@ } break; default: - IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%d)\n", (int)command); + IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%x)\n", (int)command); error = EINVAL; } @@ -1052,9 +1086,15 @@ em_encap(struct adapter *adapter, struct mbuf *m_head) { u_int32_t txd_upper; - u_int32_t txd_lower; + u_int32_t txd_lower, txd_used = 0, txd_saved = 0; int i, j, error; - + u_int64_t address; + + /* For 82544 Workaround */ + DESC_ARRAY desc_array; + u_int32_t array_elements; + u_int32_t counter; + #if __FreeBSD_version < 500000 struct ifvlan *ifv = NULL; #else @@ -1118,23 +1158,66 @@ #endif i = adapter->next_avail_tx_desc; + if (adapter->pcix_82544) { + txd_saved = i; + txd_used = 0; + } for (j = 0; j < q.nsegs; j++) { - tx_buffer = &adapter->tx_buffer_area[i]; - current_tx_desc = &adapter->tx_desc_base[i]; + /* If adapter is 82544 and on PCIX bus */ + if(adapter->pcix_82544) { + array_elements = 0; + address = htole64(q.segs[j].ds_addr); + /* + * Check the Address and Length combination and + * split the data accordingly + */ + array_elements = em_fill_descriptors(address, + htole32(q.segs[j].ds_len), + &desc_array); + for (counter = 0; counter < array_elements; counter++) { + if (txd_used == adapter->num_tx_desc_avail) { + adapter->next_avail_tx_desc = txd_saved; + adapter->no_tx_desc_avail2++; + bus_dmamap_destroy(adapter->txtag, q.map); + return (ENOBUFS); + } + tx_buffer = &adapter->tx_buffer_area[i]; + current_tx_desc = &adapter->tx_desc_base[i]; + current_tx_desc->buffer_addr = htole64( + desc_array.descriptor[counter].address); + current_tx_desc->lower.data = htole32( + (adapter->txd_cmd | txd_lower | + (u_int16_t)desc_array.descriptor[counter].length)); + current_tx_desc->upper.data = htole32((txd_upper)); + if (++i == adapter->num_tx_desc) + i = 0; + + tx_buffer->m_head = NULL; + txd_used++; + } + } else { + tx_buffer = &adapter->tx_buffer_area[i]; + current_tx_desc = &adapter->tx_desc_base[i]; - current_tx_desc->buffer_addr = htole64(q.segs[j].ds_addr); - current_tx_desc->lower.data = htole32( - adapter->txd_cmd | txd_lower | q.segs[j].ds_len); - current_tx_desc->upper.data = htole32(txd_upper); + current_tx_desc->buffer_addr = htole64(q.segs[j].ds_addr); + current_tx_desc->lower.data = htole32( + adapter->txd_cmd | txd_lower | q.segs[j].ds_len); + current_tx_desc->upper.data = htole32(txd_upper); - if (++i == adapter->num_tx_desc) - i = 0; + if (++i == adapter->num_tx_desc) + i = 0; - tx_buffer->m_head = NULL; + tx_buffer->m_head = NULL; + } } - adapter->num_tx_desc_avail -= q.nsegs; - adapter->next_avail_tx_desc = i; + adapter->next_avail_tx_desc = i; + if (adapter->pcix_82544) { + adapter->num_tx_desc_avail -= txd_used; + } + else { + adapter->num_tx_desc_avail -= q.nsegs; + } #if __FreeBSD_version < 500000 if (ifv != NULL) { @@ -1474,7 +1557,7 @@ struct adapter * adapter = arg; ifp = &adapter->interface_data.ac_if; - INIT_DEBUGOUT("em_stop: begin\n"); + INIT_DEBUGOUT("em_stop: begin"); em_disable_intr(adapter); em_reset_hw(&adapter->hw); untimeout(em_local_timer, adapter, adapter->timer_handle); @@ -1522,6 +1605,12 @@ /* Identify the MAC */ if (em_set_mac_type(&adapter->hw)) printf("em%d: Unknown MAC Type\n", adapter->unit); + + if(adapter->hw.mac_type == em_82541 || + adapter->hw.mac_type == em_82541_rev_2 || + adapter->hw.mac_type == em_82547 || + adapter->hw.mac_type == em_82547_rev_2) + adapter->hw.phy_init_script = TRUE; return; } @@ -1629,6 +1718,7 @@ static int em_hardware_init(struct adapter * adapter) { + INIT_DEBUGOUT("em_hardware_init: begin"); /* Issue a global reset */ em_reset_hw(&adapter->hw); @@ -1984,6 +2074,7 @@ u_int32_t reg_tipg = 0; u_int64_t bus_addr; + INIT_DEBUGOUT("em_initialize_transmit_unit: begin"); /* Setup the Base and Length of the Tx Descriptor Ring */ bus_addr = adapter->txdma.dma_paddr; E1000_WRITE_REG(&adapter->hw, TDBAL, (u_int32_t)bus_addr); @@ -2399,6 +2490,7 @@ struct ifnet *ifp; u_int64_t bus_addr; + INIT_DEBUGOUT("em_initialize_receive_unit: begin"); ifp = &adapter->interface_data.ac_if; /* Make sure receives are disabled while setting up the descriptor ring */ @@ -2469,6 +2561,7 @@ /* Enable Receives */ E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl); + em_set_promisc(adapter); return; } @@ -2805,6 +2898,59 @@ return; } +/********************************************************************* +* 82544 Coexistence issue workaround. +* There are 2 issues. +* 1. Transmit Hang issue. +* To detect this issue, following equation can be used... +* SIZE[3:0] + ADDR[2:0] = SUM[3:0]. +* If SUM[3:0] is in between 1 to 4, we will have this issue. +* +* 2. DAC issue. +* To detect this issue, following equation can be used... +* SIZE[3:0] + ADDR[2:0] = SUM[3:0]. +* If SUM[3:0] is in between 9 to c, we will have this issue. +* +* +* WORKAROUND: +* Make sure we do not have ending address as 1,2,3,4(Hang) or 9,a,b,c (DAC) +* +*** *********************************************************************/ +static u_int32_t +em_fill_descriptors (u_int64_t address, + u_int32_t length, + PDESC_ARRAY desc_array) +{ + /* Since issue is sensitive to length and address.*/ + /* Let us first check the address...*/ + u_int32_t safe_terminator; + if (length <= 4) { + desc_array->descriptor[0].address = address; + desc_array->descriptor[0].length = length; + desc_array->elements = 1; + return desc_array->elements; + } + safe_terminator = (u_int32_t)((((u_int32_t)address & 0x7) + (length & 0xF)) & 0xF); + /* if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then return */ + if (safe_terminator == 0 || + (safe_terminator > 4 && + safe_terminator < 9) || + (safe_terminator > 0xC && + safe_terminator <= 0xF)) { + desc_array->descriptor[0].address = address; + desc_array->descriptor[0].length = length; + desc_array->elements = 1; + return desc_array->elements; + } + + desc_array->descriptor[0].address = address; + desc_array->descriptor[0].length = length - 4; + desc_array->descriptor[1].address = address + (length - 4); + desc_array->descriptor[1].length = 4; + desc_array->elements = 2; + return desc_array->elements; +} + /********************************************************************** * * Update the board statistics counters. @@ -2815,8 +2961,12 @@ { struct ifnet *ifp; + if(adapter->hw.media_type == em_media_type_copper || + (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { + adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, SYMERRS); + adapter->stats.sec += E1000_READ_REG(&adapter->hw, SEC); + } adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, CRCERRS); - adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, SYMERRS); adapter->stats.mpc += E1000_READ_REG(&adapter->hw, MPC); adapter->stats.scc += E1000_READ_REG(&adapter->hw, SCC); adapter->stats.ecol += E1000_READ_REG(&adapter->hw, ECOL); @@ -2825,7 +2975,6 @@ adapter->stats.latecol += E1000_READ_REG(&adapter->hw, LATECOL); adapter->stats.colc += E1000_READ_REG(&adapter->hw, COLC); adapter->stats.dc += E1000_READ_REG(&adapter->hw, DC); - adapter->stats.sec += E1000_READ_REG(&adapter->hw, SEC); adapter->stats.rlec += E1000_READ_REG(&adapter->hw, RLEC); adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, XONRXC); adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, XONTXC); ==== //depot/projects/uart/dev/em/if_em.h#6 (text+ko) ==== @@ -31,7 +31,7 @@ ***************************************************************************/ -/*$FreeBSD: src/sys/dev/em/if_em.h,v 1.20 2003/08/22 05:54:51 imp Exp $*/ +/*$FreeBSD: src/sys/dev/em/if_em.h,v 1.21 2003/08/27 21:52:37 pdeuskar Exp $*/ #ifndef _EM_H_DEFINED_ #define _EM_H_DEFINED_ @@ -81,7 +81,7 @@ /* Tunables */ /* - * TxDescriptors + * EM_MAX_TXD: Maximum number of Transmit Descriptors * Valid Range: 80-256 for 82542 and 82543-based adapters * 80-4096 for others * Default Value: 256 @@ -92,7 +92,7 @@ #define EM_MAX_TXD 256 /* - * RxDescriptors + * EM_MAX_RXD - Maximum number of receive Descriptors * Valid Range: 80-256 for 82542 and 82543-based adapters * 80-4096 for others * Default Value: 256 @@ -105,7 +105,7 @@ #define EM_MAX_RXD 256 /* - * TxIntDelay + * EM_TIDV - Transmit Interrupt Delay Value * Valid Range: 0-65535 (0=off) * Default Value: 64 * This value delays the generation of transmit interrupts in units of @@ -117,20 +117,20 @@ #define EM_TIDV 64 /* - * TxAbsIntDelay (Not valid for 82542/82543/82544) + * EM_TADV - Transmit Absolute Interrupt Delay Value (Not valid for 82542/82543/82544) * Valid Range: 0-65535 (0=off) * Default Value: 64 * This value, in units of 1.024 microseconds, limits the delay in which a - * transmit interrupt is generated. Useful only if TxIntDelay is non-zero, + * transmit interrupt is generated. Useful only if EM_TIDV is non-zero, * this value ensures that an interrupt is generated after the initial * packet is sent on the wire within the set amount of time. Proper tuning, - * along with TxIntDelay, may improve traffic throughput in specific + * along with EM_TIDV, may improve traffic throughput in specific * network conditions. */ #define EM_TADV 64 /* - * RxIntDelay + * EM_RDTR - Receive Interrupt Delay Timer (Packet Timer) * Valid Range: 0-65535 (0=off) * Default Value: 0 * This value delays the generation of receive interrupts in units of 1.024 @@ -141,24 +141,24 @@ * may be set too high, causing the driver to run out of available receive * descriptors. * - * CAUTION: When setting RxIntDelay to a value other than 0, adapters + * CAUTION: When setting EM_RDTR to a value other than 0, adapters * may hang (stop transmitting) under certain network conditions. * If this occurs a WATCHDOG message is logged in the system event log. * In addition, the controller is automatically reset, restoring the * network connection. To eliminate the potential for the hang - * ensure that RxIntDelay is set to 0. + * ensure that EM_RDTR is set to 0. */ #define EM_RDTR 0 /* - * RxAbsIntDelay (Not valid for 82542/82543/82544) + * Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544) * Valid Range: 0-65535 (0=off) * Default Value: 64 * This value, in units of 1.024 microseconds, limits the delay in which a - * receive interrupt is generated. Useful only if RxIntDelay is non-zero, + * receive interrupt is generated. Useful only if EM_RDTR is non-zero, * this value ensures that an interrupt is generated after the initial * packet is received within the set amount of time. Proper tuning, - * along with RxIntDelay, may improve traffic throughput in specific network + * along with EM_RDTR, may improve traffic throughput in specific network * conditions. */ #define EM_RADV 64 @@ -202,6 +202,17 @@ */ #define WAIT_FOR_AUTO_NEG_DEFAULT 0 +/* + * EM_MASTER_SLAVE is only defined to enable a workaround for a known compatibility issue + * with 82541/82547 devices and some switches. See the "Known Limitations" section of + * the README file for a complete description and a list of affected switches. + * + * 0 = Hardware default + * 1 = Master mode + * 2 = Slave mode + * 3 = Auto master/slave + */ +/* #define EM_MASTER_SLAVE 2 */ /* Tunables -- End */ @@ -301,6 +312,19 @@ int value; /* Current value in usecs */ }; +/* For 82544 PCIX Workaround */ +typedef struct _ADDRESS_LENGTH_PAIR +{ + u_int64_t address; + u_int32_t length; +} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR; + +typedef struct _DESCRIPTOR_PAIR +{ + ADDRESS_LENGTH_PAIR descriptor[4]; + u_int32_t elements; +} DESC_ARRAY, *PDESC_ARRAY; + /* Our adapter structure */ struct adapter { struct arpcom interface_data; @@ -389,6 +413,9 @@ u_int64_t tx_fifo_reset; u_int64_t tx_fifo_wrk; + /* For 82544 PCIX Workaround */ + boolean_t pcix_82544; + #ifdef DBG_STATS unsigned long no_pkts_avail; unsigned long clean_tx_interrupts; ==== //depot/projects/uart/dev/em/if_em_hw.c#3 (text+ko) ==== @@ -36,20 +36,21 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/em/if_em_hw.c,v 1.10 2003/08/24 17:46:04 obrien Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/em/if_em_hw.c,v 1.11 2003/08/27 21:52:37 pdeuskar Exp $"); #include static int32_t em_set_phy_type(struct em_hw *hw); static void em_phy_init_script(struct em_hw *hw); -static int32_t em_setup_fiber_link(struct em_hw *hw); static int32_t em_setup_copper_link(struct em_hw *hw); +static int32_t em_setup_fiber_serdes_link(struct em_hw *hw); +static int32_t em_adjust_serdes_amplitude(struct em_hw *hw); static int32_t em_phy_force_speed_duplex(struct em_hw *hw); static int32_t em_config_mac_to_phy(struct em_hw *hw); -static int32_t em_force_mac_fc(struct em_hw *hw); static void em_raise_mdi_clk(struct em_hw *hw, uint32_t *ctrl); static void em_lower_mdi_clk(struct em_hw *hw, uint32_t *ctrl); -static void em_shift_out_mdi_bits(struct em_hw *hw, uint32_t data, uint16_t count); +static void em_shift_out_mdi_bits(struct em_hw *hw, uint32_t data, + uint16_t count); static uint16_t em_shift_in_mdi_bits(struct em_hw *hw); static int32_t em_phy_reset_dsp(struct em_hw *hw); static int32_t em_write_eeprom_spi(struct em_hw *hw, uint16_t offset, @@ -60,13 +61,30 @@ static int32_t em_spi_eeprom_ready(struct em_hw *hw); static void em_raise_ee_clk(struct em_hw *hw, uint32_t *eecd); static void em_lower_ee_clk(struct em_hw *hw, uint32_t *eecd); -static void em_shift_out_ee_bits(struct em_hw *hw, uint16_t data, uint16_t count); +static void em_shift_out_ee_bits(struct em_hw *hw, uint16_t data, + uint16_t count); +static int32_t em_write_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr, + uint16_t phy_data); +static int32_t em_read_phy_reg_ex(struct em_hw *hw,uint32_t reg_addr, + uint16_t *phy_data); static uint16_t em_shift_in_ee_bits(struct em_hw *hw, uint16_t count); static int32_t em_acquire_eeprom(struct em_hw *hw); static void em_release_eeprom(struct em_hw *hw); static void em_standby_eeprom(struct em_hw *hw); static int32_t em_id_led_init(struct em_hw * hw); +static int32_t em_set_vco_speed(struct em_hw *hw); +/* IGP cable length table */ +static const +uint16_t em_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25, + 25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120}; /****************************************************************************** @@ -108,41 +126,64 @@ DEBUGFUNC("em_phy_init_script"); if(hw->phy_init_script) { - msec_delay(10); + msec_delay(20); - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000); em_write_phy_reg(hw,0x0000,0x0140); msec_delay(5); - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F95); - em_write_phy_reg(hw,0x0015,0x0001); + + if(hw->mac_type == em_82541 || hw->mac_type == em_82547) { + em_write_phy_reg(hw, 0x1F95, 0x0001); + + em_write_phy_reg(hw, 0x1F71, 0xBD21); + + em_write_phy_reg(hw, 0x1F79, 0x0018); + + em_write_phy_reg(hw, 0x1F30, 0x1600); + + em_write_phy_reg(hw, 0x1F31, 0x0014); + + em_write_phy_reg(hw, 0x1F32, 0x161C); + + em_write_phy_reg(hw, 0x1F94, 0x0003); + + em_write_phy_reg(hw, 0x1F96, 0x003F); + + em_write_phy_reg(hw, 0x2010, 0x0008); + } else { + em_write_phy_reg(hw, 0x1F73, 0x0099); + } - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F71); - em_write_phy_reg(hw,0x0011,0xBD21); + em_write_phy_reg(hw, 0x0000, 0x3300); - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F79); - em_write_phy_reg(hw,0x0019,0x0018); - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F30); - em_write_phy_reg(hw,0x0010,0x1600); + if(hw->mac_type == em_82547) { + uint16_t fused, fine, coarse; - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F31); - em_write_phy_reg(hw,0x0011,0x0014); + /* Move to analog registers page */ + em_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused); - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F32); - em_write_phy_reg(hw,0x0012,0x161C); + if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { + em_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused); - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F94); - em_write_phy_reg(hw,0x0014,0x0003); + fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK; + coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK; - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F96); - em_write_phy_reg(hw,0x0016,0x003F); + if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) { + coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10; + fine -= IGP01E1000_ANALOG_FUSE_FINE_1; + } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH) + fine -= IGP01E1000_ANALOG_FUSE_FINE_10; - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x2010); - em_write_phy_reg(hw,0x0010,0x0008); + fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) | + (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) | + (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK); - em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000); - em_write_phy_reg(hw,0x0000,0x3300); + em_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused); + em_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS, + IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL); + } + } } } @@ -191,32 +232,89 @@ case E1000_DEV_ID_82545EM_FIBER: hw->mac_type = em_82545; break; + case E1000_DEV_ID_82545GM_COPPER: + case E1000_DEV_ID_82545GM_FIBER: + case E1000_DEV_ID_82545GM_SERDES: + hw->mac_type = em_82545_rev_3; + break; case E1000_DEV_ID_82546EB_COPPER: case E1000_DEV_ID_82546EB_FIBER: case E1000_DEV_ID_82546EB_QUAD_COPPER: hw->mac_type = em_82546; break; + case E1000_DEV_ID_82546GB_COPPER: + case E1000_DEV_ID_82546GB_FIBER: + case E1000_DEV_ID_82546GB_SERDES: + hw->mac_type = em_82546_rev_3; + break; case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EP: + case E1000_DEV_ID_82541EI_MOBILE: hw->mac_type = em_82541; break; + case E1000_DEV_ID_82541ER: + case E1000_DEV_ID_82541GI: + case E1000_DEV_ID_82541GI_MOBILE: + hw->mac_type = em_82541_rev_2; + break; case E1000_DEV_ID_82547EI: hw->mac_type = em_82547; break; + case E1000_DEV_ID_82547GI: + hw->mac_type = em_82547_rev_2; + break; default: /* Should never have loaded on this device */ return -E1000_ERR_MAC_TYPE; } + return E1000_SUCCESS; +} - return E1000_SUCCESS; +/***************************************************************************** + * Set media type and TBI compatibility. + * + * hw - Struct containing variables accessed by shared code + * **************************************************************************/ +void +em_set_media_type(struct em_hw *hw) +{ + uint32_t status; + + DEBUGFUNC("em_set_media_type"); + + if(hw->mac_type != em_82543) { + /* tbi_compatibility is only valid on 82543 */ + hw->tbi_compatibility_en = FALSE; + } + + switch (hw->device_id) { + case E1000_DEV_ID_82545GM_SERDES: + case E1000_DEV_ID_82546GB_SERDES: + hw->media_type = em_media_type_internal_serdes; + break; + default: + if(hw->mac_type >= em_82543) { + status = E1000_READ_REG(hw, STATUS); + if(status & E1000_STATUS_TBIMODE) { + hw->media_type = em_media_type_fiber; + /* tbi_compatibility not valid on fiber */ + hw->tbi_compatibility_en = FALSE; + } else { + hw->media_type = em_media_type_copper; + } + } else { + /* This is an 82542 (fiber only) */ + hw->media_type = em_media_type_fiber; + } + } } + /****************************************************************************** * Reset the transmit and receive units; mask and clear all interrupts. * * hw - Struct containing variables accessed by shared code *****************************************************************************/ -void +int32_t em_reset_hw(struct em_hw *hw) { uint32_t ctrl; @@ -253,49 +351,75 @@ */ msec_delay(10); + ctrl = E1000_READ_REG(hw, CTRL); + + /* Must reset the PHY before resetting the MAC */ + if((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) { + E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST)); + msec_delay(5); + } + /* Issue a global reset to the MAC. This will reset the chip's * transmit, receive, DMA, and link units. It will not effect * the current PCI configuration. The global reset bit is self- * clearing, and should clear within a microsecond. */ DEBUGOUT("Issuing a global reset to MAC\n"); - ctrl = E1000_READ_REG(hw, CTRL); - /* Must reset the PHY before resetting the MAC */ >>> TRUNCATED FOR MAIL (1000 lines) <<<