Beispiel #1
0
static void
lmc_ds3_watchdog (lmc_softc_t * const sc)
{
	sc->lmc_miireg16 = lmc_mii_readreg (sc, 0, 16);
	if (sc->lmc_miireg16 & 0x0018)
	{
		printf("%s: AIS Received\n", sc->lmc_xname);
		lmc_led_on (sc, LMC_DS3_LED1 | LMC_DS3_LED2);
	}
}
static void
lmc_shutdown(void *arg)
{
	lmc_softc_t * const sc = arg;
	LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
	DELAY(10);

	sc->lmc_miireg16 = 0;  /* deassert ready, and all others too */
	lmc_led_on(sc, LMC_MII16_LED_ALL);
}
Beispiel #3
0
static void
lmc_t1_watchdog(lmc_softc_t * const sc)
{
	int t1stat;

	/* read alarm 1 status (receive) */
	t1stat = lmc_t1_read (sc, 0x47);
	/* blue alarm -- RAIS */
	if (t1stat & 0x08) {
		if (sc->lmc_blue != 1)
			printf ("%s: AIS Received\n", sc->lmc_xname);
		lmc_led_on (sc, LMC_DS3_LED1 | LMC_DS3_LED2);
		sc->lmc_blue = 1;
	} else {
		if (sc->lmc_blue == 1)
			printf ("%s: AIS ok\n", sc->lmc_xname);
		lmc_led_off (sc, LMC_DS3_LED1);
		lmc_led_on (sc, LMC_DS3_LED2);
		sc->lmc_blue = 0;
	}

	/* Red alarm -- LOS | LOF */
	if (t1stat & 0x04) {
		/* Only print the error once */
		if (sc->lmc_red != 1)
			printf ("%s: Red Alarm\n", sc->lmc_xname);
		lmc_led_on (sc, LMC_DS3_LED2 | LMC_DS3_LED3);
		sc->lmc_red = 1;
	} else { 
		if (sc->lmc_red == 1)
			printf ("%s: Red Alarm ok\n", sc->lmc_xname);
	lmc_led_off (sc, LMC_DS3_LED3);
	lmc_led_on (sc, LMC_DS3_LED2);
	sc->lmc_red = 0;
	}

	/* check for Receive Multiframe Yellow Alarm
	 * Ignore Receive Yellow Alarm
	 */
	if (t1stat & 0x80) {
		if (sc->lmc_yel != 1) {
			printf ("%s: Receive Yellow Alarm\n", sc->lmc_xname);
		}
			lmc_led_on (sc, LMC_DS3_LED0 | LMC_DS3_LED2);
			sc->lmc_yel = 1;
	}
	else {
		if (sc->lmc_yel == 1)
		printf ("%s: Yellow Alarm ok\n", sc->lmc_xname);
		lmc_led_off (sc, LMC_DS3_LED0);
		lmc_led_on (sc, LMC_DS3_LED2);
		sc->lmc_yel = 0;
	}
}
Beispiel #4
0
static void
lmc_ssi_watchdog (lmc_softc_t * const sc)
{
	u_int16_t mii17;
	struct ssicsr2 {
		unsigned short dtr:1, dsr:1, rts:1, cable:3, crc:1, led0:1,
		led1:1, led2:1, led3:1, fifo:1, ll:1, rl:1, tm:1, loop:1;
	};
	struct ssicsr2 *ssicsr;
	mii17 = lmc_mii_readreg (sc, 0, 17);
	ssicsr = (struct ssicsr2 *) &mii17;
	if (ssicsr->cable == 7) {
		lmc_led_off (sc, LMC_MII16_LED2);
	}
	else {
		lmc_led_on (sc, LMC_MII16_LED2);
	}

}
int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 
{
    lmc_softc_t *sc = dev_to_sc(dev);
    lmc_ctl_t ctl;
    int ret = -EOPNOTSUPP;
    u16 regVal;
    unsigned long flags;

    lmc_trace(dev, "lmc_ioctl in");


    switch (cmd) {
    case LMCIOCGINFO: 
	if (copy_to_user(ifr->ifr_data, &sc->ictl, sizeof(lmc_ctl_t)))
		ret = -EFAULT;
	else
		ret = 0;
        break;

    case LMCIOCSINFO: 
        if (!capable(CAP_NET_ADMIN)) {
            ret = -EPERM;
            break;
        }

        if(dev->flags & IFF_UP){
            ret = -EBUSY;
            break;
        }

	if (copy_from_user(&ctl, ifr->ifr_data, sizeof(lmc_ctl_t))) {
		ret = -EFAULT;
		break;
	}

	spin_lock_irqsave(&sc->lmc_lock, flags);
        sc->lmc_media->set_status (sc, &ctl);

        if(ctl.crc_length != sc->ictl.crc_length) {
            sc->lmc_media->set_crc_length(sc, ctl.crc_length);
	    if (sc->ictl.crc_length == LMC_CTL_CRC_LENGTH_16)
		sc->TxDescriptControlInit |=  LMC_TDES_ADD_CRC_DISABLE;
	    else
		sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE;
        }
	spin_unlock_irqrestore(&sc->lmc_lock, flags);

        ret = 0;
        break;

    case LMCIOCIFTYPE: 
        {
	    u16 old_type = sc->if_type;
	    u16	new_type;

	    if (!capable(CAP_NET_ADMIN)) {
		ret = -EPERM;
		break;
	    }

	    if (copy_from_user(&new_type, ifr->ifr_data, sizeof(u16))) {
		ret = -EFAULT;
		break;
	    }

            
	    if (new_type == old_type)
	    {
		ret = 0 ;
		break;				
            }
            
	    spin_lock_irqsave(&sc->lmc_lock, flags);
            lmc_proto_close(sc);

            sc->if_type = new_type;
            lmc_proto_attach(sc);
	    ret = lmc_proto_open(sc);
	    spin_unlock_irqrestore(&sc->lmc_lock, flags);
	    break;
	}

    case LMCIOCGETXINFO: 
	spin_lock_irqsave(&sc->lmc_lock, flags);
        sc->lmc_xinfo.Magic0 = 0xBEEFCAFE;

        sc->lmc_xinfo.PciCardType = sc->lmc_cardtype;
        sc->lmc_xinfo.PciSlotNumber = 0;
        sc->lmc_xinfo.DriverMajorVersion = DRIVER_MAJOR_VERSION;
        sc->lmc_xinfo.DriverMinorVersion = DRIVER_MINOR_VERSION;
        sc->lmc_xinfo.DriverSubVersion = DRIVER_SUB_VERSION;
        sc->lmc_xinfo.XilinxRevisionNumber =
            lmc_mii_readreg (sc, 0, 3) & 0xf;
        sc->lmc_xinfo.MaxFrameSize = LMC_PKT_BUF_SZ;
        sc->lmc_xinfo.link_status = sc->lmc_media->get_link_status (sc);
        sc->lmc_xinfo.mii_reg16 = lmc_mii_readreg (sc, 0, 16);
	spin_unlock_irqrestore(&sc->lmc_lock, flags);

        sc->lmc_xinfo.Magic1 = 0xDEADBEEF;

        if (copy_to_user(ifr->ifr_data, &sc->lmc_xinfo,
			 sizeof(struct lmc_xinfo)))
		ret = -EFAULT;
	else
		ret = 0;

        break;

    case LMCIOCGETLMCSTATS:
	    spin_lock_irqsave(&sc->lmc_lock, flags);
	    if (sc->lmc_cardtype == LMC_CARDTYPE_T1) {
		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_LSB);
		    sc->extra_stats.framingBitErrorCount +=
			    lmc_mii_readreg(sc, 0, 18) & 0xff;
		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_MSB);
		    sc->extra_stats.framingBitErrorCount +=
			    (lmc_mii_readreg(sc, 0, 18) & 0xff) << 8;
		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_LSB);
		    sc->extra_stats.lineCodeViolationCount +=
			    lmc_mii_readreg(sc, 0, 18) & 0xff;
		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_MSB);
		    sc->extra_stats.lineCodeViolationCount +=
			    (lmc_mii_readreg(sc, 0, 18) & 0xff) << 8;
		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_AERR);
		    regVal = lmc_mii_readreg(sc, 0, 18) & 0xff;

		    sc->extra_stats.lossOfFrameCount +=
			    (regVal & T1FRAMER_LOF_MASK) >> 4;
		    sc->extra_stats.changeOfFrameAlignmentCount +=
			    (regVal & T1FRAMER_COFA_MASK) >> 2;
		    sc->extra_stats.severelyErroredFrameCount +=
			    regVal & T1FRAMER_SEF_MASK;
	    }
	    spin_unlock_irqrestore(&sc->lmc_lock, flags);
	    if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats,
			     sizeof(sc->lmc_device->stats)) ||
		copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats),
			     &sc->extra_stats, sizeof(sc->extra_stats)))
		    ret = -EFAULT;
	    else
		    ret = 0;
	    break;

    case LMCIOCCLEARLMCSTATS:
	    if (!capable(CAP_NET_ADMIN)) {
		    ret = -EPERM;
		    break;
	    }

	    spin_lock_irqsave(&sc->lmc_lock, flags);
	    memset(&sc->lmc_device->stats, 0, sizeof(sc->lmc_device->stats));
	    memset(&sc->extra_stats, 0, sizeof(sc->extra_stats));
	    sc->extra_stats.check = STATCHECK;
	    sc->extra_stats.version_size = (DRIVER_VERSION << 16) +
		    sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats);
	    sc->extra_stats.lmc_cardtype = sc->lmc_cardtype;
	    spin_unlock_irqrestore(&sc->lmc_lock, flags);
	    ret = 0;
	    break;

    case LMCIOCSETCIRCUIT: 
        if (!capable(CAP_NET_ADMIN)){
            ret = -EPERM;
            break;
        }

        if(dev->flags & IFF_UP){
            ret = -EBUSY;
            break;
        }

	if (copy_from_user(&ctl, ifr->ifr_data, sizeof(lmc_ctl_t))) {
		ret = -EFAULT;
		break;
	}
	spin_lock_irqsave(&sc->lmc_lock, flags);
        sc->lmc_media->set_circuit_type(sc, ctl.circuit_type);
        sc->ictl.circuit_type = ctl.circuit_type;
	spin_unlock_irqrestore(&sc->lmc_lock, flags);
        ret = 0;

        break;

    case LMCIOCRESET: 
        if (!capable(CAP_NET_ADMIN)){
            ret = -EPERM;
            break;
        }

	spin_lock_irqsave(&sc->lmc_lock, flags);
        
        printk (" REG16 before reset +%04x\n", lmc_mii_readreg (sc, 0, 16));
        lmc_running_reset (dev);
        printk (" REG16 after reset +%04x\n", lmc_mii_readreg (sc, 0, 16));

        LMC_EVENT_LOG(LMC_EVENT_FORCEDRESET, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16));
	spin_unlock_irqrestore(&sc->lmc_lock, flags);

        ret = 0;
        break;

