patch-2.4.23 linux-2.4.23/drivers/net/sis900.c

Next file: linux-2.4.23/drivers/net/sk98lin/Makefile
Previous file: linux-2.4.23/drivers/net/seeq8005.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.22/drivers/net/sis900.c linux-2.4.23/drivers/net/sis900.c
@@ -98,7 +98,7 @@
 	"SiS 900 PCI Fast Ethernet",
 	"SiS 7016 PCI Fast Ethernet"
 };
-static struct pci_device_id sis900_pci_tbl [] __devinitdata = {
+static struct pci_device_id sis900_pci_tbl [] = {
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_900,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_900},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7016,
@@ -170,6 +170,7 @@
 	dma_addr_t rx_ring_dma;
 
 	unsigned int tx_full;			/* The Tx queue is full.    */
+	u8 host_bridge_rev;
 };
 
 MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>, Ollie Lho <ollie@sis.com.tw>");
@@ -197,7 +198,7 @@
 static int sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
 static int sis900_rx(struct net_device *net_dev);
 static void sis900_finish_xmit (struct net_device *net_dev);
-static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 static int sis900_close(struct net_device *net_dev);
 static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd);
 static struct net_device_stats *sis900_get_stats(struct net_device *net_dev);
@@ -211,6 +212,7 @@
 static u16 sis900_reset_phy(struct net_device *net_dev, int phy_addr);
 static void sis900_auto_negotiate(struct net_device *net_dev, int phy_addr);
 static void sis900_set_mode (long ioaddr, int speed, int duplex);
+static struct ethtool_ops sis900_ethtool_ops;
 
 /**
  *	sis900_get_mac_addr - Get MAC address for stand alone SiS900 model
@@ -368,6 +370,7 @@
 {
 	struct sis900_private *sis_priv;
 	struct net_device *net_dev;
+	struct pci_dev *dev;
 	dma_addr_t ring_dma;
 	void *ring_space;
 	long ioaddr;
@@ -440,6 +443,7 @@
 	net_dev->do_ioctl = &mii_ioctl;
 	net_dev->tx_timeout = sis900_tx_timeout;
 	net_dev->watchdog_timeo = TX_TIMEOUT;
+	net_dev->ethtool_ops = &sis900_ethtool_ops;
 	
 	ret = register_netdev(net_dev);
 	if (ret)
@@ -473,6 +477,11 @@
 		goto err_out_unregister;
 	}
 
+	/* save our host bridge revision */
+	dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, NULL);
+	if (dev)
+		pci_read_config_byte(dev, PCI_CLASS_REVISION, &sis_priv->host_bridge_rev);
+
 	/* print some information about our NIC */
 	printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name,
 	       card_name, ioaddr, net_dev->irq);
@@ -1108,18 +1117,12 @@
 {
 	struct sis900_private *sis_priv = net_dev->priv;
 	u16 reg14h, eq_value=0, max_value=0, min_value=0;
-	u8 host_bridge_rev;
 	int i, maxcount=10;
-	struct pci_dev *dev=NULL;
 
 	if ( !(revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
 	       revision == SIS630A_900_REV || revision ==  SIS630ET_900_REV) )
 		return;
 
-	dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, dev);
-	if (dev)
-		pci_read_config_byte(dev, PCI_CLASS_REVISION, &host_bridge_rev);
-
 	if (netif_carrier_ok(net_dev)) {
 		reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
 		mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (0x2200 | reg14h) & 0xBFFF);
@@ -1142,7 +1145,8 @@
 		}
 		/* 630B0&B1 rule to determine the equalizer value */
 		if (revision == SIS630A_900_REV && 
-		    (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1)) {
+		    (sis_priv->host_bridge_rev == SIS630B0 || 
+		     sis_priv->host_bridge_rev == SIS630B1)) {
 			if (max_value == 0)
 				eq_value=3;
 			else
@@ -1157,7 +1161,8 @@
 	else {
 		reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
 		if (revision == SIS630A_900_REV && 
-		    (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1)) 
+		    (sis_priv->host_bridge_rev == SIS630B0 || 
+		     sis_priv->host_bridge_rev == SIS630B1)) 
 			mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2200) & 0xBFFF);
 		else
 			mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2000) & 0xBFFF);
