X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2F8139cp.c;fp=drivers%2Fnet%2F8139cp.c;h=dd410496aadbbe83fbb7ad6a99a25b414a38bc21;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=1428bb7715afd16a04fb6132cd560b420636d111;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 1428bb771..dd410496a 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -19,11 +19,11 @@ See the file COPYING in this distribution for more information. Contributors: - + Wake-on-LAN support - Felipe Damasio PCI suspend/resume - Felipe Damasio LinkChg interrupt - Felipe Damasio - + TODO: * Test Tx checksumming thoroughly * Implement dev->tx_timeout @@ -52,6 +52,7 @@ #define DRV_RELDATE "Mar 22, 2004" +#include #include #include #include @@ -400,11 +401,6 @@ static void cp_clean_rings (struct cp_private *cp); #ifdef CONFIG_NET_POLL_CONTROLLER static void cp_poll_controller(struct net_device *dev); #endif -static int cp_get_eeprom_len(struct net_device *dev); -static int cp_get_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data); -static int cp_set_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data); static struct pci_device_id cp_pci_tbl[] = { { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, @@ -465,7 +461,7 @@ static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) static inline void cp_set_rxbufsize (struct cp_private *cp) { unsigned int mtu = cp->dev->mtu; - + if (mtu > ETH_DATA_LEN) /* MTU + ethernet header + FCS + optional VLAN tag */ cp->rx_buf_sz = mtu + ETH_HLEN + 8; @@ -514,7 +510,7 @@ static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail, static inline unsigned int cp_rx_csum_ok (u32 status) { unsigned int protocol = (status >> 16) & 0x3; - + if (likely((protocol == RxProtoTCP) && (!(status & TCPFail)))) return 1; else if ((protocol == RxProtoUDP) && (!(status & UDPFail))) @@ -543,7 +539,8 @@ rx_status_loop: unsigned buflen; skb = cp->rx_skb[rx_tail].skb; - BUG_ON(!skb); + if (!skb) + BUG(); desc = &cp->rx_ring[rx_tail]; status = le32_to_cpu(desc->opts1); @@ -726,7 +723,8 @@ static void cp_tx (struct cp_private *cp) break; skb = cp->tx_skb[tx_tail].skb; - BUG_ON(!skb); + if (!skb) + BUG(); pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping, cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE); @@ -796,7 +794,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) entry = cp->tx_head; eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; if (dev->features & NETIF_F_TSO) - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; if (skb_shinfo(skb)->nr_frags == 0) { struct cp_desc *txd = &cp->tx_ring[entry]; @@ -1065,7 +1063,7 @@ static void cp_init_hw (struct cp_private *cp) cpw8(Config3, PARMEnable); cp->wol_enabled = 0; - cpw8(Config5, cpr8(Config5) & PMEStatus); + cpw8(Config5, cpr8(Config5) & PMEStatus); cpw32_f(HiTxRingAddr, 0); cpw32_f(HiTxRingAddr + 4, 0); @@ -1203,7 +1201,7 @@ static int cp_open (struct net_device *dev) cp_init_hw(cp); - rc = request_irq(dev->irq, cp_interrupt, IRQF_SHARED, dev->name, dev); + rc = request_irq(dev->irq, cp_interrupt, SA_SHIRQ, dev->name, dev); if (rc) goto err_out_hw; @@ -1278,7 +1276,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu) } #endif /* BROKEN */ -static const char mii_2_8139_map[8] = { +static char mii_2_8139_map[8] = { BasicModeCtrl, BasicModeStatus, 0, @@ -1355,7 +1353,7 @@ static void netdev_get_wol (struct cp_private *cp, WAKE_MCAST | WAKE_UCAST; /* We don't need to go on if WOL is disabled */ if (!cp->wol_enabled) return; - + options = cpr8 (Config3); if (options & LinkUp) wol->wolopts |= WAKE_PHY; if (options & MagicPacket) wol->wolopts |= WAKE_MAGIC; @@ -1552,7 +1550,8 @@ static void cp_get_ethtool_stats (struct net_device *dev, tmp_stats[i++] = le16_to_cpu(nic_stats->tx_abort); tmp_stats[i++] = le16_to_cpu(nic_stats->tx_underrun); tmp_stats[i++] = cp->cp_stats.rx_frags; - BUG_ON(i != CP_NUM_STATS); + if (i != CP_NUM_STATS) + BUG(); pci_free_consistent(cp->pdev, sizeof(*nic_stats), nic_stats, dma); } @@ -1581,9 +1580,6 @@ static struct ethtool_ops cp_ethtool_ops = { .get_strings = cp_get_strings, .get_ethtool_stats = cp_get_ethtool_stats, .get_perm_addr = ethtool_op_get_perm_addr, - .get_eeprom_len = cp_get_eeprom_len, - .get_eeprom = cp_get_eeprom, - .set_eeprom = cp_set_eeprom, }; static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) @@ -1619,32 +1615,24 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) #define eeprom_delay() readl(ee_addr) /* The EEPROM commands include the alway-set leading bit. */ -#define EE_EXTEND_CMD (4) #define EE_WRITE_CMD (5) #define EE_READ_CMD (6) #define EE_ERASE_CMD (7) -#define EE_EWDS_ADDR (0) -#define EE_WRAL_ADDR (1) -#define EE_ERAL_ADDR (2) -#define EE_EWEN_ADDR (3) - -#define CP_EEPROM_MAGIC PCI_DEVICE_ID_REALTEK_8139 - -static void eeprom_cmd_start(void __iomem *ee_addr) +static int read_eeprom (void __iomem *ioaddr, int location, int addr_len) { + int i; + unsigned retval = 0; + void __iomem *ee_addr = ioaddr + Cfg9346; + int read_cmd = location | (EE_READ_CMD << addr_len); + writeb (EE_ENB & ~EE_CS, ee_addr); writeb (EE_ENB, ee_addr); eeprom_delay (); -} - -static void eeprom_cmd(void __iomem *ee_addr, int cmd, int cmd_len) -{ - int i; - /* Shift the command bits out. */ - for (i = cmd_len - 1; i >= 0; i--) { - int dataval = (cmd & (1 << i)) ? EE_DATA_WRITE : 0; + /* Shift the read command bits out. */ + for (i = 4 + addr_len; i >= 0; i--) { + int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; writeb (EE_ENB | dataval, ee_addr); eeprom_delay (); writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); @@ -1652,33 +1640,6 @@ static void eeprom_cmd(void __iomem *ee_addr, int cmd, int cmd_len) } writeb (EE_ENB, ee_addr); eeprom_delay (); -} - -static void eeprom_cmd_end(void __iomem *ee_addr) -{ - writeb (~EE_CS, ee_addr); - eeprom_delay (); -} - -static void eeprom_extend_cmd(void __iomem *ee_addr, int extend_cmd, - int addr_len) -{ - int cmd = (EE_EXTEND_CMD << addr_len) | (extend_cmd << (addr_len - 2)); - - eeprom_cmd_start(ee_addr); - eeprom_cmd(ee_addr, cmd, 3 + addr_len); - eeprom_cmd_end(ee_addr); -} - -static u16 read_eeprom (void __iomem *ioaddr, int location, int addr_len) -{ - int i; - u16 retval = 0; - void __iomem *ee_addr = ioaddr + Cfg9346; - int read_cmd = location | (EE_READ_CMD << addr_len); - - eeprom_cmd_start(ee_addr); - eeprom_cmd(ee_addr, read_cmd, 3 + addr_len); for (i = 16; i > 0; i--) { writeb (EE_ENB | EE_SHIFT_CLK, ee_addr); @@ -1690,125 +1651,13 @@ static u16 read_eeprom (void __iomem *ioaddr, int location, int addr_len) eeprom_delay (); } - eeprom_cmd_end(ee_addr); + /* Terminate the EEPROM access. */ + writeb (~EE_CS, ee_addr); + eeprom_delay (); return retval; } -static void write_eeprom(void __iomem *ioaddr, int location, u16 val, - int addr_len) -{ - int i; - void __iomem *ee_addr = ioaddr + Cfg9346; - int write_cmd = location | (EE_WRITE_CMD << addr_len); - - eeprom_extend_cmd(ee_addr, EE_EWEN_ADDR, addr_len); - - eeprom_cmd_start(ee_addr); - eeprom_cmd(ee_addr, write_cmd, 3 + addr_len); - eeprom_cmd(ee_addr, val, 16); - eeprom_cmd_end(ee_addr); - - eeprom_cmd_start(ee_addr); - for (i = 0; i < 20000; i++) - if (readb(ee_addr) & EE_DATA_READ) - break; - eeprom_cmd_end(ee_addr); - - eeprom_extend_cmd(ee_addr, EE_EWDS_ADDR, addr_len); -} - -static int cp_get_eeprom_len(struct net_device *dev) -{ - struct cp_private *cp = netdev_priv(dev); - int size; - - spin_lock_irq(&cp->lock); - size = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 256 : 128; - spin_unlock_irq(&cp->lock); - - return size; -} - -static int cp_get_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data) -{ - struct cp_private *cp = netdev_priv(dev); - unsigned int addr_len; - u16 val; - u32 offset = eeprom->offset >> 1; - u32 len = eeprom->len; - u32 i = 0; - - eeprom->magic = CP_EEPROM_MAGIC; - - spin_lock_irq(&cp->lock); - - addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6; - - if (eeprom->offset & 1) { - val = read_eeprom(cp->regs, offset, addr_len); - data[i++] = (u8)(val >> 8); - offset++; - } - - while (i < len - 1) { - val = read_eeprom(cp->regs, offset, addr_len); - data[i++] = (u8)val; - data[i++] = (u8)(val >> 8); - offset++; - } - - if (i < len) { - val = read_eeprom(cp->regs, offset, addr_len); - data[i] = (u8)val; - } - - spin_unlock_irq(&cp->lock); - return 0; -} - -static int cp_set_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data) -{ - struct cp_private *cp = netdev_priv(dev); - unsigned int addr_len; - u16 val; - u32 offset = eeprom->offset >> 1; - u32 len = eeprom->len; - u32 i = 0; - - if (eeprom->magic != CP_EEPROM_MAGIC) - return -EINVAL; - - spin_lock_irq(&cp->lock); - - addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6; - - if (eeprom->offset & 1) { - val = read_eeprom(cp->regs, offset, addr_len) & 0xff; - val |= (u16)data[i++] << 8; - write_eeprom(cp->regs, offset, val, addr_len); - offset++; - } - - while (i < len - 1) { - val = (u16)data[i++]; - val |= (u16)data[i++] << 8; - write_eeprom(cp->regs, offset, val, addr_len); - offset++; - } - - if (i < len) { - val = read_eeprom(cp->regs, offset, addr_len) & 0xff00; - val |= (u16)data[i]; - write_eeprom(cp->regs, offset, val, addr_len); - } - - spin_unlock_irq(&cp->lock); - return 0; -} - /* Put the board into D3cold state and wait for WakeUp signal */ static void cp_set_d3_state (struct cp_private *cp) { @@ -1822,7 +1671,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) struct cp_private *cp; int rc; void __iomem *regs; - resource_size_t pciaddr; + long pciaddr; unsigned int addr_len, i, pci_using_dac; u8 pci_rev; @@ -1836,10 +1685,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (pdev->vendor == PCI_VENDOR_ID_REALTEK && pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev < 0x20) { - dev_err(&pdev->dev, - "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n", - pdev->vendor, pdev->device, pci_rev); - dev_err(&pdev->dev, "Try the \"8139too\" driver instead.\n"); + printk(KERN_ERR PFX "pci dev %s (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n", + pci_name(pdev), pdev->vendor, pdev->device, pci_rev); + printk(KERN_ERR PFX "Try the \"8139too\" driver instead.\n"); return -ENODEV; } @@ -1877,13 +1725,14 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) pciaddr = pci_resource_start(pdev, 1); if (!pciaddr) { rc = -EIO; - dev_err(&pdev->dev, "no MMIO resource\n"); + printk(KERN_ERR PFX "no MMIO resource for pci dev %s\n", + pci_name(pdev)); goto err_out_res; } if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) { rc = -EIO; - dev_err(&pdev->dev, "MMIO resource (%llx) too small\n", - (unsigned long long)pci_resource_len(pdev, 1)); + printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", + pci_resource_len(pdev, 1), pci_name(pdev)); goto err_out_res; } @@ -1897,15 +1746,14 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (rc) { - dev_err(&pdev->dev, - "No usable DMA configuration, aborting.\n"); + printk(KERN_ERR PFX "No usable DMA configuration, " + "aborting.\n"); goto err_out_res; } rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); if (rc) { - dev_err(&pdev->dev, - "No usable consistent DMA configuration, " - "aborting.\n"); + printk(KERN_ERR PFX "No usable consistent DMA configuration, " + "aborting.\n"); goto err_out_res; } } @@ -1916,9 +1764,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) regs = ioremap(pciaddr, CP_REGS_SIZE); if (!regs) { rc = -EIO; - dev_err(&pdev->dev, "Cannot map PCI MMIO (%Lx@%Lx)\n", - (unsigned long long)pci_resource_len(pdev, 1), - (unsigned long long)pciaddr); + printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", + pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); goto err_out_res; } dev->base_addr = (unsigned long) regs; @@ -1987,8 +1834,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) /* enable busmastering and memory-write-invalidate */ pci_set_master(pdev); - if (cp->wol_enabled) - cp_set_d3_state (cp); + if (cp->wol_enabled) cp_set_d3_state (cp); return 0; @@ -2010,11 +1856,11 @@ static void cp_remove_one (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct cp_private *cp = netdev_priv(dev); - BUG_ON(!dev); + if (!dev) + BUG(); unregister_netdev(dev); iounmap(cp->regs); - if (cp->wol_enabled) - pci_set_power_state (pdev, PCI_D0); + if (cp->wol_enabled) pci_set_power_state (pdev, PCI_D0); pci_release_regions(pdev); pci_clear_mwi(pdev); pci_disable_device(pdev); @@ -2077,7 +1923,7 @@ static int cp_resume (struct pci_dev *pdev) mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); spin_unlock_irqrestore (&cp->lock, flags); - + return 0; } #endif /* CONFIG_PM */