#ifdef DEBUG
    case LMCIOCDUMPEVENTLOG:
	if (copy_to_user(ifr->ifr_data, &lmcEventLogIndex, sizeof(u32))) {
		ret = -EFAULT;
		break;
	}
	if (copy_to_user(ifr->ifr_data + sizeof(u32), lmcEventLogBuf,
			 sizeof(lmcEventLogBuf)))
		ret = -EFAULT;
	else
		ret = 0;

        break;
#endif 
    case LMCIOCT1CONTROL: 
        if (sc->lmc_cardtype != LMC_CARDTYPE_T1){
            ret = -EOPNOTSUPP;
            break;
        }
        break;
    case LMCIOCXILINX: 
        {
            struct lmc_xilinx_control xc; 

            if (!capable(CAP_NET_ADMIN)){
                ret = -EPERM;
                break;
            }

            netif_stop_queue(dev);

	    if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) {
		ret = -EFAULT;
		break;
	    }
            switch(xc.command){
            case lmc_xilinx_reset: 
                {
                    u16 mii;
		    spin_lock_irqsave(&sc->lmc_lock, flags);
                    mii = lmc_mii_readreg (sc, 0, 16);

                    lmc_gpio_mkinput(sc, 0xff);

                    lmc_gpio_mkoutput(sc, LMC_GEP_RESET);


                    sc->lmc_gpio &= ~LMC_GEP_RESET;
                    LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);


                    udelay(50);

                    sc->lmc_gpio |= LMC_GEP_RESET;
                    LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);


                    lmc_gpio_mkinput(sc, 0xff);

                    
                    sc->lmc_media->set_link_status (sc, 1);
                    sc->lmc_media->set_status (sc, NULL);

                    {
                        int i;
                        for(i = 0; i < 5; i++){
                            lmc_led_on(sc, LMC_DS3_LED0);
                            mdelay(100);
                            lmc_led_off(sc, LMC_DS3_LED0);
                            lmc_led_on(sc, LMC_DS3_LED1);
                            mdelay(100);
                            lmc_led_off(sc, LMC_DS3_LED1);
                            lmc_led_on(sc, LMC_DS3_LED3);
                            mdelay(100);
                            lmc_led_off(sc, LMC_DS3_LED3);
                            lmc_led_on(sc, LMC_DS3_LED2);
                            mdelay(100);
                            lmc_led_off(sc, LMC_DS3_LED2);
                        }
                    }
		    spin_unlock_irqrestore(&sc->lmc_lock, flags);
                    
                    

                    ret = 0x0;

                }

                break;
            case lmc_xilinx_load_prom: 
                {
                    u16 mii;
                    int timeout = 500000;
		    spin_lock_irqsave(&sc->lmc_lock, flags);
                    mii = lmc_mii_readreg (sc, 0, 16);

                    lmc_gpio_mkinput(sc, 0xff);

                    lmc_gpio_mkoutput(sc,  LMC_GEP_DP | LMC_GEP_RESET);


                    sc->lmc_gpio &= ~(LMC_GEP_RESET | LMC_GEP_DP);
                    LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);


                    udelay(50);

                    sc->lmc_gpio |= LMC_GEP_DP | LMC_GEP_RESET;
                    LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);

                    while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 &&
                           (timeout-- > 0))
                        cpu_relax();


                    lmc_gpio_mkinput(sc, 0xff);
		    spin_unlock_irqrestore(&sc->lmc_lock, flags);

                    ret = 0x0;
                    

                    break;

                }

            case lmc_xilinx_load: 
                {
                    char *data;
                    int pos;
                    int timeout = 500000;

                    if (!xc.data) {
                            ret = -EINVAL;
                            break;
                    }

                    data = kmalloc(xc.len, GFP_KERNEL);
                    if (!data) {
                            ret = -ENOMEM;
                            break;
                    }
                    
                    if(copy_from_user(data, xc.data, xc.len))
                    {
                    	kfree(data);
                    	ret = -ENOMEM;
                    	break;
                    }

                    printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data);

		    spin_lock_irqsave(&sc->lmc_lock, flags);
                    lmc_gpio_mkinput(sc, 0xff);


                    sc->lmc_gpio = 0x00;
                    sc->lmc_gpio &= ~LMC_GEP_DP;
                    sc->lmc_gpio &= ~LMC_GEP_RESET;
                    sc->lmc_gpio |=  LMC_GEP_MODE;
                    LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);

                    lmc_gpio_mkoutput(sc, LMC_GEP_MODE | LMC_GEP_DP | LMC_GEP_RESET);

                    udelay(50);

                    lmc_gpio_mkinput(sc, LMC_GEP_DP | LMC_GEP_RESET);

                    sc->lmc_gpio = 0x00;
                    sc->lmc_gpio |= LMC_GEP_MODE;
                    sc->lmc_gpio |= LMC_GEP_DATA;
                    sc->lmc_gpio |= LMC_GEP_CLK;
                    LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
                    
                    lmc_gpio_mkoutput(sc, LMC_GEP_DATA | LMC_GEP_CLK | LMC_GEP_MODE );

                    while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 &&
                           (timeout-- > 0))
                        cpu_relax();

                    printk(KERN_DEBUG "%s: Waited %d for the Xilinx to clear it's memory\n", dev->name, 500000-timeout);

                    for(pos = 0; pos < xc.len; pos++){
                        switch(data[pos]){
                        case 0:
                            sc->lmc_gpio &= ~LMC_GEP_DATA; 
                            break;
                        case 1:
                            sc->lmc_gpio |= LMC_GEP_DATA; 
                            break;
                        default:
                            printk(KERN_WARNING "%s Bad data in xilinx programming data at %d, got %d wanted 0 or 1\n", dev->name, pos, data[pos]);
                            sc->lmc_gpio |= LMC_GEP_DATA; 
                        }
                        sc->lmc_gpio &= ~LMC_GEP_CLK; 
                        sc->lmc_gpio |= LMC_GEP_MODE;
                        LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
                        udelay(1);
                        
                        sc->lmc_gpio |= LMC_GEP_CLK; 
                        sc->lmc_gpio |= LMC_GEP_MODE;
                        LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
                        udelay(1);
                    }
                    if((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0){
                        printk(KERN_WARNING "%s: Reprogramming FAILED. Needs to be reprogrammed. (corrupted data)\n", dev->name);
                    }
                    else if((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0){
                        printk(KERN_WARNING "%s: Reprogramming FAILED. Needs to be reprogrammed. (done)\n", dev->name);
                    }
                    else {
                        printk(KERN_DEBUG "%s: Done reprogramming Xilinx, %d bits, good luck!\n", dev->name, pos);
                    }

                    lmc_gpio_mkinput(sc, 0xff);
                    
                    sc->lmc_miireg16 |= LMC_MII16_FIFO_RESET;
                    lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);

                    sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET;
                    lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
		    spin_unlock_irqrestore(&sc->lmc_lock, flags);

                    kfree(data);
                    
                    ret = 0;
                    
                    break;
                }
            default: 
                ret = -EBADE;
                break;
            }

            netif_wake_queue(dev);
            sc->lmc_txfull = 0;

        }
        break;
    default: 
        
        ret = lmc_proto_ioctl (sc, ifr, cmd);
        break;
    }
