aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/acenic.c
diff options
context:
space:
mode:
authorJaswinder Singh <jaswinder@infradead.org>2009-01-04 19:09:40 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-04 19:10:02 -0500
commit949b42544a20fb22800e244a004ff45bd359a21b (patch)
treedca766b86ae1018f79276e4fd3916c2012966e89 /drivers/net/acenic.c
parent14deae41566b5cdd992c01d0069518ced5227c83 (diff)
firmware: convert acenic driver to request_firmware()
We store the firmware in its native big-endian form now, so the loop in ace_copy() is modified to use be32_to_cpup() when writing it out. We can forget the BSS,SBSS sections of the firmware, since we were clearing all the device's RAM anyway. And the text,rodata,data sections can all be loaded as a single chunk since they're contiguous (give or take a few dozen bytes in between). Signed-off-by: Jaswinder Singh <jaswinder@infradead.org> Signed-off-by: David Woodhouse <dwmw2@infradead.org> Acked-by: Jes Sorensen <jes@sgi.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/acenic.c')
-rw-r--r--drivers/net/acenic.c117
1 files changed, 71 insertions, 46 deletions
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 517fce48d94a..5b396ff6c83f 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -66,6 +66,7 @@
66#include <linux/mm.h> 66#include <linux/mm.h>
67#include <linux/highmem.h> 67#include <linux/highmem.h>
68#include <linux/sockios.h> 68#include <linux/sockios.h>
69#include <linux/firmware.h>
69 70
70#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 71#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
71#include <linux/if_vlan.h> 72#include <linux/if_vlan.h>
@@ -186,8 +187,6 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
186#define MAX_RODATA_LEN 8*1024 187#define MAX_RODATA_LEN 8*1024
187#define MAX_DATA_LEN 2*1024 188#define MAX_DATA_LEN 2*1024
188 189
189#include "acenic_firmware.h"
190
191#ifndef tigon2FwReleaseLocal 190#ifndef tigon2FwReleaseLocal
192#define tigon2FwReleaseLocal 0 191#define tigon2FwReleaseLocal 0
193#endif 192#endif
@@ -417,6 +416,10 @@ static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
417MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>"); 416MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>");
418MODULE_LICENSE("GPL"); 417MODULE_LICENSE("GPL");
419MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver"); 418MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
419#ifndef CONFIG_ACENIC_OMIT_TIGON_I
420MODULE_FIRMWARE("acenic/tg1.bin");
421#endif
422MODULE_FIRMWARE("acenic/tg2.bin");
420 423
421module_param_array_named(link, link_state, int, NULL, 0); 424module_param_array_named(link, link_state, int, NULL, 0);
422module_param_array(trace, int, NULL, 0); 425module_param_array(trace, int, NULL, 0);
@@ -943,8 +946,8 @@ static int __devinit ace_init(struct net_device *dev)
943 case 4: 946 case 4:
944 case 5: 947 case 5:
945 printk(KERN_INFO " Tigon I (Rev. %i), Firmware: %i.%i.%i, ", 948 printk(KERN_INFO " Tigon I (Rev. %i), Firmware: %i.%i.%i, ",
946 tig_ver, tigonFwReleaseMajor, tigonFwReleaseMinor, 949 tig_ver, ap->firmware_major, ap->firmware_minor,
947 tigonFwReleaseFix); 950 ap->firmware_fix);
948 writel(0, &regs->LocalCtrl); 951 writel(0, &regs->LocalCtrl);
949 ap->version = 1; 952 ap->version = 1;
950 ap->tx_ring_entries = TIGON_I_TX_RING_ENTRIES; 953 ap->tx_ring_entries = TIGON_I_TX_RING_ENTRIES;
@@ -952,8 +955,8 @@ static int __devinit ace_init(struct net_device *dev)
952#endif 955#endif
953 case 6: 956 case 6:
954 printk(KERN_INFO " Tigon II (Rev. %i), Firmware: %i.%i.%i, ", 957 printk(KERN_INFO " Tigon II (Rev. %i), Firmware: %i.%i.%i, ",
955 tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor, 958 tig_ver, ap->firmware_major, ap->firmware_minor,
956 tigon2FwReleaseFix); 959 ap->firmware_fix);
957 writel(readl(&regs->CpuBCtrl) | CPU_HALT, &regs->CpuBCtrl); 960 writel(readl(&regs->CpuBCtrl) | CPU_HALT, &regs->CpuBCtrl);
958 readl(&regs->CpuBCtrl); /* PCI write posting */ 961 readl(&regs->CpuBCtrl); /* PCI write posting */
959 /* 962 /*
@@ -1205,7 +1208,9 @@ static int __devinit ace_init(struct net_device *dev)
1205 memset(ap->info, 0, sizeof(struct ace_info)); 1208 memset(ap->info, 0, sizeof(struct ace_info));
1206 memset(ap->skb, 0, sizeof(struct ace_skb)); 1209 memset(ap->skb, 0, sizeof(struct ace_skb));
1207 1210
1208 ace_load_firmware(dev); 1211 if (ace_load_firmware(dev))
1212 goto init_error;
1213
1209 ap->fw_running = 0; 1214 ap->fw_running = 0;
1210 1215
1211 tmp_ptr = ap->info_dma; 1216 tmp_ptr = ap->info_dma;
@@ -1441,10 +1446,7 @@ static int __devinit ace_init(struct net_device *dev)
1441 if (ap->version >= 2) 1446 if (ap->version >= 2)
1442 writel(tmp, &regs->TuneFastLink); 1447 writel(tmp, &regs->TuneFastLink);
1443 1448
1444 if (ACE_IS_TIGON_I(ap)) 1449 writel(ap->firmware_start, &regs->Pc);
1445 writel(tigonFwStartAddr, &regs->Pc);
1446 if (ap->version == 2)
1447 writel(tigon2FwStartAddr, &regs->Pc);
1448 1450
1449 writel(0, &regs->Mb0Lo); 1451 writel(0, &regs->Mb0Lo);
1450 1452
@@ -2761,8 +2763,8 @@ static void ace_get_drvinfo(struct net_device *dev,
2761 2763
2762 strlcpy(info->driver, "acenic", sizeof(info->driver)); 2764 strlcpy(info->driver, "acenic", sizeof(info->driver));
2763 snprintf(info->version, sizeof(info->version), "%i.%i.%i", 2765 snprintf(info->version, sizeof(info->version), "%i.%i.%i",
2764 tigonFwReleaseMajor, tigonFwReleaseMinor, 2766 ap->firmware_major, ap->firmware_minor,
2765 tigonFwReleaseFix); 2767 ap->firmware_fix);
2766 2768
2767 if (ap->pdev) 2769 if (ap->pdev)
2768 strlcpy(info->bus_info, pci_name(ap->pdev), 2770 strlcpy(info->bus_info, pci_name(ap->pdev),
@@ -2869,11 +2871,10 @@ static struct net_device_stats *ace_get_stats(struct net_device *dev)
2869} 2871}
2870 2872
2871 2873
2872static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src, 2874static void __devinit ace_copy(struct ace_regs __iomem *regs, const __be32 *src,
2873 u32 dest, int size) 2875 u32 dest, int size)
2874{ 2876{
2875 void __iomem *tdest; 2877 void __iomem *tdest;
2876 u32 *wsrc;
2877 short tsize, i; 2878 short tsize, i;
2878 2879
2879 if (size <= 0) 2880 if (size <= 0)
@@ -2885,20 +2886,15 @@ static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src,
2885 tdest = (void __iomem *) &regs->Window + 2886 tdest = (void __iomem *) &regs->Window +
2886 (dest & (ACE_WINDOW_SIZE - 1)); 2887 (dest & (ACE_WINDOW_SIZE - 1));
2887 writel(dest & ~(ACE_WINDOW_SIZE - 1), &regs->WinBase); 2888 writel(dest & ~(ACE_WINDOW_SIZE - 1), &regs->WinBase);
2888 /*
2889 * This requires byte swapping on big endian, however
2890 * writel does that for us
2891 */
2892 wsrc = src;
2893 for (i = 0; i < (tsize / 4); i++) { 2889 for (i = 0; i < (tsize / 4); i++) {
2894 writel(wsrc[i], tdest + i*4); 2890 /* Firmware is big-endian */
2891 writel(be32_to_cpup(src), tdest);
2892 src++;
2893 tdest += 4;
2894 dest += 4;
2895 size -= 4;
2895 } 2896 }
2896 dest += tsize;
2897 src += tsize;
2898 size -= tsize;
2899 } 2897 }
2900
2901 return;
2902} 2898}
2903 2899
2904 2900
@@ -2937,8 +2933,13 @@ static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int siz
2937 */ 2933 */
2938static int __devinit ace_load_firmware(struct net_device *dev) 2934static int __devinit ace_load_firmware(struct net_device *dev)
2939{ 2935{
2936 const struct firmware *fw;
2937 const char *fw_name = "acenic/tg2.bin";
2940 struct ace_private *ap = netdev_priv(dev); 2938 struct ace_private *ap = netdev_priv(dev);
2941 struct ace_regs __iomem *regs = ap->regs; 2939 struct ace_regs __iomem *regs = ap->regs;
2940 const __be32 *fw_data;
2941 u32 load_addr;
2942 int ret;
2942 2943
2943 if (!(readl(&regs->CpuCtrl) & CPU_HALTED)) { 2944 if (!(readl(&regs->CpuCtrl) & CPU_HALTED)) {
2944 printk(KERN_ERR "%s: trying to download firmware while the " 2945 printk(KERN_ERR "%s: trying to download firmware while the "
@@ -2946,28 +2947,52 @@ static int __devinit ace_load_firmware(struct net_device *dev)
2946 return -EFAULT; 2947 return -EFAULT;
2947 } 2948 }
2948 2949
2950 if (ACE_IS_TIGON_I(ap))
2951 fw_name = "acenic/tg1.bin";
2952
2953 ret = request_firmware(&fw, fw_name, &ap->pdev->dev);
2954 if (ret) {
2955 printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
2956 ap->name, fw_name);
2957 return ret;
2958 }
2959
2960 fw_data = (void *)fw->data;
2961
2962 /* Firmware blob starts with version numbers, followed by
2963 load and start address. Remainder is the blob to be loaded
2964 contiguously from load address. We don't bother to represent
2965 the BSS/SBSS sections any more, since we were clearing the
2966 whole thing anyway. */
2967 ap->firmware_major = fw->data[0];
2968 ap->firmware_minor = fw->data[1];
2969 ap->firmware_fix = fw->data[2];
2970
2971 ap->firmware_start = be32_to_cpu(fw_data[1]);
2972 if (ap->firmware_start < 0x4000 || ap->firmware_start >= 0x80000) {
2973 printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n",
2974 ap->name, ap->firmware_start, fw_name);
2975 ret = -EINVAL;
2976 goto out;
2977 }
2978
2979 load_addr = be32_to_cpu(fw_data[2]);
2980 if (load_addr < 0x4000 || load_addr >= 0x80000) {
2981 printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n",
2982 ap->name, load_addr, fw_name);
2983 ret = -EINVAL;
2984 goto out;
2985 }
2986
2949 /* 2987 /*
2950 * Do not try to clear more than 512KB or we end up seeing 2988 * Do not try to clear more than 512KiB or we end up seeing
2951 * funny things on NICs with only 512KB SRAM 2989 * funny things on NICs with only 512KiB SRAM
2952 */ 2990 */
2953 ace_clear(regs, 0x2000, 0x80000-0x2000); 2991 ace_clear(regs, 0x2000, 0x80000-0x2000);
2954 if (ACE_IS_TIGON_I(ap)) { 2992 ace_copy(regs, &fw_data[3], load_addr, fw->size-12);
2955 ace_copy(regs, tigonFwText, tigonFwTextAddr, tigonFwTextLen); 2993 out:
2956 ace_copy(regs, tigonFwData, tigonFwDataAddr, tigonFwDataLen); 2994 release_firmware(fw);
2957 ace_copy(regs, tigonFwRodata, tigonFwRodataAddr, 2995 return ret;
2958 tigonFwRodataLen);
2959 ace_clear(regs, tigonFwBssAddr, tigonFwBssLen);
2960 ace_clear(regs, tigonFwSbssAddr, tigonFwSbssLen);
2961 }else if (ap->version == 2) {
2962 ace_clear(regs, tigon2FwBssAddr, tigon2FwBssLen);
2963 ace_clear(regs, tigon2FwSbssAddr, tigon2FwSbssLen);
2964 ace_copy(regs, tigon2FwText, tigon2FwTextAddr,tigon2FwTextLen);
2965 ace_copy(regs, tigon2FwRodata, tigon2FwRodataAddr,
2966 tigon2FwRodataLen);
2967 ace_copy(regs, tigon2FwData, tigon2FwDataAddr,tigon2FwDataLen);
2968 }
2969
2970 return 0;
2971} 2996}
2972 2997
2973 2998