X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Facenic.c;h=5f0b05c2d71fbe64f4699394f88b621c214bf2df;hb=8d65af789f3e2cf4cfbdbf71a0f7a61ebcd41d38;hp=6eefd93a08f33250bbb12b3e5170611484fb0b5e;hpb=e174961ca1a0b28f7abf0be47973ad57cb74e5f0;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 6eefd93..5f0b05c 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -66,6 +66,7 @@ #include #include #include +#include #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #include @@ -186,8 +187,6 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); #define MAX_RODATA_LEN 8*1024 #define MAX_DATA_LEN 2*1024 -#include "acenic_firmware.h" - #ifndef tigon2FwReleaseLocal #define tigon2FwReleaseLocal 0 #endif @@ -417,6 +416,10 @@ static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1}; MODULE_AUTHOR("Jes Sorensen "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver"); +#ifndef CONFIG_ACENIC_OMIT_TIGON_I +MODULE_FIRMWARE("acenic/tg1.bin"); +#endif +MODULE_FIRMWARE("acenic/tg2.bin"); module_param_array_named(link, link_state, int, NULL, 0); module_param_array(trace, int, NULL, 0); @@ -434,7 +437,7 @@ MODULE_PARM_DESC(max_rx_desc, "AceNIC/3C985/GA620 max number of receive descript MODULE_PARM_DESC(tx_ratio, "AceNIC/3C985/GA620 ratio of NIC memory used for TX/RX descriptors (range 0-63)"); -static char version[] __devinitdata = +static const char version[] __devinitconst = "acenic.c: v0.92 08/05/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n" " http://home.cern.ch/~jes/gige/acenic.html\n"; @@ -450,6 +453,21 @@ static const struct ethtool_ops ace_ethtool_ops = { static void ace_watchdog(struct net_device *dev); +static const struct net_device_ops ace_netdev_ops = { + .ndo_open = ace_open, + .ndo_stop = ace_close, + .ndo_tx_timeout = ace_watchdog, + .ndo_get_stats = ace_get_stats, + .ndo_start_xmit = ace_start_xmit, + .ndo_set_multicast_list = ace_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = ace_set_mac_addr, + .ndo_change_mtu = ace_change_mtu, +#if ACENIC_DO_VLAN + .ndo_vlan_rx_register = ace_vlan_rx_register, +#endif +}; + static int __devinit acenic_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -466,27 +484,19 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev, SET_NETDEV_DEV(dev, &pdev->dev); - ap = dev->priv; + ap = netdev_priv(dev); ap->pdev = pdev; ap->name = pci_name(pdev); dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; #if ACENIC_DO_VLAN dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->vlan_rx_register = ace_vlan_rx_register; #endif - dev->tx_timeout = &ace_watchdog; dev->watchdog_timeo = 5*HZ; - dev->open = &ace_open; - dev->stop = &ace_close; - dev->hard_start_xmit = &ace_start_xmit; - dev->get_stats = &ace_get_stats; - dev->set_multicast_list = &ace_set_multicast_list; + dev->netdev_ops = &ace_netdev_ops; SET_ETHTOOL_OPS(dev, &ace_ethtool_ops); - dev->set_mac_address = &ace_set_mac_addr; - dev->change_mtu = &ace_change_mtu; /* we only display this string ONCE */ if (!boards_found) @@ -937,8 +947,8 @@ static int __devinit ace_init(struct net_device *dev) case 4: case 5: printk(KERN_INFO " Tigon I (Rev. %i), Firmware: %i.%i.%i, ", - tig_ver, tigonFwReleaseMajor, tigonFwReleaseMinor, - tigonFwReleaseFix); + tig_ver, ap->firmware_major, ap->firmware_minor, + ap->firmware_fix); writel(0, ®s->LocalCtrl); ap->version = 1; ap->tx_ring_entries = TIGON_I_TX_RING_ENTRIES; @@ -946,8 +956,8 @@ static int __devinit ace_init(struct net_device *dev) #endif case 6: printk(KERN_INFO " Tigon II (Rev. %i), Firmware: %i.%i.%i, ", - tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor, - tigon2FwReleaseFix); + tig_ver, ap->firmware_major, ap->firmware_minor, + ap->firmware_fix); writel(readl(®s->CpuBCtrl) | CPU_HALT, ®s->CpuBCtrl); readl(®s->CpuBCtrl); /* PCI write posting */ /* @@ -1151,9 +1161,9 @@ static int __devinit ace_init(struct net_device *dev) /* * Configure DMA attributes. */ - if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { ap->pci_using_dac = 1; - } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { + } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { ap->pci_using_dac = 0; } else { ecode = -ENODEV; @@ -1199,7 +1209,9 @@ static int __devinit ace_init(struct net_device *dev) memset(ap->info, 0, sizeof(struct ace_info)); memset(ap->skb, 0, sizeof(struct ace_skb)); - ace_load_firmware(dev); + if (ace_load_firmware(dev)) + goto init_error; + ap->fw_running = 0; tmp_ptr = ap->info_dma; @@ -1435,10 +1447,7 @@ static int __devinit ace_init(struct net_device *dev) if (ap->version >= 2) writel(tmp, ®s->TuneFastLink); - if (ACE_IS_TIGON_I(ap)) - writel(tigonFwStartAddr, ®s->Pc); - if (ap->version == 2) - writel(tigon2FwStartAddr, ®s->Pc); + writel(ap->firmware_start, ®s->Pc); writel(0, ®s->Mb0Lo); @@ -2033,7 +2042,6 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) #endif netif_rx(skb); - dev->last_rx = jiffies; dev->stats.rx_packets++; dev->stats.rx_bytes += retdesc->size; @@ -2456,7 +2464,8 @@ ace_load_tx_bd(struct ace_private *ap, struct tx_desc *desc, u64 addr, } -static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t ace_start_xmit(struct sk_buff *skb, + struct net_device *dev) { struct ace_private *ap = netdev_priv(dev); struct ace_regs __iomem *regs = ap->regs; @@ -2565,7 +2574,6 @@ restart: netif_wake_queue(dev); } - dev->trans_start = jiffies; return NETDEV_TX_OK; overflow: @@ -2756,8 +2764,8 @@ static void ace_get_drvinfo(struct net_device *dev, strlcpy(info->driver, "acenic", sizeof(info->driver)); snprintf(info->version, sizeof(info->version), "%i.%i.%i", - tigonFwReleaseMajor, tigonFwReleaseMinor, - tigonFwReleaseFix); + ap->firmware_major, ap->firmware_minor, + ap->firmware_fix); if (ap->pdev) strlcpy(info->bus_info, pci_name(ap->pdev), @@ -2864,11 +2872,10 @@ static struct net_device_stats *ace_get_stats(struct net_device *dev) } -static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src, - u32 dest, int size) +static void __devinit ace_copy(struct ace_regs __iomem *regs, const __be32 *src, + u32 dest, int size) { void __iomem *tdest; - u32 *wsrc; short tsize, i; if (size <= 0) @@ -2880,20 +2887,15 @@ static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src, tdest = (void __iomem *) ®s->Window + (dest & (ACE_WINDOW_SIZE - 1)); writel(dest & ~(ACE_WINDOW_SIZE - 1), ®s->WinBase); - /* - * This requires byte swapping on big endian, however - * writel does that for us - */ - wsrc = src; for (i = 0; i < (tsize / 4); i++) { - writel(wsrc[i], tdest + i*4); + /* Firmware is big-endian */ + writel(be32_to_cpup(src), tdest); + src++; + tdest += 4; + dest += 4; + size -= 4; } - dest += tsize; - src += tsize; - size -= tsize; } - - return; } @@ -2932,8 +2934,13 @@ static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int siz */ static int __devinit ace_load_firmware(struct net_device *dev) { + const struct firmware *fw; + const char *fw_name = "acenic/tg2.bin"; struct ace_private *ap = netdev_priv(dev); struct ace_regs __iomem *regs = ap->regs; + const __be32 *fw_data; + u32 load_addr; + int ret; if (!(readl(®s->CpuCtrl) & CPU_HALTED)) { printk(KERN_ERR "%s: trying to download firmware while the " @@ -2941,28 +2948,52 @@ static int __devinit ace_load_firmware(struct net_device *dev) return -EFAULT; } + if (ACE_IS_TIGON_I(ap)) + fw_name = "acenic/tg1.bin"; + + ret = request_firmware(&fw, fw_name, &ap->pdev->dev); + if (ret) { + printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", + ap->name, fw_name); + return ret; + } + + fw_data = (void *)fw->data; + + /* Firmware blob starts with version numbers, followed by + load and start address. Remainder is the blob to be loaded + contiguously from load address. We don't bother to represent + the BSS/SBSS sections any more, since we were clearing the + whole thing anyway. */ + ap->firmware_major = fw->data[0]; + ap->firmware_minor = fw->data[1]; + ap->firmware_fix = fw->data[2]; + + ap->firmware_start = be32_to_cpu(fw_data[1]); + if (ap->firmware_start < 0x4000 || ap->firmware_start >= 0x80000) { + printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n", + ap->name, ap->firmware_start, fw_name); + ret = -EINVAL; + goto out; + } + + load_addr = be32_to_cpu(fw_data[2]); + if (load_addr < 0x4000 || load_addr >= 0x80000) { + printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n", + ap->name, load_addr, fw_name); + ret = -EINVAL; + goto out; + } + /* - * Do not try to clear more than 512KB or we end up seeing - * funny things on NICs with only 512KB SRAM + * Do not try to clear more than 512KiB or we end up seeing + * funny things on NICs with only 512KiB SRAM */ ace_clear(regs, 0x2000, 0x80000-0x2000); - if (ACE_IS_TIGON_I(ap)) { - ace_copy(regs, tigonFwText, tigonFwTextAddr, tigonFwTextLen); - ace_copy(regs, tigonFwData, tigonFwDataAddr, tigonFwDataLen); - ace_copy(regs, tigonFwRodata, tigonFwRodataAddr, - tigonFwRodataLen); - ace_clear(regs, tigonFwBssAddr, tigonFwBssLen); - ace_clear(regs, tigonFwSbssAddr, tigonFwSbssLen); - }else if (ap->version == 2) { - ace_clear(regs, tigon2FwBssAddr, tigon2FwBssLen); - ace_clear(regs, tigon2FwSbssAddr, tigon2FwSbssLen); - ace_copy(regs, tigon2FwText, tigon2FwTextAddr,tigon2FwTextLen); - ace_copy(regs, tigon2FwRodata, tigon2FwRodataAddr, - tigon2FwRodataLen); - ace_copy(regs, tigon2FwData, tigon2FwDataAddr,tigon2FwDataLen); - } - - return 0; + ace_copy(regs, &fw_data[3], load_addr, fw->size-12); + out: + release_firmware(fw); + return ret; } @@ -3219,10 +3250,3 @@ static int __devinit read_eeprom_byte(struct net_device *dev, ap->name, offset); goto out; } - - -/* - * Local variables: - * compile-command: "gcc -D__SMP__ -D__KERNEL__ -DMODULE -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -DMODVERSIONS -include ../../include/linux/modversions.h -c -o acenic.o acenic.c" - * End: - */