Exemple #1
0
/* on each timer ticks we check two things, Link Status (ON/OFF) and 
   Link Mode (10/100/Full/Half)
 */
static void sis900_timer(unsigned long data)
{
        struct device *net_dev = (struct device *)data;
        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
	struct mii_phy *mii_phy = sis_priv->mii;
        static int next_tick = 5*HZ;
        u16 status;

	status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);

	/* current mii phy is failed to link, try another one */
	while (!(status & MII_STAT_LINK)) {		
		if (mii_phy->next == NULL) { 
			if (sis_priv->LinkOn) {
				/* link stat change from ON to OFF */
				next_tick = HZ;
				sis_priv->LinkOn = FALSE;
				printk(KERN_INFO "%s: Media Link Off\n",
				       net_dev->name);
			}
			sis_priv->timer.expires = jiffies + next_tick;
			add_timer(&sis_priv->timer);
			return;
		}
		mii_phy = mii_phy->next;
		status = mdio_read(net_dev, mii_phy->phy_addr, MII_STATUS);
	}

	if (!sis_priv->LinkOn) {
		/* link stat change forn OFF to ON, read and report link mode */
		sis_priv->LinkOn = TRUE;
		next_tick = 5*HZ;
		/* change what cur_phy means */
		if (mii_phy->phy_addr != sis_priv->cur_phy) {
			printk(KERN_INFO "%s: Changing transceiver to %s\n", net_dev->name,
			       mii_phy->chip_info->name);
			status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
			mdio_write(net_dev, sis_priv->cur_phy, 
				   MII_CONTROL, status | MII_CNTL_ISOLATE);
			status = mdio_read(net_dev, mii_phy->phy_addr, MII_CONTROL);
			mdio_write(net_dev, mii_phy->phy_addr, 
				   MII_CONTROL, status & ~MII_CNTL_ISOLATE);
			sis_priv->cur_phy = mii_phy->phy_addr;
		}
		sis900_check_mode(net_dev, mii_phy);
	}

	sis_priv->timer.expires = jiffies + next_tick;
	add_timer(&sis_priv->timer);
}
Exemple #2
0
static void
sis900_init(struct nic *nic)
{
    
    sis900_reset(nic);

    sis900_init_rxfilter(nic);

    sis900_init_txd(nic);
    sis900_init_rxd(nic);

    sis900_set_rx_mode(nic);

    sis900_check_mode(nic);

    outl(RxENA, ioaddr + cr);
}
Exemple #3
0
static int
sis900_open(struct device *net_dev)
{
        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        long ioaddr = net_dev->base_addr;

        /* Soft reset the chip. */
	sis900_reset(net_dev);

        if (request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ, net_dev->name, net_dev)) {
                return -EAGAIN;
        }

        MOD_INC_USE_COUNT;

	sis900_init_rxfilter(net_dev);

	sis900_init_tx_ring(net_dev);
	sis900_init_rx_ring(net_dev);

        set_rx_mode(net_dev);

        net_dev->tbusy = 0;
        net_dev->interrupt = 0;
        net_dev->start = 1;

        /* Enable all known interrupts by setting the interrupt mask. */
	outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
        outl(RxENA, ioaddr + cr);
        outl(IE, ioaddr + ier);

	sis900_check_mode(net_dev, sis_priv->mii);

        /* Set the timer to switch to check for link beat and perhaps switch
           to an alternate media type. */
        init_timer(&sis_priv->timer);
        sis_priv->timer.expires = jiffies + HZ;
        sis_priv->timer.data = (unsigned long)net_dev;
        sis_priv->timer.function = &sis900_timer;
        add_timer(&sis_priv->timer);

        return 0;
}