@@ -1434,7 +1439,7 @@
 			pci_unmap_single(sis_priv->pci_dev, 
 				sis_priv->tx_ring[i].bufptr, skb->len,
 				PCI_DMA_TODEVICE);
-			dev_kfree_skb(skb);
+			dev_kfree_skb_irq(skb);
 			sis_priv->tx_skbuff[i] = 0;
 			sis_priv->tx_ring[i].cmdsts = 0;
 			sis_priv->tx_ring[i].bufptr = 0;
@@ -1536,13 +1541,14 @@
  *	and cleans up after the Tx thread
  */
 
-static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 {
 	struct net_device *net_dev = dev_instance;
 	struct sis900_private *sis_priv = net_dev->priv;
 	int boguscnt = max_interrupt_work;
 	long ioaddr = net_dev->base_addr;
 	u32 status;
+	unsigned int handled = 0;
 
 	spin_lock (&sis_priv->lock);
 
@@ -1552,6 +1558,7 @@
 		if ((status & (HIBERR|TxURN|TxERR|TxIDLE|RxORN|RxERR|RxOK)) == 0)
 			/* nothing intresting happened */
 			break;
+		handled = 1;
 
 		/* why dow't we break after Tx/Rx case ?? keyword: full-duplex */
 		if (status & (RxORN | RxERR | RxOK))
@@ -1582,7 +1589,7 @@
 		       net_dev->name, inl(ioaddr + isr));
 	
 	spin_unlock (&sis_priv->lock);
-	return;
+	return IRQ_RETVAL(handled);
 }
 
 /**
@@ -1851,39 +1858,27 @@
 }
 
 /**
- *	netdev_ethtool_ioctl - For the basic support of ethtool
- *	@net_dev: the net device to command for
- *	@useraddr: start address of interface request
+ *	sis900_get_drvinfo - Return information about driver
+ *	@net_dev: the net device to probe
+ *	@info: container for info returned
  *
  *	Process ethtool command such as "ehtool -i" to show information
  */
-
-static int netdev_ethtool_ioctl (struct net_device *net_dev, void *useraddr)
+ 
+static void sis900_get_drvinfo(struct net_device *net_dev,
+			       struct ethtool_drvinfo *info)
 {
  	struct sis900_private *sis_priv = net_dev->priv;
- 	u32 ethcmd;
-
-	if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
-		return -EFAULT;
-	
-	switch (ethcmd) {
-	case ETHTOOL_GDRVINFO:
-		{
-			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-			strcpy (info.driver, SIS900_MODULE_NAME);
-			strcpy (info.version, SIS900_DRV_VERSION);
-			strcpy (info.bus_info, sis_priv->pci_dev->slot_name);
-			if (copy_to_user (useraddr, &info, sizeof (info)))
-				return -EFAULT;
-			return 0;
-		}
-	default:
-		break;
-	}
 
-	return -EOPNOTSUPP;
+	strcpy (info->driver, SIS900_MODULE_NAME);
+	strcpy (info->version, SIS900_DRV_VERSION);
+	strcpy (info->bus_info, pci_name(sis_priv->pci_dev));
 }
 
+static struct ethtool_ops sis900_ethtool_ops = {
+	.get_drvinfo =		sis900_get_drvinfo,
+};
+
 /**
  *	mii_ioctl - process MII i/o control command 
  *	@net_dev: the net device to command for
@@ -1899,9 +1894,6 @@
 	struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
 
 	switch(cmd) {
-	case SIOCETHTOOL:
-		return netdev_ethtool_ioctl(net_dev, (void *) rq->ifr_data);
-
 	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
 	case SIOCDEVPRIVATE:		/* for binary compat, remove in 2.5 */
 		data->phy_id = sis_priv->mii->phy_addr;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)