1139749Simp/*- 28027Swollman * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 38027Swollman * 48027Swollman * This software may be used, modified, copied, distributed, and sold, in 58027Swollman * both source and binary form provided that the above copyright, these 68027Swollman * terms and the following disclaimer are retained. The name of the author 78027Swollman * and/or the contributor may not be used to endorse or promote products 88027Swollman * derived from this software without specific prior written permission. 98027Swollman * 108027Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND 118027Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 128027Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 138027Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE 148027Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 158027Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 168027Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION. 178027Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 188027Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 198027Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 208027Swollman * SUCH DAMAGE. 218027Swollman */ 228027Swollman 23119418Sobrien#include <sys/cdefs.h> 24119418Sobrien__FBSDID("$FreeBSD$"); 25119418Sobrien 268027Swollman/* 2714645Sjkh * 288027Swollman * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards. 2914645Sjkh * Contributed by M. Sekiguchi. <seki@sysrap.cs.fujitsu.co.jp> 308027Swollman * 318027Swollman * This version is intended to be a generic template for various 328027Swollman * MB86960A/MB86965A based Ethernet cards. It currently supports 3314645Sjkh * Fujitsu FMV-180 series for ISA and Allied-Telesis AT1700/RE2000 34150458Simp * series for ISA, as well as Fujitsu MBH10302 PC Card. 3514645Sjkh * There are some currently- 3614645Sjkh * unused hooks embedded, which are primarily intended to support 378027Swollman * other types of Ethernet cards, but the author is not sure whether 388027Swollman * they are useful. 398027Swollman * 4041823Skato * This version also includes some alignments to support RE1000, 4141823Skato * C-NET(98)P2 and so on. These cards are not for AT-compatibles, 4241823Skato * but for NEC PC-98 bus -- a proprietary bus architecture available 4341823Skato * only in Japan. Confusingly, it is different from the Microsoft's 4441823Skato * PC98 architecture. :-{ 4541823Skato * Further work for PC-98 version will be available as a part of 4641823Skato * FreeBSD(98) project. 4714645Sjkh * 488027Swollman * This software is a derivative work of if_ed.c version 1.56 by David 498027Swollman * Greenman available as a part of FreeBSD 2.0 RELEASE source distribution. 508027Swollman * 518027Swollman * The following lines are retained from the original if_ed.c: 528027Swollman * 538027Swollman * Copyright (C) 1993, David Greenman. This software may be used, modified, 548027Swollman * copied, distributed, and sold, in both source and binary form provided 558027Swollman * that the above copyright and these terms are retained. Under no 568027Swollman * circumstances is the author responsible for the proper functioning 578027Swollman * of this software, nor does the author assume any responsibility 588027Swollman * for damages incurred with its use. 598027Swollman */ 608027Swollman 6114645Sjkh/* 6214645Sjkh * TODO: 6314645Sjkh * o To support ISA PnP auto configuration for FMV-183/184. 6465832Snyan * o To support REX-9886/87(PC-98 only). 6514645Sjkh * o To reconsider mbuf usage. 6614645Sjkh * o To reconsider transmission buffer usage, including 6714645Sjkh * transmission buffer size (currently 4KB x 2) and pros-and- 6814645Sjkh * cons of multiple frame transmission. 6914645Sjkh * o To test IPX codes. 7065832Snyan * o To test new-bus frontend. 7114645Sjkh */ 7214645Sjkh 738027Swollman#include <sys/param.h> 74179493Sjhb#include <sys/kernel.h> 758027Swollman#include <sys/systm.h> 7665832Snyan#include <sys/socket.h> 7724204Sbde#include <sys/sockio.h> 788027Swollman#include <sys/mbuf.h> 7965832Snyan 8061011Speter#include <sys/bus.h> 8165832Snyan#include <machine/bus.h> 8265832Snyan#include <sys/rman.h> 838027Swollman 8450026Smdodd#include <net/ethernet.h> 858027Swollman#include <net/if.h> 868027Swollman#include <net/if_dl.h> 8741823Skato#include <net/if_mib.h> 8841823Skato#include <net/if_media.h> 89147256Sbrooks#include <net/if_types.h> 908027Swollman 9150026Smdodd#include <netinet/in.h> 9250026Smdodd#include <netinet/if_ether.h> 9350026Smdodd 948027Swollman#include <net/bpf.h> 958027Swollman 96142135Simp#include <dev/fe/mb86960.h> 9765832Snyan#include <dev/fe/if_fereg.h> 9865832Snyan#include <dev/fe/if_fevar.h> 998027Swollman 1008027Swollman/* 10114645Sjkh * Transmit just one packet per a "send" command to 86960. 1028027Swollman * This option is intended for performance test. An EXPERIMENTAL option. 1038027Swollman */ 1048027Swollman#ifndef FE_SINGLE_TRANSMISSION 1058027Swollman#define FE_SINGLE_TRANSMISSION 0 1068027Swollman#endif 1078027Swollman 1088027Swollman/* 10941823Skato * Maximum loops when interrupt. 11041823Skato * This option prevents an infinite loop due to hardware failure. 111150458Simp * (Some laptops make an infinite loop after PC Card is ejected.) 11241823Skato */ 11341823Skato#ifndef FE_MAX_LOOP 11441823Skato#define FE_MAX_LOOP 0x800 11541823Skato#endif 11641823Skato 11741823Skato/* 1188027Swollman * Device configuration flags. 1198027Swollman */ 1208027Swollman 1218027Swollman/* DLCR6 settings. */ 1228027Swollman#define FE_FLAGS_DLCR6_VALUE 0x007F 1238027Swollman 1248027Swollman/* Force DLCR6 override. */ 1258027Swollman#define FE_FLAGS_OVERRIDE_DLCR6 0x0080 1268027Swollman 1278027Swollman 12865832Snyandevclass_t fe_devclass; 1298027Swollman 1308027Swollman/* 1318027Swollman * Special filter values. 1328027Swollman */ 1338027Swollmanstatic struct fe_filter const fe_filter_nothing = { FE_FILTER_NOTHING }; 1348027Swollmanstatic struct fe_filter const fe_filter_all = { FE_FILTER_ALL }; 1358027Swollman 1368027Swollman/* Standard driver entry points. These can be static. */ 13765832Snyanstatic void fe_init (void *); 138179493Sjhbstatic void fe_init_locked (struct fe_softc *); 13965896Sjhbstatic driver_intr_t fe_intr; 14065832Snyanstatic int fe_ioctl (struct ifnet *, u_long, caddr_t); 14165832Snyanstatic void fe_start (struct ifnet *); 142179493Sjhbstatic void fe_start_locked (struct ifnet *); 143179493Sjhbstatic void fe_watchdog (void *); 14465832Snyanstatic int fe_medchange (struct ifnet *); 14565832Snyanstatic void fe_medstat (struct ifnet *, struct ifmediareq *); 1468027Swollman 1478027Swollman/* Local functions. Order of declaration is confused. FIXME. */ 1488027Swollmanstatic int fe_get_packet ( struct fe_softc *, u_short ); 1498027Swollmanstatic void fe_tint ( struct fe_softc *, u_char ); 1508027Swollmanstatic void fe_rint ( struct fe_softc *, u_char ); 1518027Swollmanstatic void fe_xmit ( struct fe_softc * ); 1528027Swollmanstatic void fe_write_mbufs ( struct fe_softc *, struct mbuf * ); 1538027Swollmanstatic void fe_setmode ( struct fe_softc * ); 1548027Swollmanstatic void fe_loadmar ( struct fe_softc * ); 15541823Skato 15641823Skato#ifdef DIAGNOSTIC 15741823Skatostatic void fe_emptybuffer ( struct fe_softc * ); 1588027Swollman#endif 1598027Swollman 1608027Swollman/* 1618027Swollman * Fe driver specific constants which relate to 86960/86965. 1628027Swollman */ 1638027Swollman 1648027Swollman/* Interrupt masks */ 1658027Swollman#define FE_TMASK ( FE_D2_COLL16 | FE_D2_TXDONE ) 1668027Swollman#define FE_RMASK ( FE_D3_OVRFLO | FE_D3_CRCERR \ 1678027Swollman | FE_D3_ALGERR | FE_D3_SRTPKT | FE_D3_PKTRDY ) 1688027Swollman 16914645Sjkh/* Maximum number of iterations for a receive interrupt. */ 1708027Swollman#define FE_MAX_RECV_COUNT ( ( 65536 - 2048 * 2 ) / 64 ) 17114645Sjkh /* 17214645Sjkh * Maximum size of SRAM is 65536, 1738027Swollman * minimum size of transmission buffer in fe is 2x2KB, 1748027Swollman * and minimum amount of received packet including headers 1758027Swollman * added by the chip is 64 bytes. 1768027Swollman * Hence FE_MAX_RECV_COUNT is the upper limit for number 17714645Sjkh * of packets in the receive buffer. 17814645Sjkh */ 1798027Swollman 1808027Swollman/* 18141823Skato * Miscellaneous definitions not directly related to hardware. 18241823Skato */ 18341823Skato 18441823Skato/* The following line must be delete when "net/if_media.h" support it. */ 18541823Skato#ifndef IFM_10_FL 18641823Skato#define IFM_10_FL /* 13 */ IFM_10_5 18741823Skato#endif 18841823Skato 18941823Skato#if 0 19041823Skato/* Mapping between media bitmap (in fe_softc.mbitmap) and ifm_media. */ 19141823Skatostatic int const bit2media [] = { 19241823Skato IFM_HDX | IFM_ETHER | IFM_AUTO, 19341823Skato IFM_HDX | IFM_ETHER | IFM_MANUAL, 19441823Skato IFM_HDX | IFM_ETHER | IFM_10_T, 19541823Skato IFM_HDX | IFM_ETHER | IFM_10_2, 19641823Skato IFM_HDX | IFM_ETHER | IFM_10_5, 19741823Skato IFM_HDX | IFM_ETHER | IFM_10_FL, 19841823Skato IFM_FDX | IFM_ETHER | IFM_10_T, 19941823Skato /* More can be come here... */ 20041823Skato 0 20141823Skato}; 20241823Skato#else 20341823Skato/* Mapping between media bitmap (in fe_softc.mbitmap) and ifm_media. */ 20441823Skatostatic int const bit2media [] = { 20541823Skato IFM_ETHER | IFM_AUTO, 20641823Skato IFM_ETHER | IFM_MANUAL, 20741823Skato IFM_ETHER | IFM_10_T, 20841823Skato IFM_ETHER | IFM_10_2, 20941823Skato IFM_ETHER | IFM_10_5, 21041823Skato IFM_ETHER | IFM_10_FL, 21141823Skato IFM_ETHER | IFM_10_T, 21241823Skato /* More can be come here... */ 21341823Skato 0 21441823Skato}; 21541823Skato#endif 21641823Skato 21741823Skato/* 2188027Swollman * Check for specific bits in specific registers have specific values. 21941823Skato * A common utility function called from various sub-probe routines. 2208027Swollman */ 22165832Snyanint 22265832Snyanfe_simple_probe (struct fe_softc const * sc, 22365832Snyan struct fe_simple_probe_struct const * sp) 2248027Swollman{ 22565832Snyan struct fe_simple_probe_struct const *p; 226142135Simp int8_t bits; 2278027Swollman 22865832Snyan for (p = sp; p->mask != 0; p++) { 229142135Simp bits = fe_inb(sc, p->port); 230142135Simp printf("port %d, mask %x, bits %x read %x\n", p->port, 231142135Simp p->mask, p->bits, bits); 232142135Simp if ((bits & p->mask) != p->bits) 23365832Snyan return 0; 2348027Swollman } 23565832Snyan return 1; 2368027Swollman} 2378027Swollman 23841823Skato/* Test if a given 6 byte value is a valid Ethernet station (MAC) 23941823Skato address. "Vendor" is an expected vendor code (first three bytes,) 24041823Skato or a zero when nothing expected. */ 24165832Snyanint 242139972Simpfe_valid_Ether_p (u_char const * addr, unsigned vendor) 24341823Skato{ 24441823Skato#ifdef FE_DEBUG 24541823Skato printf("fe?: validating %6D against %06x\n", addr, ":", vendor); 24641823Skato#endif 24741823Skato 24841823Skato /* All zero is not allowed as a vendor code. */ 24941823Skato if (addr[0] == 0 && addr[1] == 0 && addr[2] == 0) return 0; 25041823Skato 25141823Skato switch (vendor) { 25241823Skato case 0x000000: 25341823Skato /* Legal Ethernet address (stored in ROM) must have 25441823Skato its Group and Local bits cleared. */ 25541823Skato if ((addr[0] & 0x03) != 0) return 0; 25641823Skato break; 25741823Skato case 0x020000: 25841823Skato /* Same as above, but a local address is allowed in 25941823Skato this context. */ 260136239Sbms if (ETHER_IS_MULTICAST(addr)) return 0; 26141823Skato break; 26241823Skato default: 26341823Skato /* Make sure the vendor part matches if one is given. */ 26441823Skato if ( addr[0] != ((vendor >> 16) & 0xFF) 26541823Skato || addr[1] != ((vendor >> 8) & 0xFF) 26641823Skato || addr[2] != ((vendor ) & 0xFF)) return 0; 26741823Skato break; 26841823Skato } 26941823Skato 27041823Skato /* Host part must not be all-zeros nor all-ones. */ 27141823Skato if (addr[3] == 0xFF && addr[4] == 0xFF && addr[5] == 0xFF) return 0; 27241823Skato if (addr[3] == 0x00 && addr[4] == 0x00 && addr[5] == 0x00) return 0; 27341823Skato 27441823Skato /* Given addr looks like an Ethernet address. */ 27541823Skato return 1; 27641823Skato} 27741823Skato 27841823Skato/* Fill our softc struct with default value. */ 27965832Snyanvoid 28041823Skatofe_softc_defaults (struct fe_softc *sc) 28141823Skato{ 28241823Skato /* Prepare for typical register prototypes. We assume a 28341823Skato "typical" board has <32KB> of <fast> SRAM connected with a 28441823Skato <byte-wide> data lines. */ 28541823Skato sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; 28641823Skato sc->proto_dlcr5 = 0; 28741823Skato sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB 28841823Skato | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns; 28941823Skato sc->proto_dlcr7 = FE_D7_BYTSWP_LH; 29041823Skato sc->proto_bmpr13 = 0; 29141823Skato 29241823Skato /* Assume the probe process (to be done later) is stable. */ 29341823Skato sc->stability = 0; 29441823Skato 29541823Skato /* A typical board needs no hooks. */ 29641823Skato sc->init = NULL; 29741823Skato sc->stop = NULL; 29841823Skato 29941823Skato /* Assume the board has no software-controllable media selection. */ 30041823Skato sc->mbitmap = MB_HM; 30141823Skato sc->defmedia = MB_HM; 30241823Skato sc->msel = NULL; 30341823Skato} 30441823Skato 30541823Skato/* Common error reporting routine used in probe routines for 30641823Skato "soft configured IRQ"-type boards. */ 30765832Snyanvoid 30841823Skatofe_irq_failure (char const *name, int unit, int irq, char const *list) 30941823Skato{ 31041823Skato printf("fe%d: %s board is detected, but %s IRQ was given\n", 31141823Skato unit, name, (irq == NO_IRQ ? "no" : "invalid")); 31241823Skato if (list != NULL) { 31341823Skato printf("fe%d: specify an IRQ from %s in kernel config\n", 31441823Skato unit, list); 31541823Skato } 31641823Skato} 31741823Skato 3188027Swollman/* 31965832Snyan * Hardware (vendor) specific hooks. 3208027Swollman */ 3218027Swollman 32241823Skato/* 32341823Skato * Generic media selection scheme for MB86965 based boards. 32441823Skato */ 32565832Snyanvoid 32641823Skatofe_msel_965 (struct fe_softc *sc) 3278027Swollman{ 32841823Skato u_char b13; 32941823Skato 33041823Skato /* Find the appropriate bits for BMPR13 tranceiver control. */ 33141823Skato switch (IFM_SUBTYPE(sc->media.ifm_media)) { 33241823Skato case IFM_AUTO: b13 = FE_B13_PORT_AUTO | FE_B13_TPTYPE_UTP; break; 33341823Skato case IFM_10_T: b13 = FE_B13_PORT_TP | FE_B13_TPTYPE_UTP; break; 33441823Skato default: b13 = FE_B13_PORT_AUI; break; 33541823Skato } 33641823Skato 33741823Skato /* Write it into the register. It takes effect immediately. */ 33865832Snyan fe_outb(sc, FE_BMPR13, sc->proto_bmpr13 | b13); 33941823Skato} 34041823Skato 34165832Snyan 34241823Skato/* 34341823Skato * Fujitsu MB86965 JLI mode support routines. 34441823Skato */ 34541823Skato 34641823Skato/* 34741823Skato * Routines to read all bytes from the config EEPROM through MB86965A. 34841823Skato * It is a MicroWire (3-wire) serial EEPROM with 6-bit address. 34941823Skato * (93C06 or 93C46.) 35041823Skato */ 35141823Skatostatic void 35265832Snyanfe_strobe_eeprom_jli (struct fe_softc *sc, u_short bmpr16) 35341823Skato{ 3548027Swollman /* 35541823Skato * We must guarantee 1us (or more) interval to access slow 35614645Sjkh * EEPROMs. The following redundant code provides enough 35714645Sjkh * delay with ISA timing. (Even if the bus clock is "tuned.") 35814645Sjkh * Some modification will be needed on faster busses. 3598027Swollman */ 36065832Snyan fe_outb(sc, bmpr16, FE_B16_SELECT); 36165832Snyan fe_outb(sc, bmpr16, FE_B16_SELECT | FE_B16_CLOCK); 36265832Snyan fe_outb(sc, bmpr16, FE_B16_SELECT | FE_B16_CLOCK); 36365832Snyan fe_outb(sc, bmpr16, FE_B16_SELECT); 3648027Swollman} 3658027Swollman 36665832Snyanvoid 36765832Snyanfe_read_eeprom_jli (struct fe_softc * sc, u_char * data) 3688027Swollman{ 3698027Swollman u_char n, val, bit; 37041823Skato u_char save16, save17; 3718027Swollman 37241823Skato /* Save the current value of the EEPROM interface registers. */ 37365832Snyan save16 = fe_inb(sc, FE_BMPR16); 37465832Snyan save17 = fe_inb(sc, FE_BMPR17); 37541823Skato 37614645Sjkh /* Read bytes from EEPROM; two bytes per an iteration. */ 37765832Snyan for (n = 0; n < JLI_EEPROM_SIZE / 2; n++) { 3788027Swollman 3798027Swollman /* Reset the EEPROM interface. */ 38065832Snyan fe_outb(sc, FE_BMPR16, 0x00); 38165832Snyan fe_outb(sc, FE_BMPR17, 0x00); 3828027Swollman 3838027Swollman /* Start EEPROM access. */ 38465832Snyan fe_outb(sc, FE_BMPR16, FE_B16_SELECT); 38565832Snyan fe_outb(sc, FE_BMPR17, FE_B17_DATA); 38665832Snyan fe_strobe_eeprom_jli(sc, FE_BMPR16); 3878027Swollman 38841823Skato /* Pass the iteration count as well as a READ command. */ 3898027Swollman val = 0x80 | n; 39065832Snyan for (bit = 0x80; bit != 0x00; bit >>= 1) { 39165832Snyan fe_outb(sc, FE_BMPR17, (val & bit) ? FE_B17_DATA : 0); 39265832Snyan fe_strobe_eeprom_jli(sc, FE_BMPR16); 3938027Swollman } 39465832Snyan fe_outb(sc, FE_BMPR17, 0x00); 3958027Swollman 3968027Swollman /* Read a byte. */ 3978027Swollman val = 0; 39865832Snyan for (bit = 0x80; bit != 0x00; bit >>= 1) { 39965832Snyan fe_strobe_eeprom_jli(sc, FE_BMPR16); 40065832Snyan if (fe_inb(sc, FE_BMPR17) & FE_B17_DATA) 4018027Swollman val |= bit; 4028027Swollman } 4038027Swollman *data++ = val; 4048027Swollman 4058027Swollman /* Read one more byte. */ 4068027Swollman val = 0; 40765832Snyan for (bit = 0x80; bit != 0x00; bit >>= 1) { 40865832Snyan fe_strobe_eeprom_jli(sc, FE_BMPR16); 40965832Snyan if (fe_inb(sc, FE_BMPR17) & FE_B17_DATA) 4108027Swollman val |= bit; 4118027Swollman } 4128027Swollman *data++ = val; 4138027Swollman } 4148027Swollman 41541823Skato#if 0 41614645Sjkh /* Reset the EEPROM interface, again. */ 41765832Snyan fe_outb(sc, FE_BMPR16, 0x00); 41865832Snyan fe_outb(sc, FE_BMPR17, 0x00); 41941823Skato#else 42041823Skato /* Make sure to restore the original value of EEPROM interface 42141823Skato registers, since we are not yet sure we have MB86965A on 42241823Skato the address. */ 42365832Snyan fe_outb(sc, FE_BMPR17, save17); 42465832Snyan fe_outb(sc, FE_BMPR16, save16); 42541823Skato#endif 4268027Swollman 42741823Skato#if 1 4288027Swollman /* Report what we got. */ 42941823Skato if (bootverbose) { 43041823Skato int i; 43141823Skato data -= JLI_EEPROM_SIZE; 43241823Skato for (i = 0; i < JLI_EEPROM_SIZE; i += 16) { 433147256Sbrooks if_printf(sc->ifp, 434147256Sbrooks "EEPROM(JLI):%3x: %16D\n", i, data + i, " "); 43541823Skato } 43641823Skato } 4378027Swollman#endif 4388027Swollman} 4398027Swollman 44065832Snyanvoid 44141823Skatofe_init_jli (struct fe_softc * sc) 44241823Skato{ 44341823Skato /* "Reset" by writing into a magic location. */ 44441823Skato DELAY(200); 44565832Snyan fe_outb(sc, 0x1E, fe_inb(sc, 0x1E)); 44641823Skato DELAY(300); 44741823Skato} 44841823Skato 44965832Snyan 4508027Swollman/* 45141823Skato * SSi 78Q8377A support routines. 4528027Swollman */ 4538027Swollman 4548027Swollman/* 45541823Skato * Routines to read all bytes from the config EEPROM through 78Q8377A. 45641823Skato * It is a MicroWire (3-wire) serial EEPROM with 8-bit address. (I.e., 45741823Skato * 93C56 or 93C66.) 45841823Skato * 45941823Skato * As I don't have SSi manuals, (hmm, an old song again!) I'm not exactly 46041823Skato * sure the following code is correct... It is just stolen from the 46141823Skato * C-NET(98)P2 support routine in FreeBSD(98). 4628027Swollman */ 46341823Skato 46465832Snyanvoid 46541823Skatofe_read_eeprom_ssi (struct fe_softc *sc, u_char *data) 4668027Swollman{ 46741823Skato u_char val, bit; 46841823Skato int n; 46941823Skato u_char save6, save7, save12; 4708027Swollman 47141823Skato /* Save the current value for the DLCR registers we are about 47241823Skato to destroy. */ 47365832Snyan save6 = fe_inb(sc, FE_DLCR6); 47465832Snyan save7 = fe_inb(sc, FE_DLCR7); 4758027Swollman 47641823Skato /* Put the 78Q8377A into a state that we can access the EEPROM. */ 47765832Snyan fe_outb(sc, FE_DLCR6, 47865832Snyan FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_DLC_DISABLE); 47965832Snyan fe_outb(sc, FE_DLCR7, 48065832Snyan FE_D7_BYTSWP_LH | FE_D7_RBS_BMPR | FE_D7_RDYPNS | FE_D7_POWER_UP); 4818027Swollman 48241823Skato /* Save the current value for the BMPR12 register, too. */ 48365832Snyan save12 = fe_inb(sc, FE_DLCR12); 4848027Swollman 48541823Skato /* Read bytes from EEPROM; two bytes per an iteration. */ 48665832Snyan for (n = 0; n < SSI_EEPROM_SIZE / 2; n++) { 4878027Swollman 48841823Skato /* Start EEPROM access */ 48965832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP); 49065832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL); 49141823Skato 49241823Skato /* Send the following four bits to the EEPROM in the 49365832Snyan specified order: a dummy bit, a start bit, and 49465832Snyan command bits (10) for READ. */ 49565832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL ); 49665832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK ); /* 0 */ 49765832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_DAT); 49865832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK | SSI_DAT); /* 1 */ 49965832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_DAT); 50065832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK | SSI_DAT); /* 1 */ 50165832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL ); 50265832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK ); /* 0 */ 50341823Skato 50441823Skato /* Pass the iteration count to the chip. */ 50565832Snyan for (bit = 0x80; bit != 0x00; bit >>= 1) { 50665832Snyan val = ( n & bit ) ? SSI_DAT : 0; 50765832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | val); 50865832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK | val); 50941823Skato } 51041823Skato 51141823Skato /* Read a byte. */ 51241823Skato val = 0; 51365832Snyan for (bit = 0x80; bit != 0x00; bit >>= 1) { 51465832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL); 51565832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK); 51665832Snyan if (fe_inb(sc, FE_DLCR12) & SSI_DIN) 51765832Snyan val |= bit; 51841823Skato } 51941823Skato *data++ = val; 52041823Skato 52141823Skato /* Read one more byte. */ 52241823Skato val = 0; 52365832Snyan for (bit = 0x80; bit != 0x00; bit >>= 1) { 52465832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL); 52565832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK); 52665832Snyan if (fe_inb(sc, FE_DLCR12) & SSI_DIN) 52765832Snyan val |= bit; 52841823Skato } 52941823Skato *data++ = val; 53041823Skato 53165832Snyan fe_outb(sc, FE_DLCR12, SSI_EEP); 5328027Swollman } 5338027Swollman 53441823Skato /* Reset the EEPROM interface. (For now.) */ 53565832Snyan fe_outb(sc, FE_DLCR12, 0x00); 53641823Skato 53741823Skato /* Restore the saved register values, for the case that we 53841823Skato didn't have 78Q8377A at the given address. */ 53965832Snyan fe_outb(sc, FE_DLCR12, save12); 54065832Snyan fe_outb(sc, FE_DLCR7, save7); 54165832Snyan fe_outb(sc, FE_DLCR6, save6); 54241823Skato 54341823Skato#if 1 54441823Skato /* Report what we got. */ 54541823Skato if (bootverbose) { 54641823Skato int i; 54741823Skato data -= SSI_EEPROM_SIZE; 54841823Skato for (i = 0; i < SSI_EEPROM_SIZE; i += 16) { 549147256Sbrooks if_printf(sc->ifp, 550147256Sbrooks "EEPROM(SSI):%3x: %16D\n", i, data + i, " "); 55141823Skato } 55214645Sjkh } 55341823Skato#endif 55441823Skato} 55514645Sjkh 55641823Skato/* 55741823Skato * TDK/LANX boards support routines. 55841823Skato */ 55941823Skato 56041823Skato/* It is assumed that the CLK line is low and SDA is high (float) upon entry. */ 56141823Skato#define LNX_PH(D,K,N) \ 56241823Skato ((LNX_SDA_##D | LNX_CLK_##K) << N) 56341823Skato#define LNX_CYCLE(D1,D2,D3,D4,K1,K2,K3,K4) \ 56441823Skato (LNX_PH(D1,K1,0)|LNX_PH(D2,K2,8)|LNX_PH(D3,K3,16)|LNX_PH(D4,K4,24)) 56541823Skato 56641823Skato#define LNX_CYCLE_START LNX_CYCLE(HI,LO,LO,HI, HI,HI,LO,LO) 56741823Skato#define LNX_CYCLE_STOP LNX_CYCLE(LO,LO,HI,HI, LO,HI,HI,LO) 56841823Skato#define LNX_CYCLE_HI LNX_CYCLE(HI,HI,HI,HI, LO,HI,LO,LO) 56941823Skato#define LNX_CYCLE_LO LNX_CYCLE(LO,LO,LO,HI, LO,HI,LO,LO) 57041823Skato#define LNX_CYCLE_INIT LNX_CYCLE(LO,HI,HI,HI, LO,LO,LO,LO) 57141823Skato 57241823Skatostatic void 57365832Snyanfe_eeprom_cycle_lnx (struct fe_softc *sc, u_short reg20, u_long cycle) 57441823Skato{ 57565832Snyan fe_outb(sc, reg20, (cycle ) & 0xFF); 57641823Skato DELAY(15); 57765832Snyan fe_outb(sc, reg20, (cycle >> 8) & 0xFF); 57841823Skato DELAY(15); 57965832Snyan fe_outb(sc, reg20, (cycle >> 16) & 0xFF); 58041823Skato DELAY(15); 58165832Snyan fe_outb(sc, reg20, (cycle >> 24) & 0xFF); 58241823Skato DELAY(15); 58341823Skato} 58441823Skato 58541823Skatostatic u_char 58665832Snyanfe_eeprom_receive_lnx (struct fe_softc *sc, u_short reg20) 58741823Skato{ 58841823Skato u_char dat; 58941823Skato 59065832Snyan fe_outb(sc, reg20, LNX_CLK_HI | LNX_SDA_FL); 59141823Skato DELAY(15); 59265832Snyan dat = fe_inb(sc, reg20); 59365832Snyan fe_outb(sc, reg20, LNX_CLK_LO | LNX_SDA_FL); 59441823Skato DELAY(15); 59541823Skato return (dat & LNX_SDA_IN); 59641823Skato} 59741823Skato 59865832Snyanvoid 59941823Skatofe_read_eeprom_lnx (struct fe_softc *sc, u_char *data) 60041823Skato{ 60141823Skato int i; 60241823Skato u_char n, bit, val; 60341823Skato u_char save20; 60465832Snyan u_short reg20 = 0x14; 60541823Skato 60665832Snyan save20 = fe_inb(sc, reg20); 60741823Skato 60841823Skato /* NOTE: DELAY() timing constants are approximately three 60941823Skato times longer (slower) than the required minimum. This is 61041823Skato to guarantee a reliable operation under some tough 61141823Skato conditions... Fortunately, this routine is only called 61241823Skato during the boot phase, so the speed is less important than 61341823Skato stability. */ 61441823Skato 61541823Skato#if 1 61641823Skato /* Reset the X24C01's internal state machine and put it into 61741823Skato the IDLE state. We usually don't need this, but *if* 61841823Skato someone (e.g., probe routine of other driver) write some 61941823Skato garbage into the register at 0x14, synchronization will be 62041823Skato lost, and the normal EEPROM access protocol won't work. 62141823Skato Moreover, as there are no easy way to reset, we need a 62241823Skato _manoeuvre_ here. (It even lacks a reset pin, so pushing 62341823Skato the RESET button on the PC doesn't help!) */ 62465832Snyan fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_INIT); 62565832Snyan for (i = 0; i < 10; i++) 62665832Snyan fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_START); 62765832Snyan fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_STOP); 62841823Skato DELAY(10000); 62919781Swollman#endif 6308027Swollman 63141823Skato /* Issue a start condition. */ 63265832Snyan fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_START); 63314645Sjkh 63441823Skato /* Send seven bits of the starting address (zero, in this 63541823Skato case) and a command bit for READ. */ 63641823Skato val = 0x01; 63741823Skato for (bit = 0x80; bit != 0x00; bit >>= 1) { 63841823Skato if (val & bit) { 63965832Snyan fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_HI); 64041823Skato } else { 64165832Snyan fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_LO); 64214645Sjkh } 64341823Skato } 64441823Skato 64541823Skato /* Receive an ACK bit. */ 64665832Snyan if (fe_eeprom_receive_lnx(sc, reg20)) { 64741823Skato /* ACK was not received. EEPROM is not present (i.e., 64841823Skato this board was not a TDK/LANX) or not working 64941823Skato properly. */ 65041823Skato if (bootverbose) { 651147256Sbrooks if_printf(sc->ifp, 652147256Sbrooks "no ACK received from EEPROM(LNX)\n"); 65314645Sjkh } 65441823Skato /* Clear the given buffer to indicate we could not get 65541823Skato any info. and return. */ 65641823Skato bzero(data, LNX_EEPROM_SIZE); 65741823Skato goto RET; 65841823Skato } 65941823Skato 66041823Skato /* Read bytes from EEPROM. */ 66141823Skato for (n = 0; n < LNX_EEPROM_SIZE; n++) { 66241823Skato 66341823Skato /* Read a byte and store it into the buffer. */ 66441823Skato val = 0x00; 66541823Skato for (bit = 0x80; bit != 0x00; bit >>= 1) { 66665832Snyan if (fe_eeprom_receive_lnx(sc, reg20)) 66765832Snyan val |= bit; 66814645Sjkh } 66941823Skato *data++ = val; 67041823Skato 67141823Skato /* Acknowledge if we have to read more. */ 67241823Skato if (n < LNX_EEPROM_SIZE - 1) { 67365832Snyan fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_LO); 67414645Sjkh } 6758027Swollman } 6768027Swollman 67741823Skato /* Issue a STOP condition, de-activating the clock line. 67841823Skato It will be safer to keep the clock line low than to leave 67941823Skato it high. */ 68065832Snyan fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_STOP); 68141823Skato 68241823Skato RET: 68365832Snyan fe_outb(sc, reg20, save20); 68441823Skato 68541823Skato#if 1 68641823Skato /* Report what we got. */ 68741823Skato if (bootverbose) { 68850239Skato data -= LNX_EEPROM_SIZE; 68950239Skato for (i = 0; i < LNX_EEPROM_SIZE; i += 16) { 690147256Sbrooks if_printf(sc->ifp, 691147256Sbrooks "EEPROM(LNX):%3x: %16D\n", i, data + i, " "); 69241823Skato } 69314645Sjkh } 69441823Skato#endif 69541823Skato} 6968027Swollman 69765832Snyanvoid 69865832Snyanfe_init_lnx (struct fe_softc * sc) 69941823Skato{ 70041823Skato /* Reset the 86960. Do we need this? FIXME. */ 70165832Snyan fe_outb(sc, 0x12, 0x06); 70241823Skato DELAY(100); 70365832Snyan fe_outb(sc, 0x12, 0x07); 70441823Skato DELAY(100); 7058027Swollman 70641823Skato /* Setup IRQ control register on the ASIC. */ 70765832Snyan fe_outb(sc, 0x14, sc->priv_info); 70841823Skato} 70941823Skato 71065832Snyan 71141823Skato/* 71241823Skato * Ungermann-Bass boards support routine. 71341823Skato */ 71465832Snyanvoid 71565832Snyanfe_init_ubn (struct fe_softc * sc) 71641823Skato{ 71742188Skato /* Do we need this? FIXME. */ 71865832Snyan fe_outb(sc, FE_DLCR7, 71942188Skato sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP); 72065832Snyan fe_outb(sc, 0x18, 0x00); 72165832Snyan DELAY(200); 72241823Skato 72341823Skato /* Setup IRQ control register on the ASIC. */ 72465832Snyan fe_outb(sc, 0x14, sc->priv_info); 72541823Skato} 72641823Skato 72741823Skato 7288027Swollman/* 72965832Snyan * Install interface into kernel networking data structures 7308027Swollman */ 73165832Snyanint 73265832Snyanfe_attach (device_t dev) 7338027Swollman{ 73465832Snyan struct fe_softc *sc = device_get_softc(dev); 735147256Sbrooks struct ifnet *ifp; 73665832Snyan int flags = device_get_flags(dev); 73765832Snyan int b, error; 738147256Sbrooks 739147256Sbrooks ifp = sc->ifp = if_alloc(IFT_ETHER); 740147256Sbrooks if (ifp == NULL) { 741147256Sbrooks device_printf(dev, "can not ifalloc\n"); 742179493Sjhb fe_release_resource(dev); 743147256Sbrooks return (ENOSPC); 744147256Sbrooks } 7458027Swollman 746179493Sjhb mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK, 747179493Sjhb MTX_DEF); 748179493Sjhb callout_init_mtx(&sc->timer, &sc->lock, 0); 7498027Swollman 7508027Swollman /* 7518027Swollman * Initialize ifnet structure 7528027Swollman */ 753147256Sbrooks ifp->if_softc = sc; 754147256Sbrooks if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev)); 755147256Sbrooks ifp->if_start = fe_start; 756147256Sbrooks ifp->if_ioctl = fe_ioctl; 757147256Sbrooks ifp->if_init = fe_init; 758147256Sbrooks ifp->if_linkmib = &sc->mibdata; 759147256Sbrooks ifp->if_linkmiblen = sizeof (sc->mibdata); 7608027Swollman 76141823Skato#if 0 /* I'm not sure... */ 76241823Skato sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS; 76341823Skato#endif 76441823Skato 7658027Swollman /* 76641823Skato * Set fixed interface flags. 7678027Swollman */ 768179493Sjhb ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 769207554Ssobomax IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 7708027Swollman 7718027Swollman#if FE_SINGLE_TRANSMISSION 7728027Swollman /* Override txb config to allocate minimum. */ 7738027Swollman sc->proto_dlcr6 &= ~FE_D6_TXBSIZ 7748027Swollman sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB; 7758027Swollman#endif 7768027Swollman 7778027Swollman /* Modify hardware config if it is requested. */ 77865832Snyan if (flags & FE_FLAGS_OVERRIDE_DLCR6) 77965832Snyan sc->proto_dlcr6 = flags & FE_FLAGS_DLCR6_VALUE; 7808027Swollman 7818027Swollman /* Find TX buffer size, based on the hardware dependent proto. */ 78265832Snyan switch (sc->proto_dlcr6 & FE_D6_TXBSIZ) { 7838027Swollman case FE_D6_TXBSIZ_2x2KB: sc->txb_size = 2048; break; 7848027Swollman case FE_D6_TXBSIZ_2x4KB: sc->txb_size = 4096; break; 7858027Swollman case FE_D6_TXBSIZ_2x8KB: sc->txb_size = 8192; break; 7868027Swollman default: 7878027Swollman /* Oops, we can't work with single buffer configuration. */ 78841823Skato if (bootverbose) { 789147256Sbrooks if_printf(sc->ifp, 790147256Sbrooks "strange TXBSIZ config; fixing\n"); 79141823Skato } 7928027Swollman sc->proto_dlcr6 &= ~FE_D6_TXBSIZ; 7938027Swollman sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB; 7948027Swollman sc->txb_size = 2048; 7958027Swollman break; 7968027Swollman } 7978027Swollman 79841823Skato /* Initialize the if_media interface. */ 79965832Snyan ifmedia_init(&sc->media, 0, fe_medchange, fe_medstat); 80041823Skato for (b = 0; bit2media[b] != 0; b++) { 80141823Skato if (sc->mbitmap & (1 << b)) { 80241823Skato ifmedia_add(&sc->media, bit2media[b], 0, NULL); 80341823Skato } 80441823Skato } 80541823Skato for (b = 0; bit2media[b] != 0; b++) { 80641823Skato if (sc->defmedia & (1 << b)) { 80741823Skato ifmedia_set(&sc->media, bit2media[b]); 80841823Skato break; 80941823Skato } 81041823Skato } 81141823Skato#if 0 /* Turned off; this is called later, when the interface UPs. */ 81241823Skato fe_medchange(sc); 81341823Skato#endif 81441823Skato 81515363Snate /* Attach and stop the interface. */ 816179493Sjhb FE_LOCK(sc); 817179493Sjhb fe_stop(sc); 818179493Sjhb FE_UNLOCK(sc); 819147256Sbrooks ether_ifattach(sc->ifp, sc->enaddr); 820179493Sjhb 821179493Sjhb error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, 822179493Sjhb NULL, fe_intr, sc, &sc->irq_handle); 823179493Sjhb if (error) { 824179493Sjhb ether_ifdetach(ifp); 825179493Sjhb mtx_destroy(&sc->lock); 826179493Sjhb if_free(ifp); 827179493Sjhb fe_release_resource(dev); 828179493Sjhb return ENXIO; 829179493Sjhb } 830179493Sjhb 83114645Sjkh /* Print additional info when attached. */ 832126966Smdodd device_printf(dev, "type %s%s\n", sc->typestr, 83365832Snyan (sc->proto_dlcr4 & FE_D4_DSC) ? ", full duplex" : ""); 83441823Skato if (bootverbose) { 8358027Swollman int buf, txb, bbw, sbw, ram; 8368027Swollman 8378027Swollman buf = txb = bbw = sbw = ram = -1; 8388027Swollman switch ( sc->proto_dlcr6 & FE_D6_BUFSIZ ) { 8398027Swollman case FE_D6_BUFSIZ_8KB: buf = 8; break; 8408027Swollman case FE_D6_BUFSIZ_16KB: buf = 16; break; 8418027Swollman case FE_D6_BUFSIZ_32KB: buf = 32; break; 8428027Swollman case FE_D6_BUFSIZ_64KB: buf = 64; break; 8438027Swollman } 8448027Swollman switch ( sc->proto_dlcr6 & FE_D6_TXBSIZ ) { 8458027Swollman case FE_D6_TXBSIZ_2x2KB: txb = 2; break; 8468027Swollman case FE_D6_TXBSIZ_2x4KB: txb = 4; break; 8478027Swollman case FE_D6_TXBSIZ_2x8KB: txb = 8; break; 8488027Swollman } 8498027Swollman switch ( sc->proto_dlcr6 & FE_D6_BBW ) { 8508027Swollman case FE_D6_BBW_BYTE: bbw = 8; break; 8518027Swollman case FE_D6_BBW_WORD: bbw = 16; break; 8528027Swollman } 8538027Swollman switch ( sc->proto_dlcr6 & FE_D6_SBW ) { 8548027Swollman case FE_D6_SBW_BYTE: sbw = 8; break; 8558027Swollman case FE_D6_SBW_WORD: sbw = 16; break; 8568027Swollman } 8578027Swollman switch ( sc->proto_dlcr6 & FE_D6_SRAM ) { 8588027Swollman case FE_D6_SRAM_100ns: ram = 100; break; 8598027Swollman case FE_D6_SRAM_150ns: ram = 150; break; 8608027Swollman } 86165832Snyan device_printf(dev, "SRAM %dKB %dbit %dns, TXB %dKBx2, %dbit I/O\n", 86265832Snyan buf, bbw, ram, txb, sbw); 8638027Swollman } 86465832Snyan if (sc->stability & UNSTABLE_IRQ) 86565832Snyan device_printf(dev, "warning: IRQ number may be incorrect\n"); 86665832Snyan if (sc->stability & UNSTABLE_MAC) 86765832Snyan device_printf(dev, "warning: above MAC address may be incorrect\n"); 86865832Snyan if (sc->stability & UNSTABLE_TYPE) 86965832Snyan device_printf(dev, "warning: hardware type was not validated\n"); 87065832Snyan 87165832Snyan return 0; 87265832Snyan} 87365832Snyan 87465832Snyanint 87565832Snyanfe_alloc_port(device_t dev, int size) 87665832Snyan{ 87765832Snyan struct fe_softc *sc = device_get_softc(dev); 87865832Snyan struct resource *res; 87965832Snyan int rid; 88065832Snyan 88165832Snyan rid = 0; 88265832Snyan res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 88365832Snyan 0ul, ~0ul, size, RF_ACTIVE); 88465832Snyan if (res) { 88565832Snyan sc->port_used = size; 88665832Snyan sc->port_res = res; 88765832Snyan return (0); 88841823Skato } 88965832Snyan 89065832Snyan return (ENOENT); 89165832Snyan} 89265832Snyan 89365832Snyanint 89465832Snyanfe_alloc_irq(device_t dev, int flags) 89565832Snyan{ 89665832Snyan struct fe_softc *sc = device_get_softc(dev); 89765832Snyan struct resource *res; 89865832Snyan int rid; 89965832Snyan 90065832Snyan rid = 0; 901127135Snjl res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | flags); 90265832Snyan if (res) { 90365832Snyan sc->irq_res = res; 90465832Snyan return (0); 90541823Skato } 9068027Swollman 90765832Snyan return (ENOENT); 9088027Swollman} 9098027Swollman 91065832Snyanvoid 91165832Snyanfe_release_resource(device_t dev) 91265832Snyan{ 91365832Snyan struct fe_softc *sc = device_get_softc(dev); 91465832Snyan 91565832Snyan if (sc->port_res) { 91665832Snyan bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port_res); 91765832Snyan sc->port_res = NULL; 91865832Snyan } 91965832Snyan if (sc->irq_res) { 92065832Snyan bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); 92165832Snyan sc->irq_res = NULL; 92265832Snyan } 92365832Snyan} 92465832Snyan 9258027Swollman/* 92641823Skato * Reset interface, after some (hardware) trouble is deteced. 9278027Swollman */ 92812724Sphkstatic void 92941823Skatofe_reset (struct fe_softc *sc) 9308027Swollman{ 93141823Skato /* Record how many packets are lost by this accident. */ 932147256Sbrooks sc->ifp->if_oerrors += sc->txb_sched + sc->txb_count; 93341823Skato sc->mibdata.dot3StatsInternalMacTransmitErrors++; 93441823Skato 93541823Skato /* Put the interface into known initial state. */ 93641823Skato fe_stop(sc); 937147256Sbrooks if (sc->ifp->if_flags & IFF_UP) 938179493Sjhb fe_init_locked(sc); 9398027Swollman} 9408027Swollman 9418027Swollman/* 9428027Swollman * Stop everything on the interface. 9438027Swollman * 9448027Swollman * All buffered packets, both transmitting and receiving, 9458027Swollman * if any, will be lost by stopping the interface. 9468027Swollman */ 94765832Snyanvoid 94841823Skatofe_stop (struct fe_softc *sc) 9498027Swollman{ 9508027Swollman 951179493Sjhb FE_ASSERT_LOCKED(sc); 9528027Swollman 9538027Swollman /* Disable interrupts. */ 95465832Snyan fe_outb(sc, FE_DLCR2, 0x00); 95565832Snyan fe_outb(sc, FE_DLCR3, 0x00); 9568027Swollman 9578027Swollman /* Stop interface hardware. */ 95865832Snyan DELAY(200); 95965832Snyan fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE); 96065832Snyan DELAY(200); 9618027Swollman 9628027Swollman /* Clear all interrupt status. */ 96365832Snyan fe_outb(sc, FE_DLCR0, 0xFF); 96465832Snyan fe_outb(sc, FE_DLCR1, 0xFF); 9658027Swollman 9668027Swollman /* Put the chip in stand-by mode. */ 96765832Snyan DELAY(200); 96865832Snyan fe_outb(sc, FE_DLCR7, sc->proto_dlcr7 | FE_D7_POWER_DOWN); 96965832Snyan DELAY(200); 9708027Swollman 9718027Swollman /* Reset transmitter variables and interface flags. */ 972148887Srwatson sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); 973179959Sjhb sc->tx_timeout = 0; 974179493Sjhb callout_stop(&sc->timer); 9758027Swollman sc->txb_free = sc->txb_size; 9768027Swollman sc->txb_count = 0; 9778027Swollman sc->txb_sched = 0; 9788027Swollman 9798027Swollman /* MAR loading can be delayed. */ 9808027Swollman sc->filter_change = 0; 9818027Swollman 98241823Skato /* Call a device-specific hook. */ 98365832Snyan if (sc->stop) 98465832Snyan sc->stop(sc); 9858027Swollman} 9868027Swollman 9878027Swollman/* 9888027Swollman * Device timeout/watchdog routine. Entered if the device neglects to 9898027Swollman * generate an interrupt after a transmit has been started on it. 9908027Swollman */ 99112724Sphkstatic void 992179493Sjhbfe_watchdog (void *arg) 9938027Swollman{ 994179493Sjhb struct fe_softc *sc = arg; 9958027Swollman 996179493Sjhb FE_ASSERT_LOCKED(sc); 997179493Sjhb 998179959Sjhb if (sc->tx_timeout && --sc->tx_timeout == 0) { 999179959Sjhb /* A "debug" message. */ 1000179959Sjhb if_printf(sc->ifp, "transmission timeout (%d+%d)%s\n", 1001179959Sjhb sc->txb_sched, sc->txb_count, 1002179959Sjhb (sc->ifp->if_flags & IFF_UP) ? "" : " when down"); 1003179959Sjhb if (sc->ifp->if_opackets == 0 && sc->ifp->if_ipackets == 0) 1004179959Sjhb if_printf(sc->ifp, "wrong IRQ setting in config?\n"); 1005179959Sjhb fe_reset(sc); 1006179959Sjhb } 1007179959Sjhb callout_reset(&sc->timer, hz, fe_watchdog, sc); 10088027Swollman} 10098027Swollman 10108027Swollman/* 10118027Swollman * Initialize device. 10128027Swollman */ 101312724Sphkstatic void 101441823Skatofe_init (void * xsc) 10158027Swollman{ 101641823Skato struct fe_softc *sc = xsc; 10178027Swollman 1018179493Sjhb FE_LOCK(sc); 1019179493Sjhb fe_init_locked(sc); 1020179493Sjhb FE_UNLOCK(sc); 1021179493Sjhb} 1022179493Sjhb 1023179493Sjhbstatic void 1024179493Sjhbfe_init_locked (struct fe_softc *sc) 1025179493Sjhb{ 1026179493Sjhb 10278027Swollman /* Start initializing 86960. */ 10288027Swollman 102941823Skato /* Call a hook before we start initializing the chip. */ 103065832Snyan if (sc->init) 103165832Snyan sc->init(sc); 10328027Swollman 10338027Swollman /* 10348027Swollman * Make sure to disable the chip, also. 10358027Swollman * This may also help re-programming the chip after 10368027Swollman * hot insertion of PCMCIAs. 10378027Swollman */ 103865832Snyan DELAY(200); 103965832Snyan fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE); 104065832Snyan DELAY(200); 10418027Swollman 10428027Swollman /* Power up the chip and select register bank for DLCRs. */ 104365832Snyan DELAY(200); 104465832Snyan fe_outb(sc, FE_DLCR7, 104565832Snyan sc->proto_dlcr7 | FE_D7_RBS_DLCR | FE_D7_POWER_UP); 104665832Snyan DELAY(200); 10478027Swollman 10488027Swollman /* Feed the station address. */ 1049152315Sru fe_outblk(sc, FE_DLCR8, IF_LLADDR(sc->ifp), ETHER_ADDR_LEN); 10508027Swollman 10518027Swollman /* Clear multicast address filter to receive nothing. */ 105265832Snyan fe_outb(sc, FE_DLCR7, 105365832Snyan sc->proto_dlcr7 | FE_D7_RBS_MAR | FE_D7_POWER_UP); 105465832Snyan fe_outblk(sc, FE_MAR8, fe_filter_nothing.data, FE_FILTER_LEN); 10558027Swollman 10568027Swollman /* Select the BMPR bank for runtime register access. */ 105765832Snyan fe_outb(sc, FE_DLCR7, 105865832Snyan sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP); 10598027Swollman 10608027Swollman /* Initialize registers. */ 106165832Snyan fe_outb(sc, FE_DLCR0, 0xFF); /* Clear all bits. */ 106265832Snyan fe_outb(sc, FE_DLCR1, 0xFF); /* ditto. */ 106365832Snyan fe_outb(sc, FE_DLCR2, 0x00); 106465832Snyan fe_outb(sc, FE_DLCR3, 0x00); 106565832Snyan fe_outb(sc, FE_DLCR4, sc->proto_dlcr4); 106665832Snyan fe_outb(sc, FE_DLCR5, sc->proto_dlcr5); 106765832Snyan fe_outb(sc, FE_BMPR10, 0x00); 106865832Snyan fe_outb(sc, FE_BMPR11, FE_B11_CTRL_SKIP | FE_B11_MODE1); 106965832Snyan fe_outb(sc, FE_BMPR12, 0x00); 107065832Snyan fe_outb(sc, FE_BMPR13, sc->proto_bmpr13); 107165832Snyan fe_outb(sc, FE_BMPR14, 0x00); 107265832Snyan fe_outb(sc, FE_BMPR15, 0x00); 10738027Swollman 10748027Swollman /* Enable interrupts. */ 107565832Snyan fe_outb(sc, FE_DLCR2, FE_TMASK); 107665832Snyan fe_outb(sc, FE_DLCR3, FE_RMASK); 10778027Swollman 107841823Skato /* Select requested media, just before enabling DLC. */ 107965832Snyan if (sc->msel) 108065832Snyan sc->msel(sc); 108141823Skato 10828027Swollman /* Enable transmitter and receiver. */ 108365832Snyan DELAY(200); 108465832Snyan fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_ENABLE); 108565832Snyan DELAY(200); 10868027Swollman 108741823Skato#ifdef DIAGNOSTIC 10888027Swollman /* 10898027Swollman * Make sure to empty the receive buffer. 10908027Swollman * 10918027Swollman * This may be redundant, but *if* the receive buffer were full 109219781Swollman * at this point, then the driver would hang. I have experienced 109314645Sjkh * some strange hang-up just after UP. I hope the following 10948027Swollman * code solve the problem. 10958027Swollman * 10968027Swollman * I have changed the order of hardware initialization. 10978027Swollman * I think the receive buffer cannot have any packets at this 10988027Swollman * point in this version. The following code *must* be 10998027Swollman * redundant now. FIXME. 110019781Swollman * 1101150458Simp * I've heard a rumore that on some PC Card implementation of 110219781Swollman * 8696x, the receive buffer can have some data at this point. 110319781Swollman * The following message helps discovering the fact. FIXME. 11048027Swollman */ 110565832Snyan if (!(fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP)) { 1106147256Sbrooks if_printf(sc->ifp, 1107147256Sbrooks "receive buffer has some data after reset\n"); 110865832Snyan fe_emptybuffer(sc); 11098027Swollman } 11108027Swollman 111119781Swollman /* Do we need this here? Actually, no. I must be paranoia. */ 111265832Snyan fe_outb(sc, FE_DLCR0, 0xFF); /* Clear all bits. */ 111365832Snyan fe_outb(sc, FE_DLCR1, 0xFF); /* ditto. */ 111441823Skato#endif 11158027Swollman 11168027Swollman /* Set 'running' flag, because we are now running. */ 1117148887Srwatson sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; 1118179959Sjhb callout_reset(&sc->timer, hz, fe_watchdog, sc); 11198027Swollman 11208027Swollman /* 112114645Sjkh * At this point, the interface is running properly, 11228027Swollman * except that it receives *no* packets. we then call 11238027Swollman * fe_setmode() to tell the chip what packets to be 11248027Swollman * received, based on the if_flags and multicast group 11258027Swollman * list. It completes the initialization process. 11268027Swollman */ 112765832Snyan fe_setmode(sc); 11288027Swollman 112941823Skato#if 0 11308027Swollman /* ...and attempt to start output queued packets. */ 113141823Skato /* TURNED OFF, because the semi-auto media prober wants to UP 113241823Skato the interface keeping it idle. The upper layer will soon 113341823Skato start the interface anyway, and there are no significant 113441823Skato delay. */ 1135179493Sjhb fe_start_locked(sc->ifp); 11368027Swollman#endif 11378027Swollman} 11388027Swollman 11398027Swollman/* 11408027Swollman * This routine actually starts the transmission on the interface 11418027Swollman */ 114214645Sjkhstatic void 114365832Snyanfe_xmit (struct fe_softc *sc) 11448027Swollman{ 11458027Swollman /* 11468027Swollman * Set a timer just in case we never hear from the board again. 11478027Swollman * We use longer timeout for multiple packet transmission. 11488027Swollman * I'm not sure this timer value is appropriate. FIXME. 11498027Swollman */ 1150179959Sjhb sc->tx_timeout = 1 + sc->txb_count; 11518027Swollman 11528027Swollman /* Update txb variables. */ 11538027Swollman sc->txb_sched = sc->txb_count; 11548027Swollman sc->txb_count = 0; 11558027Swollman sc->txb_free = sc->txb_size; 115619781Swollman sc->tx_excolls = 0; 11578027Swollman 11588027Swollman /* Start transmitter, passing packets in TX buffer. */ 115965832Snyan fe_outb(sc, FE_BMPR10, sc->txb_sched | FE_B10_START); 11608027Swollman} 11618027Swollman 11628027Swollman/* 11638027Swollman * Start output on interface. 1164179493Sjhb * We make one assumption here: 1165179493Sjhb * 1) that the IFF_DRV_OACTIVE flag is checked before this code is called 11668027Swollman * (i.e. that the output part of the interface is idle) 11678027Swollman */ 1168104094Sphkstatic void 116965832Snyanfe_start (struct ifnet *ifp) 11708027Swollman{ 117114645Sjkh struct fe_softc *sc = ifp->if_softc; 1172179493Sjhb 1173179493Sjhb FE_LOCK(sc); 1174179493Sjhb fe_start_locked(ifp); 1175179493Sjhb FE_UNLOCK(sc); 1176179493Sjhb} 1177179493Sjhb 1178179493Sjhbstatic void 1179179493Sjhbfe_start_locked (struct ifnet *ifp) 1180179493Sjhb{ 1181179493Sjhb struct fe_softc *sc = ifp->if_softc; 11828027Swollman struct mbuf *m; 11838027Swollman 118441823Skato#ifdef DIAGNOSTIC 11858027Swollman /* Just a sanity check. */ 118665832Snyan if ((sc->txb_count == 0) != (sc->txb_free == sc->txb_size)) { 11878027Swollman /* 11888027Swollman * Txb_count and txb_free co-works to manage the 11898027Swollman * transmission buffer. Txb_count keeps track of the 11908027Swollman * used potion of the buffer, while txb_free does unused 11918027Swollman * potion. So, as long as the driver runs properly, 11928027Swollman * txb_count is zero if and only if txb_free is same 11938027Swollman * as txb_size (which represents whole buffer.) 11948027Swollman */ 1195104254Sbrooks if_printf(ifp, "inconsistent txb variables (%d, %d)\n", 1196104254Sbrooks sc->txb_count, sc->txb_free); 11978027Swollman /* 11988027Swollman * So, what should I do, then? 11998027Swollman * 12008027Swollman * We now know txb_count and txb_free contradicts. We 12018027Swollman * cannot, however, tell which is wrong. More 12028027Swollman * over, we cannot peek 86960 transmission buffer or 12038027Swollman * reset the transmission buffer. (In fact, we can 12048027Swollman * reset the entire interface. I don't want to do it.) 12058027Swollman * 120614645Sjkh * If txb_count is incorrect, leaving it as-is will cause 120714645Sjkh * sending of garbage after next interrupt. We have to 12088027Swollman * avoid it. Hence, we reset the txb_count here. If 1209160964Syar * txb_free was incorrect, resetting txb_count just loses 12108027Swollman * some packets. We can live with it. 12118027Swollman */ 12128027Swollman sc->txb_count = 0; 12138027Swollman } 12148027Swollman#endif 12158027Swollman 12168027Swollman /* 12178027Swollman * First, see if there are buffered packets and an idle 12188027Swollman * transmitter - should never happen at this point. 12198027Swollman */ 122065832Snyan if ((sc->txb_count > 0) && (sc->txb_sched == 0)) { 1221104254Sbrooks if_printf(ifp, "transmitter idle with %d buffered packets\n", 1222104254Sbrooks sc->txb_count); 122365832Snyan fe_xmit(sc); 12248027Swollman } 12258027Swollman 12268027Swollman /* 12278027Swollman * Stop accepting more transmission packets temporarily, when 12288027Swollman * a filter change request is delayed. Updating the MARs on 122914645Sjkh * 86960 flushes the transmission buffer, so it is delayed 12308027Swollman * until all buffered transmission packets have been sent 12318027Swollman * out. 12328027Swollman */ 123365832Snyan if (sc->filter_change) { 12348027Swollman /* 123514645Sjkh * Filter change request is delayed only when the DLC is 12368027Swollman * working. DLC soon raise an interrupt after finishing 12378027Swollman * the work. 12388027Swollman */ 12398027Swollman goto indicate_active; 12408027Swollman } 12418027Swollman 12428027Swollman for (;;) { 12438027Swollman 12448027Swollman /* 12458027Swollman * See if there is room to put another packet in the buffer. 12468027Swollman * We *could* do better job by peeking the send queue to 12478027Swollman * know the length of the next packet. Current version just 12488027Swollman * tests against the worst case (i.e., longest packet). FIXME. 12498876Srgrimes * 12508027Swollman * When adding the packet-peek feature, don't forget adding a 12518027Swollman * test on txb_count against QUEUEING_MAX. 12528027Swollman * There is a little chance the packet count exceeds 12538027Swollman * the limit. Assume transmission buffer is 8KB (2x8KB 12548027Swollman * configuration) and an application sends a bunch of small 12558027Swollman * (i.e., minimum packet sized) packets rapidly. An 8KB 12568027Swollman * buffer can hold 130 blocks of 62 bytes long... 12578027Swollman */ 125865832Snyan if (sc->txb_free 125965832Snyan < ETHER_MAX_LEN - ETHER_CRC_LEN + FE_DATA_LEN_LEN) { 12608027Swollman /* No room. */ 12618027Swollman goto indicate_active; 12628027Swollman } 12638027Swollman 12648027Swollman#if FE_SINGLE_TRANSMISSION 126565832Snyan if (sc->txb_count > 0) { 12668027Swollman /* Just one packet per a transmission buffer. */ 12678027Swollman goto indicate_active; 12688027Swollman } 12698027Swollman#endif 12708027Swollman 12718027Swollman /* 12728027Swollman * Get the next mbuf chain for a packet to send. 12738027Swollman */ 1274147256Sbrooks IF_DEQUEUE(&sc->ifp->if_snd, m); 127565832Snyan if (m == NULL) { 12768027Swollman /* No more packets to send. */ 12778027Swollman goto indicate_inactive; 12788027Swollman } 12798027Swollman 12808027Swollman /* 12818027Swollman * Copy the mbuf chain into the transmission buffer. 12828027Swollman * txb_* variables are updated as necessary. 12838027Swollman */ 128465832Snyan fe_write_mbufs(sc, m); 12858027Swollman 12868027Swollman /* Start transmitter if it's idle. */ 128765832Snyan if ((sc->txb_count > 0) && (sc->txb_sched == 0)) 128865832Snyan fe_xmit(sc); 12898027Swollman 12908027Swollman /* 129114645Sjkh * Tap off here if there is a bpf listener, 129214645Sjkh * and the device is *not* in promiscuous mode. 129314645Sjkh * (86960 receives self-generated packets if 129414645Sjkh * and only if it is in "receive everything" 129514645Sjkh * mode.) 12968027Swollman */ 1297147256Sbrooks if (!(sc->ifp->if_flags & IFF_PROMISC)) 1298147256Sbrooks BPF_MTAP(sc->ifp, m); 12998027Swollman 130065832Snyan m_freem(m); 13018027Swollman } 13028027Swollman 13038027Swollman indicate_inactive: 13048027Swollman /* 13058027Swollman * We are using the !OACTIVE flag to indicate to 13068027Swollman * the outside world that we can accept an 13078027Swollman * additional packet rather than that the 13088027Swollman * transmitter is _actually_ active. Indeed, the 13098027Swollman * transmitter may be active, but if we haven't 13108027Swollman * filled all the buffers with data then we still 13118027Swollman * want to accept more. 13128027Swollman */ 1313148887Srwatson sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 13148027Swollman return; 13158027Swollman 13168027Swollman indicate_active: 13178027Swollman /* 13188027Swollman * The transmitter is active, and there are no room for 13198027Swollman * more outgoing packets in the transmission buffer. 13208027Swollman */ 1321148887Srwatson sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE; 13228027Swollman return; 13238027Swollman} 13248027Swollman 13258027Swollman/* 13268027Swollman * Drop (skip) a packet from receive buffer in 86960 memory. 13278027Swollman */ 132814645Sjkhstatic void 132965832Snyanfe_droppacket (struct fe_softc * sc, int len) 13308027Swollman{ 133119781Swollman int i; 133219781Swollman 133319781Swollman /* 133419781Swollman * 86960 manual says that we have to read 8 bytes from the buffer 133519781Swollman * before skip the packets and that there must be more than 8 bytes 133619781Swollman * remaining in the buffer when issue a skip command. 133719781Swollman * Remember, we have already read 4 bytes before come here. 133819781Swollman */ 133965832Snyan if (len > 12) { 134019781Swollman /* Read 4 more bytes, and skip the rest of the packet. */ 134146410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) 134241823Skato { 134365832Snyan (void) fe_inb(sc, FE_BMPR8); 134465832Snyan (void) fe_inb(sc, FE_BMPR8); 134565832Snyan (void) fe_inb(sc, FE_BMPR8); 134665832Snyan (void) fe_inb(sc, FE_BMPR8); 134741823Skato } 134841823Skato else 134941823Skato { 135065832Snyan (void) fe_inw(sc, FE_BMPR8); 135165832Snyan (void) fe_inw(sc, FE_BMPR8); 135241823Skato } 135365832Snyan fe_outb(sc, FE_BMPR14, FE_B14_SKIP); 135419781Swollman } else { 135519781Swollman /* We should not come here unless receiving RUNTs. */ 135646410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) 135741823Skato { 135865832Snyan for (i = 0; i < len; i++) 135965832Snyan (void) fe_inb(sc, FE_BMPR8); 136019781Swollman } 136141823Skato else 136241823Skato { 136365832Snyan for (i = 0; i < len; i += 2) 136465832Snyan (void) fe_inw(sc, FE_BMPR8); 136541823Skato } 136619781Swollman } 13678027Swollman} 13688027Swollman 136941823Skato#ifdef DIAGNOSTIC 13708027Swollman/* 137119781Swollman * Empty receiving buffer. 137219781Swollman */ 137319781Swollmanstatic void 137465832Snyanfe_emptybuffer (struct fe_softc * sc) 137519781Swollman{ 137619781Swollman int i; 137719781Swollman u_char saved_dlcr5; 137819781Swollman 137941823Skato#ifdef FE_DEBUG 1380147256Sbrooks if_printf(sc->ifp, "emptying receive buffer\n"); 138119781Swollman#endif 138241823Skato 138319781Swollman /* 138419781Swollman * Stop receiving packets, temporarily. 138519781Swollman */ 138665832Snyan saved_dlcr5 = fe_inb(sc, FE_DLCR5); 138765832Snyan fe_outb(sc, FE_DLCR5, sc->proto_dlcr5); 138821694Swollman DELAY(1300); 138919781Swollman 139019781Swollman /* 139141823Skato * When we come here, the receive buffer management may 139219781Swollman * have been broken. So, we cannot use skip operation. 139321694Swollman * Just discard everything in the buffer. 139419781Swollman */ 139546410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) 139641823Skato { 139765832Snyan for (i = 0; i < 65536; i++) { 139865832Snyan if (fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP) 139965832Snyan break; 140065832Snyan (void) fe_inb(sc, FE_BMPR8); 140141823Skato } 140219781Swollman } 140341823Skato else 140441823Skato { 140565832Snyan for (i = 0; i < 65536; i += 2) { 140665832Snyan if (fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP) 140765832Snyan break; 140865832Snyan (void) fe_inw(sc, FE_BMPR8); 140941823Skato } 141041823Skato } 141119781Swollman 141219781Swollman /* 141319781Swollman * Double check. 141419781Swollman */ 141565832Snyan if (fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP) { 1416147256Sbrooks if_printf(sc->ifp, 1417147256Sbrooks "could not empty receive buffer\n"); 141819781Swollman /* Hmm. What should I do if this happens? FIXME. */ 141919781Swollman } 142019781Swollman 142119781Swollman /* 142219781Swollman * Restart receiving packets. 142319781Swollman */ 142465832Snyan fe_outb(sc, FE_DLCR5, saved_dlcr5); 142519781Swollman} 142641823Skato#endif 142719781Swollman 142819781Swollman/* 14298027Swollman * Transmission interrupt handler 14308027Swollman * The control flow of this function looks silly. FIXME. 14318027Swollman */ 14328027Swollmanstatic void 143365832Snyanfe_tint (struct fe_softc * sc, u_char tstat) 14348027Swollman{ 14358027Swollman int left; 14368027Swollman int col; 14378027Swollman 14388027Swollman /* 14398027Swollman * Handle "excessive collision" interrupt. 14408027Swollman */ 144165832Snyan if (tstat & FE_D0_COLL16) { 14428027Swollman 14438027Swollman /* 14448027Swollman * Find how many packets (including this collided one) 14458027Swollman * are left unsent in transmission buffer. 14468027Swollman */ 144765832Snyan left = fe_inb(sc, FE_BMPR10); 1448147256Sbrooks if_printf(sc->ifp, "excessive collision (%d/%d)\n", 1449147256Sbrooks left, sc->txb_sched); 14508027Swollman 14518027Swollman /* 145219781Swollman * Clear the collision flag (in 86960) here 145319781Swollman * to avoid confusing statistics. 14548027Swollman */ 145565832Snyan fe_outb(sc, FE_DLCR0, FE_D0_COLLID); 14568027Swollman 14578027Swollman /* 14588027Swollman * Restart transmitter, skipping the 14598027Swollman * collided packet. 14608027Swollman * 14618027Swollman * We *must* skip the packet to keep network running 14628027Swollman * properly. Excessive collision error is an 14638027Swollman * indication of the network overload. If we 14648027Swollman * tried sending the same packet after excessive 14658027Swollman * collision, the network would be filled with 14668027Swollman * out-of-time packets. Packets belonging 14678027Swollman * to reliable transport (such as TCP) are resent 14688027Swollman * by some upper layer. 14698027Swollman */ 147065832Snyan fe_outb(sc, FE_BMPR11, FE_B11_CTRL_SKIP | FE_B11_MODE1); 147119781Swollman 147219781Swollman /* Update statistics. */ 147319781Swollman sc->tx_excolls++; 14748027Swollman } 14758027Swollman 14768027Swollman /* 14778027Swollman * Handle "transmission complete" interrupt. 14788027Swollman */ 147965832Snyan if (tstat & FE_D0_TXDONE) { 14808027Swollman 14818027Swollman /* 14828027Swollman * Add in total number of collisions on last 14838027Swollman * transmission. We also clear "collision occurred" flag 14848027Swollman * here. 14858027Swollman * 14868027Swollman * 86960 has a design flaw on collision count on multiple 14878027Swollman * packet transmission. When we send two or more packets 14888027Swollman * with one start command (that's what we do when the 148914645Sjkh * transmission queue is crowded), 86960 informs us number 149014645Sjkh * of collisions occurred on the last packet on the 14918027Swollman * transmission only. Number of collisions on previous 14928027Swollman * packets are lost. I have told that the fact is clearly 14938027Swollman * stated in the Fujitsu document. 14948027Swollman * 14958027Swollman * I considered not to mind it seriously. Collision 14968027Swollman * count is not so important, anyway. Any comments? FIXME. 14978027Swollman */ 14988027Swollman 149965832Snyan if (fe_inb(sc, FE_DLCR0) & FE_D0_COLLID) { 15008027Swollman 15018027Swollman /* Clear collision flag. */ 150265832Snyan fe_outb(sc, FE_DLCR0, FE_D0_COLLID); 15038027Swollman 15048027Swollman /* Extract collision count from 86960. */ 150565832Snyan col = fe_inb(sc, FE_DLCR4); 150665832Snyan col = (col & FE_D4_COL) >> FE_D4_COL_SHIFT; 150765832Snyan if (col == 0) { 15088027Swollman /* 15098027Swollman * Status register indicates collisions, 15108027Swollman * while the collision count is zero. 15118027Swollman * This can happen after multiple packet 15128027Swollman * transmission, indicating that one or more 15138027Swollman * previous packet(s) had been collided. 15148027Swollman * 15158027Swollman * Since the accurate number of collisions 15168027Swollman * has been lost, we just guess it as 1; 15178027Swollman * Am I too optimistic? FIXME. 15188027Swollman */ 15198027Swollman col = 1; 15208027Swollman } 1521147256Sbrooks sc->ifp->if_collisions += col; 152265832Snyan if (col == 1) 152341823Skato sc->mibdata.dot3StatsSingleCollisionFrames++; 152465832Snyan else 152541823Skato sc->mibdata.dot3StatsMultipleCollisionFrames++; 152641823Skato sc->mibdata.dot3StatsCollFrequencies[col-1]++; 15278027Swollman } 15288027Swollman 15298027Swollman /* 153019781Swollman * Update transmission statistics. 153119781Swollman * Be sure to reflect number of excessive collisions. 15328027Swollman */ 153341823Skato col = sc->tx_excolls; 1534147256Sbrooks sc->ifp->if_opackets += sc->txb_sched - col; 1535147256Sbrooks sc->ifp->if_oerrors += col; 1536147256Sbrooks sc->ifp->if_collisions += col * 16; 153741823Skato sc->mibdata.dot3StatsExcessiveCollisions += col; 153841823Skato sc->mibdata.dot3StatsCollFrequencies[15] += col; 15398027Swollman sc->txb_sched = 0; 15408027Swollman 15418027Swollman /* 15428027Swollman * The transmitter is no more active. 15438876Srgrimes * Reset output active flag and watchdog timer. 15448027Swollman */ 1545148887Srwatson sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1546179959Sjhb sc->tx_timeout = 0; 15478027Swollman 15488027Swollman /* 15498027Swollman * If more data is ready to transmit in the buffer, start 15508027Swollman * transmitting them. Otherwise keep transmitter idle, 15518027Swollman * even if more data is queued. This gives receive 15528027Swollman * process a slight priority. 15538027Swollman */ 155465832Snyan if (sc->txb_count > 0) 155565832Snyan fe_xmit(sc); 15568027Swollman } 15578027Swollman} 15588027Swollman 15598027Swollman/* 15608027Swollman * Ethernet interface receiver interrupt. 15618027Swollman */ 15628027Swollmanstatic void 156365832Snyanfe_rint (struct fe_softc * sc, u_char rstat) 15648027Swollman{ 15658027Swollman u_short len; 15668027Swollman u_char status; 15678027Swollman int i; 15688027Swollman 15698027Swollman /* 15708027Swollman * Update statistics if this interrupt is caused by an error. 157141823Skato * Note that, when the system was not sufficiently fast, the 157241823Skato * receive interrupt might not be acknowledged immediately. If 157341823Skato * one or more errornous frames were received before this routine 157441823Skato * was scheduled, they are ignored, and the following error stats 157541823Skato * give less than real values. 15768027Swollman */ 157765832Snyan if (rstat & (FE_D1_OVRFLO | FE_D1_CRCERR | FE_D1_ALGERR | FE_D1_SRTPKT)) { 157865832Snyan if (rstat & FE_D1_OVRFLO) 157941823Skato sc->mibdata.dot3StatsInternalMacReceiveErrors++; 158065832Snyan if (rstat & FE_D1_CRCERR) 158141823Skato sc->mibdata.dot3StatsFCSErrors++; 158265832Snyan if (rstat & FE_D1_ALGERR) 158341823Skato sc->mibdata.dot3StatsAlignmentErrors++; 158441823Skato#if 0 158541823Skato /* The reference MAC receiver defined in 802.3 158641823Skato silently ignores short frames (RUNTs) without 158741823Skato notifying upper layer. RFC 1650 (dot3 MIB) is 158841823Skato based on the 802.3, and it has no stats entry for 158941823Skato RUNTs... */ 159065832Snyan if (rstat & FE_D1_SRTPKT) 159141823Skato sc->mibdata.dot3StatsFrameTooShorts++; /* :-) */ 15928027Swollman#endif 1593147256Sbrooks sc->ifp->if_ierrors++; 15948027Swollman } 15958027Swollman 15968027Swollman /* 15978027Swollman * MB86960 has a flag indicating "receive queue empty." 159814645Sjkh * We just loop, checking the flag, to pull out all received 15998027Swollman * packets. 16008027Swollman * 160114645Sjkh * We limit the number of iterations to avoid infinite-loop. 160221694Swollman * The upper bound is set to unrealistic high value. 16038027Swollman */ 160465832Snyan for (i = 0; i < FE_MAX_RECV_COUNT * 2; i++) { 16058027Swollman 160614645Sjkh /* Stop the iteration if 86960 indicates no packets. */ 160765832Snyan if (fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP) 160865832Snyan return; 16098027Swollman 16108027Swollman /* 161141823Skato * Extract a receive status byte. 16128027Swollman * As our 86960 is in 16 bit bus access mode, we have to 16138027Swollman * use inw() to get the status byte. The significant 16148027Swollman * value is returned in lower 8 bits. 16158027Swollman */ 161646410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) 161741823Skato { 161865832Snyan status = fe_inb(sc, FE_BMPR8); 161965832Snyan (void) fe_inb(sc, FE_BMPR8); 162041823Skato } 162141823Skato else 162241823Skato { 162365832Snyan status = (u_char) fe_inw(sc, FE_BMPR8); 162441823Skato } 16258027Swollman 16268027Swollman /* 162719781Swollman * Extract the packet length. 162819781Swollman * It is a sum of a header (14 bytes) and a payload. 162919781Swollman * CRC has been stripped off by the 86960. 163019781Swollman */ 163146410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) 163241823Skato { 163365832Snyan len = fe_inb(sc, FE_BMPR8); 163465832Snyan len |= (fe_inb(sc, FE_BMPR8) << 8); 16358027Swollman } 163641823Skato else 163741823Skato { 163865832Snyan len = fe_inw(sc, FE_BMPR8); 163941823Skato } 16408027Swollman 16418027Swollman /* 164241823Skato * AS our 86960 is programed to ignore errored frame, 164341823Skato * we must not see any error indication in the 164441823Skato * receive buffer. So, any error condition is a 164541823Skato * serious error, e.g., out-of-sync of the receive 164641823Skato * buffer pointers. 16478027Swollman */ 164865832Snyan if ((status & 0xF0) != 0x20 || 164965832Snyan len > ETHER_MAX_LEN - ETHER_CRC_LEN || 165065832Snyan len < ETHER_MIN_LEN - ETHER_CRC_LEN) { 1651147256Sbrooks if_printf(sc->ifp, 1652147256Sbrooks "RX buffer out-of-sync\n"); 1653147256Sbrooks sc->ifp->if_ierrors++; 165441823Skato sc->mibdata.dot3StatsInternalMacReceiveErrors++; 165541823Skato fe_reset(sc); 165641823Skato return; 16578027Swollman } 16588027Swollman 16598027Swollman /* 16608027Swollman * Go get a packet. 16618027Swollman */ 166265832Snyan if (fe_get_packet(sc, len) < 0) { 166341823Skato /* 166441823Skato * Negative return from fe_get_packet() 166541823Skato * indicates no available mbuf. We stop 166641823Skato * receiving packets, even if there are more 166741823Skato * in the buffer. We hope we can get more 166841823Skato * mbuf next time. 166941823Skato */ 1670147256Sbrooks sc->ifp->if_ierrors++; 167141823Skato sc->mibdata.dot3StatsMissedFrames++; 167265832Snyan fe_droppacket(sc, len); 167341823Skato return; 16748027Swollman } 16758027Swollman 16768027Swollman /* Successfully received a packet. Update stat. */ 1677147256Sbrooks sc->ifp->if_ipackets++; 16788027Swollman } 167941823Skato 168041823Skato /* Maximum number of frames has been received. Something 168141823Skato strange is happening here... */ 1682147256Sbrooks if_printf(sc->ifp, "unusual receive flood\n"); 168341823Skato sc->mibdata.dot3StatsInternalMacReceiveErrors++; 168441823Skato fe_reset(sc); 16858027Swollman} 16868027Swollman 16878027Swollman/* 16888027Swollman * Ethernet interface interrupt processor 16898027Swollman */ 169040565Sbdestatic void 169165832Snyanfe_intr (void *arg) 16928027Swollman{ 169365832Snyan struct fe_softc *sc = arg; 16948027Swollman u_char tstat, rstat; 169541823Skato int loop_count = FE_MAX_LOOP; 16968027Swollman 1697179493Sjhb FE_LOCK(sc); 1698179493Sjhb 169941823Skato /* Loop until there are no more new interrupt conditions. */ 170041823Skato while (loop_count-- > 0) { 17018027Swollman /* 17028027Swollman * Get interrupt conditions, masking unneeded flags. 17038027Swollman */ 170465832Snyan tstat = fe_inb(sc, FE_DLCR0) & FE_TMASK; 170565832Snyan rstat = fe_inb(sc, FE_DLCR1) & FE_RMASK; 1706179493Sjhb if (tstat == 0 && rstat == 0) { 1707179493Sjhb FE_UNLOCK(sc); 170865832Snyan return; 1709179493Sjhb } 171021694Swollman 17118027Swollman /* 17128027Swollman * Reset the conditions we are acknowledging. 17138027Swollman */ 171465832Snyan fe_outb(sc, FE_DLCR0, tstat); 171565832Snyan fe_outb(sc, FE_DLCR1, rstat); 17168027Swollman 17178027Swollman /* 171841823Skato * Handle transmitter interrupts. 17198027Swollman */ 172065832Snyan if (tstat) 172165832Snyan fe_tint(sc, tstat); 17228027Swollman 17238027Swollman /* 17248027Swollman * Handle receiver interrupts 17258027Swollman */ 172665832Snyan if (rstat) 172765832Snyan fe_rint(sc, rstat); 17288027Swollman 17298027Swollman /* 17308027Swollman * Update the multicast address filter if it is 17318027Swollman * needed and possible. We do it now, because 17328027Swollman * we can make sure the transmission buffer is empty, 17338027Swollman * and there is a good chance that the receive queue 17348027Swollman * is empty. It will minimize the possibility of 173514645Sjkh * packet loss. 17368027Swollman */ 173765832Snyan if (sc->filter_change && 173865832Snyan sc->txb_count == 0 && sc->txb_sched == 0) { 17398027Swollman fe_loadmar(sc); 1740148887Srwatson sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 17418027Swollman } 17428027Swollman 17438027Swollman /* 17448027Swollman * If it looks like the transmitter can take more data, 17458027Swollman * attempt to start output on the interface. This is done 17468027Swollman * after handling the receiver interrupt to give the 17478027Swollman * receive operation priority. 17488027Swollman * 17498027Swollman * BTW, I'm not sure in what case the OACTIVE is on at 17508027Swollman * this point. Is the following test redundant? 17518027Swollman * 17528027Swollman * No. This routine polls for both transmitter and 17538027Swollman * receiver interrupts. 86960 can raise a receiver 17548027Swollman * interrupt when the transmission buffer is full. 17558027Swollman */ 1756148887Srwatson if ((sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) 1757179493Sjhb fe_start_locked(sc->ifp); 17588027Swollman } 1759179493Sjhb FE_UNLOCK(sc); 176041823Skato 1761147256Sbrooks if_printf(sc->ifp, "too many loops\n"); 17628027Swollman} 17638027Swollman 17648027Swollman/* 17658027Swollman * Process an ioctl request. This code needs some work - it looks 17668027Swollman * pretty ugly. 17678027Swollman */ 176814645Sjkhstatic int 176965832Snyanfe_ioctl (struct ifnet * ifp, u_long command, caddr_t data) 17708027Swollman{ 177114645Sjkh struct fe_softc *sc = ifp->if_softc; 177241823Skato struct ifreq *ifr = (struct ifreq *)data; 1773179493Sjhb int error = 0; 17748027Swollman 17758027Swollman switch (command) { 17768027Swollman 17778027Swollman case SIOCSIFFLAGS: 17788027Swollman /* 17798027Swollman * Switch interface state between "running" and 17808027Swollman * "stopped", reflecting the UP flag. 17818027Swollman */ 1782179493Sjhb FE_LOCK(sc); 1783147256Sbrooks if (sc->ifp->if_flags & IFF_UP) { 1784148887Srwatson if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 1785179493Sjhb fe_init_locked(sc); 17868027Swollman } else { 1787148887Srwatson if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) 178841823Skato fe_stop(sc); 17898027Swollman } 17908027Swollman 17918027Swollman /* 17928027Swollman * Promiscuous and/or multicast flags may have changed, 17938027Swollman * so reprogram the multicast filter and/or receive mode. 17948027Swollman */ 179565832Snyan fe_setmode(sc); 1796179493Sjhb FE_UNLOCK(sc); 17978027Swollman 179841823Skato /* Done. */ 17998027Swollman break; 18008027Swollman 18018027Swollman case SIOCADDMULTI: 18028027Swollman case SIOCDELMULTI: 18038027Swollman /* 180441823Skato * Multicast list has changed; set the hardware filter 180541823Skato * accordingly. 18068027Swollman */ 1807179493Sjhb FE_LOCK(sc); 180865832Snyan fe_setmode(sc); 1809179493Sjhb FE_UNLOCK(sc); 181041823Skato break; 18118027Swollman 181241823Skato case SIOCSIFMEDIA: 181341823Skato case SIOCGIFMEDIA: 181441823Skato /* Let if_media to handle these commands and to call 181541823Skato us back. */ 181641823Skato error = ifmedia_ioctl(ifp, ifr, &sc->media, command); 18178027Swollman break; 18188027Swollman 18198027Swollman default: 1820106937Ssam error = ether_ioctl(ifp, command, data); 182141823Skato break; 18228027Swollman } 18238027Swollman 18248027Swollman return (error); 18258027Swollman} 18268027Swollman 18278027Swollman/* 182814645Sjkh * Retrieve packet from receive buffer and send to the next level up via 182960536Sarchie * ether_input(). 18308027Swollman * Returns 0 if success, -1 if error (i.e., mbuf allocation failure). 18318027Swollman */ 18328027Swollmanstatic int 183365832Snyanfe_get_packet (struct fe_softc * sc, u_short len) 18348027Swollman{ 1835147256Sbrooks struct ifnet *ifp = sc->ifp; 18368027Swollman struct ether_header *eh; 18378027Swollman struct mbuf *m; 18388027Swollman 1839179493Sjhb FE_ASSERT_LOCKED(sc); 1840179493Sjhb 18418027Swollman /* 18428027Swollman * NFS wants the data be aligned to the word (4 byte) 18438027Swollman * boundary. Ethernet header has 14 bytes. There is a 18448027Swollman * 2-byte gap. 18458027Swollman */ 18468027Swollman#define NFS_MAGIC_OFFSET 2 18478027Swollman 18488027Swollman /* 18498027Swollman * This function assumes that an Ethernet packet fits in an 18508027Swollman * mbuf (with a cluster attached when necessary.) On FreeBSD 18518027Swollman * 2.0 for x86, which is the primary target of this driver, an 18528027Swollman * mbuf cluster has 4096 bytes, and we are happy. On ancient 18538027Swollman * BSDs, such as vanilla 4.3 for 386, a cluster size was 1024, 18548027Swollman * however. If the following #error message were printed upon 18558027Swollman * compile, you need to rewrite this function. 18568027Swollman */ 185717455Sphk#if ( MCLBYTES < ETHER_MAX_LEN - ETHER_CRC_LEN + NFS_MAGIC_OFFSET ) 18588027Swollman#error "Too small MCLBYTES to use fe driver." 18598027Swollman#endif 18608027Swollman 18618027Swollman /* 18628027Swollman * Our strategy has one more problem. There is a policy on 18638027Swollman * mbuf cluster allocation. It says that we must have at 18648027Swollman * least MINCLSIZE (208 bytes on FreeBSD 2.0 for x86) to 18658027Swollman * allocate a cluster. For a packet of a size between 18668027Swollman * (MHLEN - 2) to (MINCLSIZE - 2), our code violates the rule... 186714645Sjkh * On the other hand, the current code is short, simple, 18688027Swollman * and fast, however. It does no harmful thing, just waists 18698027Swollman * some memory. Any comments? FIXME. 18708027Swollman */ 18718027Swollman 18728027Swollman /* Allocate an mbuf with packet header info. */ 1873248078Smarius MGETHDR(m, M_NOWAIT, MT_DATA); 187465832Snyan if (m == NULL) 187565832Snyan return -1; 18768027Swollman 18778027Swollman /* Attach a cluster if this packet doesn't fit in a normal mbuf. */ 187865832Snyan if (len > MHLEN - NFS_MAGIC_OFFSET) { 1879248078Smarius MCLGET(m, M_NOWAIT); 188065832Snyan if (!(m->m_flags & M_EXT)) { 188165832Snyan m_freem(m); 18828027Swollman return -1; 18838027Swollman } 18848027Swollman } 18858027Swollman 18868027Swollman /* Initialize packet header info. */ 1887106937Ssam m->m_pkthdr.rcvif = ifp; 18888027Swollman m->m_pkthdr.len = len; 18898027Swollman 18908027Swollman /* Set the length of this packet. */ 18918027Swollman m->m_len = len; 18928027Swollman 189314645Sjkh /* The following silliness is to make NFS happy */ 18948027Swollman m->m_data += NFS_MAGIC_OFFSET; 18958027Swollman 189641823Skato /* Get (actually just point to) the header part. */ 189741823Skato eh = mtod(m, struct ether_header *); 189841823Skato 18998027Swollman /* Get a packet. */ 190046410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) 190141823Skato { 190265832Snyan fe_insb(sc, FE_BMPR8, (u_int8_t *)eh, len); 190341823Skato } 190441823Skato else 190541823Skato { 190665832Snyan fe_insw(sc, FE_BMPR8, (u_int16_t *)eh, (len + 1) >> 1); 190741823Skato } 19088027Swollman 19098027Swollman /* Feed the packet to upper layer. */ 1910179493Sjhb FE_UNLOCK(sc); 1911106937Ssam (*ifp->if_input)(ifp, m); 1912179493Sjhb FE_LOCK(sc); 19138027Swollman return 0; 19148027Swollman} 19158027Swollman 19168027Swollman/* 19178027Swollman * Write an mbuf chain to the transmission buffer memory using 16 bit PIO. 19188027Swollman * Returns number of bytes actually written, including length word. 19198027Swollman * 19208027Swollman * If an mbuf chain is too long for an Ethernet frame, it is not sent. 19218027Swollman * Packets shorter than Ethernet minimum are legal, and we pad them 19228876Srgrimes * before sending out. An exception is "partial" packets which are 19238027Swollman * shorter than mandatory Ethernet header. 19248027Swollman */ 19258027Swollmanstatic void 192665832Snyanfe_write_mbufs (struct fe_softc *sc, struct mbuf *m) 19278027Swollman{ 19288027Swollman u_short length, len; 19298027Swollman struct mbuf *mp; 19308027Swollman u_char *data; 19318027Swollman u_short savebyte; /* WARNING: Architecture dependent! */ 19328027Swollman#define NO_PENDING_BYTE 0xFFFF 19338027Swollman 193465832Snyan static u_char padding [ETHER_MIN_LEN - ETHER_CRC_LEN - ETHER_HDR_LEN]; 193518794Swollman 193641823Skato#ifdef DIAGNOSTIC 19378027Swollman /* First, count up the total number of bytes to copy */ 19388027Swollman length = 0; 193965832Snyan for (mp = m; mp != NULL; mp = mp->m_next) 19408027Swollman length += mp->m_len; 194165832Snyan 194241823Skato /* Check if this matches the one in the packet header. */ 194365832Snyan if (length != m->m_pkthdr.len) { 1944147256Sbrooks if_printf(sc->ifp, 1945147256Sbrooks "packet length mismatch? (%d/%d)\n", 1946147256Sbrooks length, m->m_pkthdr.len); 194741823Skato } 194821694Swollman#else 194921694Swollman /* Just use the length value in the packet header. */ 195021694Swollman length = m->m_pkthdr.len; 195121694Swollman#endif 195221694Swollman 195341823Skato#ifdef DIAGNOSTIC 19548027Swollman /* 19558027Swollman * Should never send big packets. If such a packet is passed, 19568027Swollman * it should be a bug of upper layer. We just ignore it. 19578027Swollman * ... Partial (too short) packets, neither. 19588027Swollman */ 195965832Snyan if (length < ETHER_HDR_LEN || 196065832Snyan length > ETHER_MAX_LEN - ETHER_CRC_LEN) { 1961147256Sbrooks if_printf(sc->ifp, 1962147256Sbrooks "got an out-of-spec packet (%u bytes) to send\n", length); 1963147256Sbrooks sc->ifp->if_oerrors++; 196441823Skato sc->mibdata.dot3StatsInternalMacTransmitErrors++; 19658027Swollman return; 19668027Swollman } 19678027Swollman#endif 19688027Swollman 19698027Swollman /* 19708027Swollman * Put the length word for this frame. 19718027Swollman * Does 86960 accept odd length? -- Yes. 19728027Swollman * Do we need to pad the length to minimum size by ourselves? 19738027Swollman * -- Generally yes. But for (or will be) the last 19748027Swollman * packet in the transmission buffer, we can skip the 19758027Swollman * padding process. It may gain performance slightly. FIXME. 19768027Swollman */ 197746410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) 197841823Skato { 197965832Snyan len = max(length, ETHER_MIN_LEN - ETHER_CRC_LEN); 198065832Snyan fe_outb(sc, FE_BMPR8, len & 0x00ff); 198165832Snyan fe_outb(sc, FE_BMPR8, (len & 0xff00) >> 8); 198241823Skato } 198341823Skato else 198441823Skato { 198565832Snyan fe_outw(sc, FE_BMPR8, 198665832Snyan max(length, ETHER_MIN_LEN - ETHER_CRC_LEN)); 198741823Skato } 19888027Swollman 19898027Swollman /* 19908027Swollman * Update buffer status now. 19918027Swollman * Truncate the length up to an even number, since we use outw(). 19928027Swollman */ 199346410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) != FE_D6_SBW_BYTE) 199441823Skato { 199565832Snyan length = (length + 1) & ~1; 199641823Skato } 199765832Snyan sc->txb_free -= FE_DATA_LEN_LEN + 199865832Snyan max(length, ETHER_MIN_LEN - ETHER_CRC_LEN); 19998027Swollman sc->txb_count++; 20008027Swollman 20018027Swollman /* 20028876Srgrimes * Transfer the data from mbuf chain to the transmission buffer. 20038027Swollman * MB86960 seems to require that data be transferred as words, and 20048027Swollman * only words. So that we require some extra code to patch 20058027Swollman * over odd-length mbufs. 20068027Swollman */ 200746410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) 200841823Skato { 200941823Skato /* 8-bit cards are easy. */ 201065832Snyan for (mp = m; mp != 0; mp = mp->m_next) { 201165832Snyan if (mp->m_len) 201265832Snyan fe_outsb(sc, FE_BMPR8, mtod(mp, caddr_t), 201365832Snyan mp->m_len); 201441823Skato } 201541823Skato } 201641823Skato else 201741823Skato { 201841823Skato /* 16-bit cards are a pain. */ 201941823Skato savebyte = NO_PENDING_BYTE; 202065832Snyan for (mp = m; mp != 0; mp = mp->m_next) { 20218027Swollman 202241823Skato /* Ignore empty mbuf. */ 202341823Skato len = mp->m_len; 202465832Snyan if (len == 0) 202565832Snyan continue; 20268027Swollman 202741823Skato /* Find the actual data to send. */ 202841823Skato data = mtod(mp, caddr_t); 20298027Swollman 203041823Skato /* Finish the last byte. */ 203165832Snyan if (savebyte != NO_PENDING_BYTE) { 203265832Snyan fe_outw(sc, FE_BMPR8, savebyte | (*data << 8)); 203341823Skato data++; 203441823Skato len--; 203541823Skato savebyte = NO_PENDING_BYTE; 203641823Skato } 20378027Swollman 203841823Skato /* output contiguous words */ 203941823Skato if (len > 1) { 204065832Snyan fe_outsw(sc, FE_BMPR8, (u_int16_t *)data, 204165832Snyan len >> 1); 204241823Skato data += len & ~1; 204341823Skato len &= 1; 204441823Skato } 204541823Skato 204641823Skato /* Save a remaining byte, if there is one. */ 204765832Snyan if (len > 0) 204841823Skato savebyte = *data; 20498027Swollman } 20508027Swollman 205141823Skato /* Spit the last byte, if the length is odd. */ 205265832Snyan if (savebyte != NO_PENDING_BYTE) 205365832Snyan fe_outw(sc, FE_BMPR8, savebyte); 20548027Swollman } 20558027Swollman 205618794Swollman /* Pad to the Ethernet minimum length, if the packet is too short. */ 205765832Snyan if (length < ETHER_MIN_LEN - ETHER_CRC_LEN) { 205846410Skato if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) 205941823Skato { 206065832Snyan fe_outsb(sc, FE_BMPR8, padding, 206165832Snyan ETHER_MIN_LEN - ETHER_CRC_LEN - length); 206241823Skato } 206341823Skato else 206441823Skato { 206565832Snyan fe_outsw(sc, FE_BMPR8, (u_int16_t *)padding, 206665832Snyan (ETHER_MIN_LEN - ETHER_CRC_LEN - length) >> 1); 206741823Skato } 206818794Swollman } 20698027Swollman} 20708027Swollman 20718027Swollman/* 20728027Swollman * Compute the multicast address filter from the 20738027Swollman * list of multicast addresses we need to listen to. 20748027Swollman */ 20758027Swollmanstatic struct fe_filter 20768027Swollmanfe_mcaf ( struct fe_softc *sc ) 20778027Swollman{ 20788027Swollman int index; 20798027Swollman struct fe_filter filter; 208021666Swollman struct ifmultiaddr *ifma; 20818027Swollman 20828027Swollman filter = fe_filter_nothing; 2083195049Srwatson if_maddr_rlock(sc->ifp); 2084147256Sbrooks TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { 208521666Swollman if (ifma->ifma_addr->sa_family != AF_LINK) 208621666Swollman continue; 2087130270Snaddy index = ether_crc32_le(LLADDR((struct sockaddr_dl *) 2088130270Snaddy ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 208941823Skato#ifdef FE_DEBUG 2090147256Sbrooks if_printf(sc->ifp, "hash(%6D) == %d\n", 2091147256Sbrooks enm->enm_addrlo , ":", index); 20928027Swollman#endif 20938876Srgrimes 20948027Swollman filter.data[index >> 3] |= 1 << (index & 7); 20958027Swollman } 2096195049Srwatson if_maddr_runlock(sc->ifp); 20978027Swollman return ( filter ); 20988027Swollman} 20998027Swollman 21008027Swollman/* 21018027Swollman * Calculate a new "multicast packet filter" and put the 86960 21028027Swollman * receiver in appropriate mode. 21038027Swollman */ 21048027Swollmanstatic void 210565832Snyanfe_setmode (struct fe_softc *sc) 21068027Swollman{ 21078027Swollman 21088027Swollman /* 21098027Swollman * If the interface is not running, we postpone the update 21108027Swollman * process for receive modes and multicast address filter 21118027Swollman * until the interface is restarted. It reduces some 21128027Swollman * complicated job on maintaining chip states. (Earlier versions 21138027Swollman * of this driver had a bug on that point...) 21148027Swollman * 21158027Swollman * To complete the trick, fe_init() calls fe_setmode() after 21168027Swollman * restarting the interface. 21178027Swollman */ 2118148887Srwatson if (!(sc->ifp->if_drv_flags & IFF_DRV_RUNNING)) 211965832Snyan return; 21208027Swollman 21218027Swollman /* 21228027Swollman * Promiscuous mode is handled separately. 21238027Swollman */ 2124148887Srwatson if (sc->ifp->if_flags & IFF_PROMISC) { 21258027Swollman /* 21268027Swollman * Program 86960 to receive all packets on the segment 21278027Swollman * including those directed to other stations. 21288027Swollman * Multicast filter stored in MARs are ignored 21298027Swollman * under this setting, so we don't need to update it. 21308027Swollman * 21318027Swollman * Promiscuous mode in FreeBSD 2 is used solely by 21328027Swollman * BPF, and BPF only listens to valid (no error) packets. 213314645Sjkh * So, we ignore erroneous ones even in this mode. 21348027Swollman * (Older versions of fe driver mistook the point.) 21358027Swollman */ 213665832Snyan fe_outb(sc, FE_DLCR5, 213765832Snyan sc->proto_dlcr5 | FE_D5_AFM0 | FE_D5_AFM1); 21388027Swollman sc->filter_change = 0; 21398027Swollman return; 21408027Swollman } 21418027Swollman 21428027Swollman /* 21438027Swollman * Turn the chip to the normal (non-promiscuous) mode. 21448027Swollman */ 214565832Snyan fe_outb(sc, FE_DLCR5, sc->proto_dlcr5 | FE_D5_AFM1); 21468027Swollman 21478027Swollman /* 21488027Swollman * Find the new multicast filter value. 21498027Swollman */ 2150148887Srwatson if (sc->ifp->if_flags & IFF_ALLMULTI) 21518027Swollman sc->filter = fe_filter_all; 215265832Snyan else 215365832Snyan sc->filter = fe_mcaf(sc); 21548027Swollman sc->filter_change = 1; 21558027Swollman 21568027Swollman /* 21578027Swollman * We have to update the multicast filter in the 86960, A.S.A.P. 21588027Swollman * 215914645Sjkh * Note that the DLC (Data Link Control unit, i.e. transmitter 21608027Swollman * and receiver) must be stopped when feeding the filter, and 216114645Sjkh * DLC trashes all packets in both transmission and receive 21628027Swollman * buffers when stopped. 21638027Swollman * 216414645Sjkh * To reduce the packet loss, we delay the filter update 21658027Swollman * process until buffers are empty. 21668027Swollman */ 216765832Snyan if (sc->txb_sched == 0 && sc->txb_count == 0 && 216865832Snyan !(fe_inb(sc, FE_DLCR1) & FE_D1_PKTRDY)) { 21698027Swollman /* 21708027Swollman * Buffers are (apparently) empty. Load 21718027Swollman * the new filter value into MARs now. 21728027Swollman */ 21738027Swollman fe_loadmar(sc); 21748027Swollman } else { 21758027Swollman /* 21768027Swollman * Buffers are not empty. Mark that we have to update 21778027Swollman * the MARs. The new filter will be loaded by feintr() 21788027Swollman * later. 21798027Swollman */ 21808027Swollman } 21818027Swollman} 21828027Swollman 21838027Swollman/* 21848027Swollman * Load a new multicast address filter into MARs. 21858027Swollman * 2186179493Sjhb * The caller must have acquired the softc lock before fe_loadmar. 21878027Swollman * This function starts the DLC upon return. So it can be called only 21888027Swollman * when the chip is working, i.e., from the driver's point of view, when 21898027Swollman * a device is RUNNING. (I mistook the point in previous versions.) 21908027Swollman */ 21918027Swollmanstatic void 219265832Snyanfe_loadmar (struct fe_softc * sc) 21938027Swollman{ 21948027Swollman /* Stop the DLC (transmitter and receiver). */ 219565832Snyan DELAY(200); 219665832Snyan fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE); 219765832Snyan DELAY(200); 21988027Swollman 21998027Swollman /* Select register bank 1 for MARs. */ 220065832Snyan fe_outb(sc, FE_DLCR7, sc->proto_dlcr7 | FE_D7_RBS_MAR | FE_D7_POWER_UP); 22018027Swollman 22028027Swollman /* Copy filter value into the registers. */ 220365832Snyan fe_outblk(sc, FE_MAR8, sc->filter.data, FE_FILTER_LEN); 22048027Swollman 22058027Swollman /* Restore the bank selection for BMPRs (i.e., runtime registers). */ 220665832Snyan fe_outb(sc, FE_DLCR7, 220765832Snyan sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP); 22088027Swollman 22098027Swollman /* Restart the DLC. */ 221065832Snyan DELAY(200); 221165832Snyan fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_ENABLE); 221265832Snyan DELAY(200); 22138027Swollman 22148027Swollman /* We have just updated the filter. */ 22158027Swollman sc->filter_change = 0; 221641823Skato} 22178027Swollman 221841823Skato/* Change the media selection. */ 221941823Skatostatic int 222041823Skatofe_medchange (struct ifnet *ifp) 222141823Skato{ 222241823Skato struct fe_softc *sc = (struct fe_softc *)ifp->if_softc; 222341823Skato 222441823Skato#ifdef DIAGNOSTIC 222541823Skato /* If_media should not pass any request for a media which this 222641823Skato interface doesn't support. */ 222741823Skato int b; 222841823Skato 222941823Skato for (b = 0; bit2media[b] != 0; b++) { 223041823Skato if (bit2media[b] == sc->media.ifm_media) break; 223141823Skato } 223241823Skato if (((1 << b) & sc->mbitmap) == 0) { 2233147256Sbrooks if_printf(sc->ifp, 2234147256Sbrooks "got an unsupported media request (0x%x)\n", 2235147256Sbrooks sc->media.ifm_media); 223641823Skato return EINVAL; 223741823Skato } 22388027Swollman#endif 223941823Skato 224041823Skato /* We don't actually change media when the interface is down. 224141823Skato fe_init() will do the job, instead. Should we also wait 224241823Skato until the transmission buffer being empty? Changing the 224341823Skato media when we are sending a frame will cause two garbages 224441823Skato on wires, one on old media and another on new. FIXME */ 2245179493Sjhb FE_LOCK(sc); 2246147256Sbrooks if (sc->ifp->if_flags & IFF_UP) { 224741823Skato if (sc->msel) sc->msel(sc); 224841823Skato } 2249179493Sjhb FE_UNLOCK(sc); 225041823Skato 225141823Skato return 0; 22528027Swollman} 22538027Swollman 225441823Skato/* I don't know how I can support media status callback... FIXME. */ 22558027Swollmanstatic void 225641823Skatofe_medstat (struct ifnet *ifp, struct ifmediareq *ifmr) 22578027Swollman{ 225841823Skato (void)ifp; 225941823Skato (void)ifmr; 22608027Swollman} 2261