Beispiel #6
0
static int
lmc_t1_get_link_status(lmc_softc_t * const sc){
	u_int16_t link_status;
	lmc_mii_writereg(sc, 0, 17, T1FRAMER_ALARM1_STATUS );
	link_status = lmc_mii_readreg(sc, 0, 18);

        /*
	 * LMC 1200 LED definitions
         * led0 yellow = far-end adapter is in Red alarm condition
  	 * led1 blue = received an Alarm Indication signal (upstream failure)
         * led2 Green = power to adapter, Gate Array loaded & driver attached
         * led3 red = Loss of Signal (LOS) or out of frame (OOF) conditions
	 * detected on T3 receive signal
         */

        /* detect a change in Blue alarm indication signal */

        if( (sc->t1_alarm1_status & T1F_RAIS) != (link_status & T1F_RAIS) )
        {
                if( link_status & T1F_RAIS )
                {                        /* turn on blue LED */
                        printf("%s: link status: RAIS turn ON Blue %x\n", sc->lmc_xname, link_status); /* DEBUG */
                        lmc_led_on(sc, LMC_DS3_LED1);
                }
                else
                {                        /* turn off blue LED */
                        printf("%s: link status: RAIS turn OFF Blue %x\n", sc->lmc_xname, link_status ); /* DEBUG */
			lmc_led_off(sc, LMC_DS3_LED1);
                }       
	}
        /*
	 * T1F_RYEL wiggles quite a bit,
	 *  taking it out until I understand why -baz 6/22/99
         */
                /* Yellow alarm indication */
                if( (sc->t1_alarm1_status &  T1F_RMYEL) !=
                        (link_status & T1F_RMYEL) )
                {
		if( (link_status & (T1F_RYEL | T1F_RMYEL)) == 0 )
                        {
				/* turn off yellow LED */
       		                printf("%s: link status: RYEL turn OFF Yellow %x\n", sc->lmc_xname, link_status); /* DEBUG */
                    	        lmc_led_off(sc, LMC_DS3_LED0);

                        }
                        else
                        {
                                /* turn on yellow LED */                         
                                printf("%s: link status: RYEL turn ON Yellow %x\n", sc->lmc_xname, link_status); /* DEBUG */
                                lmc_led_on(sc, LMC_DS3_LED0);
                        }
                }


        sc->t1_alarm1_status = link_status;

        lmc_mii_writereg(sc, 0, 17, T1FRAMER_ALARM2_STATUS );
        sc->t1_alarm2_status = lmc_mii_readreg(sc, 0, 18);

        /* link status based upon T1 receive loss of frame or
         * loss of signal - RED alarm indication */
        if ((link_status & (T1F_RLOF | T1F_RLOS)) == 0)
                return 1;
        else
                return 0;
}
Beispiel #7
0
void
lmc_dec_reset(lmc_softc_t * const sc)
{
#ifndef __linux__
	lmc_ringinfo_t *ri;
	lmc_desc_t *di;
#endif
	u_int32_t val;

	/*
	 * disable all interrupts
	 */
	sc->lmc_intrmask = 0;
	LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask);

	/*
	 * we are, obviously, down.
	 */
