diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/gianfar.c | 29 | ||||
-rw-r--r-- | drivers/net/gianfar.h | 11 |
2 files changed, 38 insertions, 2 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index c52f3712ecd3..cee8ae714731 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -85,6 +85,7 @@ | |||
85 | #include <linux/net_tstamp.h> | 85 | #include <linux/net_tstamp.h> |
86 | 86 | ||
87 | #include <asm/io.h> | 87 | #include <asm/io.h> |
88 | #include <asm/reg.h> | ||
88 | #include <asm/irq.h> | 89 | #include <asm/irq.h> |
89 | #include <asm/uaccess.h> | 90 | #include <asm/uaccess.h> |
90 | #include <linux/module.h> | 91 | #include <linux/module.h> |
@@ -928,6 +929,24 @@ static void gfar_init_filer_table(struct gfar_private *priv) | |||
928 | } | 929 | } |
929 | } | 930 | } |
930 | 931 | ||
932 | static void gfar_detect_errata(struct gfar_private *priv) | ||
933 | { | ||
934 | struct device *dev = &priv->ofdev->dev; | ||
935 | unsigned int pvr = mfspr(SPRN_PVR); | ||
936 | unsigned int svr = mfspr(SPRN_SVR); | ||
937 | unsigned int mod = (svr >> 16) & 0xfff6; /* w/o E suffix */ | ||
938 | unsigned int rev = svr & 0xffff; | ||
939 | |||
940 | /* MPC8313 Rev 2.0 and higher; All MPC837x */ | ||
941 | if ((pvr == 0x80850010 && mod == 0x80b0 && rev >= 0x0020) || | ||
942 | (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) | ||
943 | priv->errata |= GFAR_ERRATA_74; | ||
944 | |||
945 | if (priv->errata) | ||
946 | dev_info(dev, "enabled errata workarounds, flags: 0x%x\n", | ||
947 | priv->errata); | ||
948 | } | ||
949 | |||
931 | /* Set up the ethernet device structure, private data, | 950 | /* Set up the ethernet device structure, private data, |
932 | * and anything else we need before we start */ | 951 | * and anything else we need before we start */ |
933 | static int gfar_probe(struct of_device *ofdev, | 952 | static int gfar_probe(struct of_device *ofdev, |
@@ -960,6 +979,8 @@ static int gfar_probe(struct of_device *ofdev, | |||
960 | dev_set_drvdata(&ofdev->dev, priv); | 979 | dev_set_drvdata(&ofdev->dev, priv); |
961 | regs = priv->gfargrp[0].regs; | 980 | regs = priv->gfargrp[0].regs; |
962 | 981 | ||
982 | gfar_detect_errata(priv); | ||
983 | |||
963 | /* Stop the DMA engine now, in case it was running before */ | 984 | /* Stop the DMA engine now, in case it was running before */ |
964 | /* (The firmware could have used it, and left it running). */ | 985 | /* (The firmware could have used it, and left it running). */ |
965 | gfar_halt(dev); | 986 | gfar_halt(dev); |
@@ -974,7 +995,10 @@ static int gfar_probe(struct of_device *ofdev, | |||
974 | gfar_write(®s->maccfg1, tempval); | 995 | gfar_write(®s->maccfg1, tempval); |
975 | 996 | ||
976 | /* Initialize MACCFG2. */ | 997 | /* Initialize MACCFG2. */ |
977 | gfar_write(®s->maccfg2, MACCFG2_INIT_SETTINGS); | 998 | tempval = MACCFG2_INIT_SETTINGS; |
999 | if (gfar_has_errata(priv, GFAR_ERRATA_74)) | ||
1000 | tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK; | ||
1001 | gfar_write(®s->maccfg2, tempval); | ||
978 | 1002 | ||
979 | /* Initialize ECNTRL */ | 1003 | /* Initialize ECNTRL */ |
980 | gfar_write(®s->ecntrl, ECNTRL_INIT_SETTINGS); | 1004 | gfar_write(®s->ecntrl, ECNTRL_INIT_SETTINGS); |
@@ -2300,7 +2324,8 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) | |||
2300 | * to allow huge frames, and to check the length */ | 2324 | * to allow huge frames, and to check the length */ |
2301 | tempval = gfar_read(®s->maccfg2); | 2325 | tempval = gfar_read(®s->maccfg2); |
2302 | 2326 | ||
2303 | if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE) | 2327 | if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE || |
2328 | gfar_has_errata(priv, GFAR_ERRATA_74)) | ||
2304 | tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); | 2329 | tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); |
2305 | else | 2330 | else |
2306 | tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); | 2331 | tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); |
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index ac4a92e08c09..0a0483ce21d2 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -1025,6 +1025,10 @@ struct gfar_priv_grp { | |||
1025 | char int_name_er[GFAR_INT_NAME_MAX]; | 1025 | char int_name_er[GFAR_INT_NAME_MAX]; |
1026 | }; | 1026 | }; |
1027 | 1027 | ||
1028 | enum gfar_errata { | ||
1029 | GFAR_ERRATA_74 = 0x01, | ||
1030 | }; | ||
1031 | |||
1028 | /* Struct stolen almost completely (and shamelessly) from the FCC enet source | 1032 | /* Struct stolen almost completely (and shamelessly) from the FCC enet source |
1029 | * (Ok, that's not so true anymore, but there is a family resemblence) | 1033 | * (Ok, that's not so true anymore, but there is a family resemblence) |
1030 | * The GFAR buffer descriptors track the ring buffers. The rx_bd_base | 1034 | * The GFAR buffer descriptors track the ring buffers. The rx_bd_base |
@@ -1049,6 +1053,7 @@ struct gfar_private { | |||
1049 | struct device_node *node; | 1053 | struct device_node *node; |
1050 | struct net_device *ndev; | 1054 | struct net_device *ndev; |
1051 | struct of_device *ofdev; | 1055 | struct of_device *ofdev; |
1056 | enum gfar_errata errata; | ||
1052 | 1057 | ||
1053 | struct gfar_priv_grp gfargrp[MAXGROUPS]; | 1058 | struct gfar_priv_grp gfargrp[MAXGROUPS]; |
1054 | struct gfar_priv_tx_q *tx_queue[MAX_TX_QS]; | 1059 | struct gfar_priv_tx_q *tx_queue[MAX_TX_QS]; |
@@ -1111,6 +1116,12 @@ struct gfar_private { | |||
1111 | extern unsigned int ftp_rqfpr[MAX_FILER_IDX + 1]; | 1116 | extern unsigned int ftp_rqfpr[MAX_FILER_IDX + 1]; |
1112 | extern unsigned int ftp_rqfcr[MAX_FILER_IDX + 1]; | 1117 | extern unsigned int ftp_rqfcr[MAX_FILER_IDX + 1]; |
1113 | 1118 | ||
1119 | static inline int gfar_has_errata(struct gfar_private *priv, | ||
1120 | enum gfar_errata err) | ||
1121 | { | ||
1122 | return priv->errata & err; | ||
1123 | } | ||
1124 | |||
1114 | static inline u32 gfar_read(volatile unsigned __iomem *addr) | 1125 | static inline u32 gfar_read(volatile unsigned __iomem *addr) |
1115 | { | 1126 | { |
1116 | u32 val; | 1127 | u32 val; |