diff options
Diffstat (limited to 'drivers/net/ethernet/sis/sis900.c')
| -rw-r--r-- | drivers/net/ethernet/sis/sis900.c | 136 |
1 files changed, 66 insertions, 70 deletions
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index 203d9c6ec23..6072f093e6b 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -81,7 +81,7 @@ #define SIS900_MODULE_NAME "sis900" #define SIS900_DRV_VERSION "v1.08.10 Apr. 2 2006" -static const char version[] __devinitconst = +static const char version[] = KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n"; static int max_interrupt_work = 40; @@ -247,11 +247,11 @@ static const struct ethtool_ops sis900_ethtool_ops; * @net_dev: the net device to get address for * * Older SiS900 and friends, use EEPROM to store MAC address. - * MAC address is read from read_eeprom() into @net_dev->dev_addr and - * @net_dev->perm_addr. + * MAC address is read from read_eeprom() into @net_dev->dev_addr. */ -static int __devinit sis900_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev) +static int sis900_get_mac_addr(struct pci_dev *pci_dev, + struct net_device *net_dev) { struct sis900_private *sis_priv = netdev_priv(net_dev); void __iomem *ioaddr = sis_priv->ioaddr; @@ -270,9 +270,6 @@ static int __devinit sis900_get_mac_addr(struct pci_dev * pci_dev, struct net_de for (i = 0; i < 3; i++) ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr); - /* Store MAC Address in perm_addr */ - memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN); - return 1; } @@ -283,12 +280,11 @@ static int __devinit sis900_get_mac_addr(struct pci_dev * pci_dev, struct net_de * * SiS630E model, use APC CMOS RAM to store MAC address. * APC CMOS RAM is accessed through ISA bridge. - * MAC address is read into @net_dev->dev_addr and - * @net_dev->perm_addr. + * MAC address is read into @net_dev->dev_addr. */ -static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev, - struct net_device *net_dev) +static int sis630e_get_mac_addr(struct pci_dev *pci_dev, + struct net_device *net_dev) { struct pci_dev *isa_bridge = NULL; u8 reg; @@ -310,9 +306,6 @@ static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev, ((u8 *)(net_dev->dev_addr))[i] = inb(0x71); } - /* Store MAC Address in perm_addr */ - memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN); - pci_write_config_byte(isa_bridge, 0x48, reg & ~0x40); pci_dev_put(isa_bridge); @@ -327,11 +320,11 @@ static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev, * * SiS635 model, set MAC Reload Bit to load Mac address from APC * to rfdr. rfdr is accessed through rfcr. MAC address is read into - * @net_dev->dev_addr and @net_dev->perm_addr. + * @net_dev->dev_addr. */ -static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev, - struct net_device *net_dev) +static int sis635_get_mac_addr(struct pci_dev *pci_dev, + struct net_device *net_dev) { struct sis900_private *sis_priv = netdev_priv(net_dev); void __iomem *ioaddr = sis_priv->ioaddr; @@ -352,9 +345,6 @@ static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev, *( ((u16 *)net_dev->dev_addr) + i) = sr16(rfdr); } - /* Store MAC Address in perm_addr */ - memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN); - /* enable packet filtering */ sw32(rfcr, rfcrSave | RFEN); @@ -374,11 +364,11 @@ static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev, * EEDONE signal to refuse EEPROM access by LAN. * The EEPROM map of SiS962 or SiS963 is different to SiS900. * The signature field in SiS962 or SiS963 spec is meaningless. - * MAC address is read into @net_dev->dev_addr and @net_dev->perm_addr. + * MAC address is read into @net_dev->dev_addr. */ -static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev, - struct net_device *net_dev) +static int sis96x_get_mac_addr(struct pci_dev *pci_dev, + struct net_device *net_dev) { struct sis900_private *sis_priv = netdev_priv(net_dev); void __iomem *ioaddr = sis_priv->ioaddr; @@ -394,9 +384,6 @@ static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev, for (i = 0; i < 3; i++) mac[i] = read_eeprom(ioaddr, i + EEPROMMACAddr); - /* Store MAC Address in perm_addr */ - memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN); - rc = 1; break; } @@ -433,8 +420,8 @@ static const struct net_device_ops sis900_netdev_ops = { * ie: sis900_open(), sis900_start_xmit(), sis900_close(), etc. */ -static int __devinit sis900_probe(struct pci_dev *pci_dev, - const struct pci_device_id *pci_id) +static int sis900_probe(struct pci_dev *pci_dev, + const struct pci_device_id *pci_id) { struct sis900_private *sis_priv; struct net_device *net_dev; @@ -478,8 +465,10 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, /* IO region. */ ioaddr = pci_iomap(pci_dev, 0, 0); - if (!ioaddr) + if (!ioaddr) { + ret = -ENOMEM; goto err_out_cleardev; + } sis_priv = netdev_priv(net_dev); sis_priv->ioaddr = ioaddr; @@ -587,7 +576,6 @@ err_unmap_tx: err_out_unmap: pci_iounmap(pci_dev, ioaddr); err_out_cleardev: - pci_set_drvdata(pci_dev, NULL); pci_release_regions(pci_dev); err_out: free_netdev(net_dev); @@ -603,7 +591,7 @@ err_out_cleardev: * return error if it failed to found. */ -static int __devinit sis900_mii_probe(struct net_device * net_dev) +static int sis900_mii_probe(struct net_device *net_dev) { struct sis900_private *sis_priv = netdev_priv(net_dev); const char *dev_name = pci_name(sis_priv->pci_dev); @@ -822,7 +810,7 @@ static void sis900_set_capability(struct net_device *net_dev, struct mii_phy *ph * Note that location is in word (16 bits) unit */ -static u16 __devinit read_eeprom(void __iomem *ioaddr, int location) +static u16 read_eeprom(void __iomem *ioaddr, int location) { u32 read_cmd = location | EEread; int i; @@ -1198,8 +1186,14 @@ sis900_init_rx_ring(struct net_device *net_dev) } sis_priv->rx_skbuff[i] = skb; sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE; - sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev, - skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev, + skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + if (unlikely(pci_dma_mapping_error(sis_priv->pci_dev, + sis_priv->rx_ring[i].bufptr))) { + dev_kfree_skb(skb); + sis_priv->rx_skbuff[i] = NULL; + break; + } } sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC); @@ -1314,23 +1308,9 @@ static void sis900_timer(unsigned long data) struct sis900_private *sis_priv = netdev_priv(net_dev); struct mii_phy *mii_phy = sis_priv->mii; static const int next_tick = 5*HZ; + int speed = 0, duplex = 0; u16 status; - if (!sis_priv->autong_complete){ - int uninitialized_var(speed), duplex = 0; - - sis900_read_mode(net_dev, &speed, &duplex); - if (duplex){ - sis900_set_mode(sis_priv, speed, duplex); - sis630_set_eq(net_dev, sis_priv->chipset_rev); - netif_start_queue(net_dev); - } - - sis_priv->timer.expires = jiffies + HZ; - add_timer(&sis_priv->timer); - return; - } - status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS); status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS); @@ -1341,9 +1321,15 @@ static void sis900_timer(unsigned long data) status = sis900_default_phy(net_dev); mii_phy = sis_priv->mii; - if (status & MII_STAT_LINK){ - sis900_check_mode(net_dev, mii_phy); - netif_carrier_on(net_dev); + if (status & MII_STAT_LINK) { + WARN_ON(!(status & MII_STAT_AUTO_DONE)); + + sis900_read_mode(net_dev, &speed, &duplex); + if (duplex) { + sis900_set_mode(sis_priv, speed, duplex); + sis630_set_eq(net_dev, sis_priv->chipset_rev); + netif_carrier_on(net_dev); + } } } else { /* Link ON -> OFF */ @@ -1617,12 +1603,6 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev) unsigned int index_cur_tx, index_dirty_tx; unsigned int count_dirty_tx; - /* Don't transmit data before the complete of auto-negotiation */ - if(!sis_priv->autong_complete){ - netif_stop_queue(net_dev); - return NETDEV_TX_BUSY; - } - spin_lock_irqsave(&sis_priv->lock, flags); /* Calculate the next Tx descriptor entry. */ @@ -1632,6 +1612,14 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev) /* set the transmit buffer descriptor and enable Transmit State Machine */ sis_priv->tx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); + if (unlikely(pci_dma_mapping_error(sis_priv->pci_dev, + sis_priv->tx_ring[entry].bufptr))) { + dev_kfree_skb_any(skb); + sis_priv->tx_skbuff[entry] = NULL; + net_dev->stats.tx_dropped++; + spin_unlock_irqrestore(&sis_priv->lock, flags); + return NETDEV_TX_OK; + } sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len); sw32(cr, TxENA | sr32(cr)); @@ -1720,7 +1708,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance) if(netif_msg_intr(sis_priv)) printk(KERN_DEBUG "%s: exiting interrupt, " - "interrupt status = 0x%#8.8x.\n", + "interrupt status = %#8.8x\n", net_dev->name, sr32(isr)); spin_unlock (&sis_priv->lock); @@ -1835,9 +1823,15 @@ static int sis900_rx(struct net_device *net_dev) refill_rx_ring: sis_priv->rx_skbuff[entry] = skb; sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; - sis_priv->rx_ring[entry].bufptr = + sis_priv->rx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + if (unlikely(pci_dma_mapping_error(sis_priv->pci_dev, + sis_priv->rx_ring[entry].bufptr))) { + dev_kfree_skb_irq(skb); + sis_priv->rx_skbuff[entry] = NULL; + break; + } } sis_priv->cur_rx++; entry = sis_priv->cur_rx % NUM_RX_DESC; @@ -1852,23 +1846,26 @@ refill_rx_ring: entry = sis_priv->dirty_rx % NUM_RX_DESC; if (sis_priv->rx_skbuff[entry] == NULL) { - if ((skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE)) == NULL) { + skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE); + if (skb == NULL) { /* not enough memory for skbuff, this makes a * "hole" on the buffer ring, it is not clear * how the hardware will react to this kind * of degenerated buffer */ - if (netif_msg_rx_err(sis_priv)) - printk(KERN_INFO "%s: Memory squeeze, " - "deferring packet.\n", - net_dev->name); net_dev->stats.rx_dropped++; break; } sis_priv->rx_skbuff[entry] = skb; sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; - sis_priv->rx_ring[entry].bufptr = + sis_priv->rx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + if (unlikely(pci_dma_mapping_error(sis_priv->pci_dev, + sis_priv->rx_ring[entry].bufptr))) { + dev_kfree_skb_irq(skb); + sis_priv->rx_skbuff[entry] = NULL; + break; + } } } /* re-enable the potentially idle receive state matchine */ @@ -2408,7 +2405,7 @@ static void sis900_reset(struct net_device *net_dev) * remove and release SiS900 net device */ -static void __devexit sis900_remove(struct pci_dev *pci_dev) +static void sis900_remove(struct pci_dev *pci_dev) { struct net_device *net_dev = pci_get_drvdata(pci_dev); struct sis900_private *sis_priv = netdev_priv(net_dev); @@ -2429,7 +2426,6 @@ static void __devexit sis900_remove(struct pci_dev *pci_dev) pci_iounmap(pci_dev, sis_priv->ioaddr); free_netdev(net_dev); pci_release_regions(pci_dev); - pci_set_drvdata(pci_dev, NULL); } #ifdef CONFIG_PM @@ -2477,7 +2473,7 @@ static int sis900_resume(struct pci_dev *pci_dev) netif_start_queue(net_dev); /* Workaround for EDB */ - sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); + sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); /* Enable all known interrupts by setting the interrupt mask. */ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); @@ -2494,7 +2490,7 @@ static struct pci_driver sis900_pci_driver = { .name = SIS900_MODULE_NAME, .id_table = sis900_pci_tbl, .probe = sis900_probe, - .remove = __devexit_p(sis900_remove), + .remove = sis900_remove, #ifdef CONFIG_PM .suspend = sis900_suspend, .resume = sis900_resume, |