#ifndef __linux__
	sc->lmc_flags &= ~(LMC_IFUP | LMC_MODEMOK);

	DP(("lmc_dec_reset\n"));
#endif

	/*
	 * Reset the chip with a software reset command.
	 * Wait 10 microseconds (actually 50 PCI cycles but at 
	 * 33MHz that comes to two microseconds but wait a
	 * bit longer anyways)
	 */
	LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
	DELAY(10);
	sc->lmc_cmdmode = LMC_CSR_READ(sc, csr_command);

	/*
	 * We want:
	 *   no ethernet address in frames we write
	 *   disable padding (txdesc, padding disable)
	 *   ignore runt frames (rdes0 bit 15)
	 *   no receiver watchdog or transmitter jabber timer
	 *       (csr15 bit 0,14 == 1)
	 *   if using 16-bit CRC, turn off CRC (trans desc, crc disable)
	 */

#ifndef TULIP_CMD_RECEIVEALL
#define TULIP_CMD_RECEIVEALL 0x40000000L
#endif

	sc->lmc_cmdmode |= ( TULIP_CMD_PROMISCUOUS
			       | TULIP_CMD_FULLDUPLEX
			       | TULIP_CMD_PASSBADPKT
			       | TULIP_CMD_NOHEARTBEAT
			       | TULIP_CMD_PORTSELECT
			       | TULIP_CMD_RECEIVEALL
			       | TULIP_CMD_MUSTBEONE
			       );
	sc->lmc_cmdmode &= ~( TULIP_CMD_OPERMODE
				| TULIP_CMD_THRESHOLDCTL
				| TULIP_CMD_STOREFWD
				| TULIP_CMD_TXTHRSHLDCTL
				);

	LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);

	/*
	 * disable receiver watchdog and transmit jabber
	 */
	val = LMC_CSR_READ(sc, csr_sia_general);
	val |= (TULIP_WATCHDOG_TXDISABLE | TULIP_WATCHDOG_RXDISABLE);
	LMC_CSR_WRITE(sc, csr_sia_general, val);

	/*
	 * turn off those LEDs...
	 */
	sc->lmc_miireg16 |= LMC_MII16_LED_ALL;
	lmc_led_on(sc, LMC_MII16_LED0);

#ifndef __linux__
	/*
	 * reprogram the tx desc, rx desc, and PCI bus options
	 */
	LMC_CSR_WRITE(sc, csr_txlist, sc->lmc_txdescmap->dm_segs[0].ds_addr);
	LMC_CSR_WRITE(sc, csr_rxlist, sc->lmc_rxdescmap->dm_segs[0].ds_addr);
	LMC_CSR_WRITE(sc, csr_busmode,
		(1 << (LMC_BURSTSIZE(sc->lmc_unit) + 8))
		|TULIP_BUSMODE_CACHE_ALIGN8
		|TULIP_BUSMODE_READMULTIPLE);

	sc->lmc_txq.ifq_maxlen = LMC_TXDESCS;

	/*
	 * Free all the mbufs that were on the transmit ring.
	 */
	for (;;) {
		bus_dmamap_t map;
		struct mbuf *m;

		IF_DEQUEUE(&sc->lmc_txq, m);
		if (m == NULL)
			break;
		map = LMC_GETCTX(m, bus_dmamap_t);
		bus_dmamap_unload(sc->lmc_dmatag, map);
		sc->lmc_txmaps[sc->lmc_txmaps_free++] = map;
		m_freem(m);
	}

	/*
	 * reset descriptor state and reclaim all descriptors.
	 */
	ri = &sc->lmc_txinfo;
	ri->ri_nextin = ri->ri_nextout = ri->ri_first;
	ri->ri_free = ri->ri_max;
	for (di = ri->ri_first; di < ri->ri_last; di++)
		di->d_status = 0;
	bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_txdescmap,
		0, sc->lmc_txdescmap->dm_mapsize,
		BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);

	/*
	 * We need to collect all the mbufs were on the 
	 * receive ring before we reinit it either to put
	 * them back on or to know if we have to allocate
	 * more.
	 */
	ri = &sc->lmc_rxinfo;
	ri->ri_nextin = ri->ri_nextout = ri->ri_first;
	ri->ri_free = ri->ri_max;
	for (di = ri->ri_first; di < ri->ri_last; di++) {
		u_int32_t ctl = di->d_ctl;
		di->d_status = 0;
		di->d_ctl = LMC_CTL(LMC_CTL_FLGS(ctl),0,0);
		di->d_addr1 = 0;
		di->d_addr2 = 0;
	}
	bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_rxdescmap,
		0, sc->lmc_rxdescmap->dm_mapsize,
		BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
	for (;;) {
		bus_dmamap_t map;
		struct mbuf *m;
		IF_DEQUEUE(&sc->lmc_rxq, m);
		if (m == NULL)
			break;
		map = LMC_GETCTX(m, bus_dmamap_t);
		bus_dmamap_unload(sc->lmc_dmatag, map);
		sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
		m_freem(m);
	}
#endif
}