aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@snapgear.com>2005-09-11 21:18:10 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-11 23:43:46 -0400
commit7dd6a2aa27a7a8036fbaf60cbce38a64128d1d4d (patch)
tree7102a933a07e642d12c479c8566e5afe84059a22 /drivers
parent2af6921f6382456ed69163be9d2ee2c339134496 (diff)
[PATCH] m68knommu: ColdFire FEC eth driver improvements
A few improvements to the Freescale/ColdFire FEC driver: . some formatting cleanups . add support for the FEC device in the ColdFire 523x processor family . add support for MAC address setting on MOD5272 and M5272C3 boards . don't re-read the PHY status register many times . ack status interrupt before reading status register . move printing init message to after full init (so that the ethX name is filled out for printing) Some parts of this patch submitted by Philippe De Muyter <phdm@macqel.be> Signed-off-by: Greg Ungerer <gerg@uclinux.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/fec.c478
1 files changed, 248 insertions, 230 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 2c7008491378..85504fb900da 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -8,7 +8,7 @@
8 * describes connections using the internal parallel port I/O, which 8 * describes connections using the internal parallel port I/O, which
9 * is basically all of Port D. 9 * is basically all of Port D.
10 * 10 *
11 * Right now, I am very watseful with the buffers. I allocate memory 11 * Right now, I am very wasteful with the buffers. I allocate memory
12 * pages and then divide them into 2K frame buffers. This way I know I 12 * pages and then divide them into 2K frame buffers. This way I know I
13 * have buffers large enough to hold one frame within one buffer descriptor. 13 * have buffers large enough to hold one frame within one buffer descriptor.
14 * Once I get this working, I will use 64 or 128 byte CPM buffers, which 14 * Once I get this working, I will use 64 or 128 byte CPM buffers, which
@@ -19,7 +19,10 @@
19 * Copyright (c) 2000 Ericsson Radio Systems AB. 19 * Copyright (c) 2000 Ericsson Radio Systems AB.
20 * 20 *
21 * Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282. 21 * Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282.
22 * Copyrught (c) 2001-2004 Greg Ungerer (gerg@snapgear.com) 22 * Copyright (c) 2001-2004 Greg Ungerer (gerg@snapgear.com)
23 *
24 * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
25 * Copyright (c) 2004-2005 Macq Electronique SA.
23 */ 26 */
24 27
25#include <linux/config.h> 28#include <linux/config.h>
@@ -46,7 +49,8 @@
46#include <asm/io.h> 49#include <asm/io.h>
47#include <asm/pgtable.h> 50#include <asm/pgtable.h>
48 51
49#if defined(CONFIG_M527x) || defined(CONFIG_M5272) || defined(CONFIG_M528x) 52#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
53 defined(CONFIG_M5272) || defined(CONFIG_M528x)
50#include <asm/coldfire.h> 54#include <asm/coldfire.h>
51#include <asm/mcfsim.h> 55#include <asm/mcfsim.h>
52#include "fec.h" 56#include "fec.h"
@@ -71,7 +75,7 @@ static unsigned int fec_hw[] = {
71#elif defined(CONFIG_M527x) 75#elif defined(CONFIG_M527x)
72 (MCF_MBAR + 0x1000), 76 (MCF_MBAR + 0x1000),
73 (MCF_MBAR + 0x1800), 77 (MCF_MBAR + 0x1800),
74#elif defined(CONFIG_M528x) 78#elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
75 (MCF_MBAR + 0x1000), 79 (MCF_MBAR + 0x1000),
76#else 80#else
77 &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), 81 &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
@@ -94,12 +98,14 @@ static unsigned char fec_mac_default[] = {
94#define FEC_FLASHMAC 0xffe04000 98#define FEC_FLASHMAC 0xffe04000
95#elif defined(CONFIG_CANCam) 99#elif defined(CONFIG_CANCam)
96#define FEC_FLASHMAC 0xf0020000 100#define FEC_FLASHMAC 0xf0020000
101#elif defined (CONFIG_M5272C3)
102#define FEC_FLASHMAC (0xffe04000 + 4)
103#elif defined(CONFIG_MOD5272)
104#define FEC_FLASHMAC 0xffc0406b
97#else 105#else
98#define FEC_FLASHMAC 0 106#define FEC_FLASHMAC 0
99#endif 107#endif
100 108
101unsigned char *fec_flashmac = (unsigned char *) FEC_FLASHMAC;
102
103/* Forward declarations of some structures to support different PHYs 109/* Forward declarations of some structures to support different PHYs
104*/ 110*/
105 111
@@ -158,7 +164,7 @@ typedef struct {
158 * size bits. Other FEC hardware does not, so we need to take that into 164 * size bits. Other FEC hardware does not, so we need to take that into
159 * account when setting it. 165 * account when setting it.
160 */ 166 */
161#if defined(CONFIG_M527x) || defined(CONFIG_M528x) 167#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
162#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) 168#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
163#else 169#else
164#define OPT_FRAME_SIZE 0 170#define OPT_FRAME_SIZE 0
@@ -196,7 +202,7 @@ struct fec_enet_private {
196 uint phy_id_done; 202 uint phy_id_done;
197 uint phy_status; 203 uint phy_status;
198 uint phy_speed; 204 uint phy_speed;
199 phy_info_t *phy; 205 phy_info_t const *phy;
200 struct work_struct phy_task; 206 struct work_struct phy_task;
201 207
202 uint sequence_done; 208 uint sequence_done;
@@ -209,7 +215,6 @@ struct fec_enet_private {
209 int link; 215 int link;
210 int old_link; 216 int old_link;
211 int full_duplex; 217 int full_duplex;
212 unsigned char mac_addr[ETH_ALEN];
213}; 218};
214 219
215static int fec_enet_open(struct net_device *dev); 220static int fec_enet_open(struct net_device *dev);
@@ -237,10 +242,10 @@ typedef struct mii_list {
237} mii_list_t; 242} mii_list_t;
238 243
239#define NMII 20 244#define NMII 20
240mii_list_t mii_cmds[NMII]; 245static mii_list_t mii_cmds[NMII];
241mii_list_t *mii_free; 246static mii_list_t *mii_free;
242mii_list_t *mii_head; 247static mii_list_t *mii_head;
243mii_list_t *mii_tail; 248static mii_list_t *mii_tail;
244 249
245static int mii_queue(struct net_device *dev, int request, 250static int mii_queue(struct net_device *dev, int request,
246 void (*func)(uint, struct net_device *)); 251 void (*func)(uint, struct net_device *));
@@ -425,7 +430,7 @@ fec_timeout(struct net_device *dev)
425 } 430 }
426 } 431 }
427#endif 432#endif
428 fec_restart(dev, 0); 433 fec_restart(dev, fep->full_duplex);
429 netif_wake_queue(dev); 434 netif_wake_queue(dev);
430} 435}
431 436
@@ -757,45 +762,52 @@ static void mii_parse_sr(uint mii_reg, struct net_device *dev)
757{ 762{
758 struct fec_enet_private *fep = netdev_priv(dev); 763 struct fec_enet_private *fep = netdev_priv(dev);
759 volatile uint *s = &(fep->phy_status); 764 volatile uint *s = &(fep->phy_status);
765 uint status;
760 766
761 *s &= ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC); 767 status = *s & ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC);
762 768
763 if (mii_reg & 0x0004) 769 if (mii_reg & 0x0004)
764 *s |= PHY_STAT_LINK; 770 status |= PHY_STAT_LINK;
765 if (mii_reg & 0x0010) 771 if (mii_reg & 0x0010)
766 *s |= PHY_STAT_FAULT; 772 status |= PHY_STAT_FAULT;
767 if (mii_reg & 0x0020) 773 if (mii_reg & 0x0020)
768 *s |= PHY_STAT_ANC; 774 status |= PHY_STAT_ANC;
775
776 *s = status;
769} 777}
770 778
771static void mii_parse_cr(uint mii_reg, struct net_device *dev) 779static void mii_parse_cr(uint mii_reg, struct net_device *dev)
772{ 780{
773 struct fec_enet_private *fep = netdev_priv(dev); 781 struct fec_enet_private *fep = netdev_priv(dev);
774 volatile uint *s = &(fep->phy_status); 782 volatile uint *s = &(fep->phy_status);
783 uint status;
775 784
776 *s &= ~(PHY_CONF_ANE | PHY_CONF_LOOP); 785 status = *s & ~(PHY_CONF_ANE | PHY_CONF_LOOP);
777 786
778 if (mii_reg & 0x1000) 787 if (mii_reg & 0x1000)
779 *s |= PHY_CONF_ANE; 788 status |= PHY_CONF_ANE;
780 if (mii_reg & 0x4000) 789 if (mii_reg & 0x4000)
781 *s |= PHY_CONF_LOOP; 790 status |= PHY_CONF_LOOP;
791 *s = status;
782} 792}
783 793
784static void mii_parse_anar(uint mii_reg, struct net_device *dev) 794static void mii_parse_anar(uint mii_reg, struct net_device *dev)
785{ 795{
786 struct fec_enet_private *fep = netdev_priv(dev); 796 struct fec_enet_private *fep = netdev_priv(dev);
787 volatile uint *s = &(fep->phy_status); 797 volatile uint *s = &(fep->phy_status);
798 uint status;
788 799
789 *s &= ~(PHY_CONF_SPMASK); 800 status = *s & ~(PHY_CONF_SPMASK);
790 801
791 if (mii_reg & 0x0020) 802 if (mii_reg & 0x0020)
792 *s |= PHY_CONF_10HDX; 803 status |= PHY_CONF_10HDX;
793 if (mii_reg & 0x0040) 804 if (mii_reg & 0x0040)
794 *s |= PHY_CONF_10FDX; 805 status |= PHY_CONF_10FDX;
795 if (mii_reg & 0x0080) 806 if (mii_reg & 0x0080)
796 *s |= PHY_CONF_100HDX; 807 status |= PHY_CONF_100HDX;
797 if (mii_reg & 0x00100) 808 if (mii_reg & 0x00100)
798 *s |= PHY_CONF_100FDX; 809 status |= PHY_CONF_100FDX;
810 *s = status;
799} 811}
800 812
801/* ------------------------------------------------------------------------- */ 813/* ------------------------------------------------------------------------- */
@@ -811,37 +823,34 @@ static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev)
811{ 823{
812 struct fec_enet_private *fep = netdev_priv(dev); 824 struct fec_enet_private *fep = netdev_priv(dev);
813 volatile uint *s = &(fep->phy_status); 825 volatile uint *s = &(fep->phy_status);
826 uint status;
814 827
815 *s &= ~(PHY_STAT_SPMASK); 828 status = *s & ~(PHY_STAT_SPMASK);
816
817 if (mii_reg & 0x0800) { 829 if (mii_reg & 0x0800) {
818 if (mii_reg & 0x1000) 830 if (mii_reg & 0x1000)
819 *s |= PHY_STAT_100FDX; 831 status |= PHY_STAT_100FDX;
820 else 832 else
821 *s |= PHY_STAT_100HDX; 833 status |= PHY_STAT_100HDX;
822 } else { 834 } else {
823 if (mii_reg & 0x1000) 835 if (mii_reg & 0x1000)
824 *s |= PHY_STAT_10FDX; 836 status |= PHY_STAT_10FDX;
825 else 837 else
826 *s |= PHY_STAT_10HDX; 838 status |= PHY_STAT_10HDX;
827 } 839 }
840 *s = status;
828} 841}
829 842
830static phy_info_t phy_info_lxt970 = { 843static phy_cmd_t const phy_cmd_lxt970_config[] = {
831 0x07810000,
832 "LXT970",
833
834 (const phy_cmd_t []) { /* config */
835 { mk_mii_read(MII_REG_CR), mii_parse_cr }, 844 { mk_mii_read(MII_REG_CR), mii_parse_cr },
836 { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, 845 { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
837 { mk_mii_end, } 846 { mk_mii_end, }
838 }, 847 };
839 (const phy_cmd_t []) { /* startup - enable interrupts */ 848static phy_cmd_t const phy_cmd_lxt970_startup[] = { /* enable interrupts */
840 { mk_mii_write(MII_LXT970_IER, 0x0002), NULL }, 849 { mk_mii_write(MII_LXT970_IER, 0x0002), NULL },
841 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ 850 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
842 { mk_mii_end, } 851 { mk_mii_end, }
843 }, 852 };
844 (const phy_cmd_t []) { /* ack_int */ 853static phy_cmd_t const phy_cmd_lxt970_ack_int[] = {
845 /* read SR and ISR to acknowledge */ 854 /* read SR and ISR to acknowledge */
846 { mk_mii_read(MII_REG_SR), mii_parse_sr }, 855 { mk_mii_read(MII_REG_SR), mii_parse_sr },
847 { mk_mii_read(MII_LXT970_ISR), NULL }, 856 { mk_mii_read(MII_LXT970_ISR), NULL },
@@ -849,11 +858,18 @@ static phy_info_t phy_info_lxt970 = {
849 /* find out the current status */ 858 /* find out the current status */
850 { mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr }, 859 { mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr },
851 { mk_mii_end, } 860 { mk_mii_end, }
852 }, 861 };
853 (const phy_cmd_t []) { /* shutdown - disable interrupts */ 862static phy_cmd_t const phy_cmd_lxt970_shutdown[] = { /* disable interrupts */
854 { mk_mii_write(MII_LXT970_IER, 0x0000), NULL }, 863 { mk_mii_write(MII_LXT970_IER, 0x0000), NULL },
855 { mk_mii_end, } 864 { mk_mii_end, }
856 }, 865 };
866static phy_info_t const phy_info_lxt970 = {
867 .id = 0x07810000,
868 .name = "LXT970",
869 .config = phy_cmd_lxt970_config,
870 .startup = phy_cmd_lxt970_startup,
871 .ack_int = phy_cmd_lxt970_ack_int,
872 .shutdown = phy_cmd_lxt970_shutdown
857}; 873};
858 874
859/* ------------------------------------------------------------------------- */ 875/* ------------------------------------------------------------------------- */
@@ -878,45 +894,44 @@ static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev)
878{ 894{
879 struct fec_enet_private *fep = netdev_priv(dev); 895 struct fec_enet_private *fep = netdev_priv(dev);
880 volatile uint *s = &(fep->phy_status); 896 volatile uint *s = &(fep->phy_status);
897 uint status;
881 898
882 *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); 899 status = *s & ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
883 900
884 if (mii_reg & 0x0400) { 901 if (mii_reg & 0x0400) {
885 fep->link = 1; 902 fep->link = 1;
886 *s |= PHY_STAT_LINK; 903 status |= PHY_STAT_LINK;
887 } else { 904 } else {
888 fep->link = 0; 905 fep->link = 0;
889 } 906 }
890 if (mii_reg & 0x0080) 907 if (mii_reg & 0x0080)
891 *s |= PHY_STAT_ANC; 908 status |= PHY_STAT_ANC;
892 if (mii_reg & 0x4000) { 909 if (mii_reg & 0x4000) {
893 if (mii_reg & 0x0200) 910 if (mii_reg & 0x0200)
894 *s |= PHY_STAT_100FDX; 911 status |= PHY_STAT_100FDX;
895 else 912 else
896 *s |= PHY_STAT_100HDX; 913 status |= PHY_STAT_100HDX;
897 } else { 914 } else {
898 if (mii_reg & 0x0200) 915 if (mii_reg & 0x0200)
899 *s |= PHY_STAT_10FDX; 916 status |= PHY_STAT_10FDX;
900 else 917 else
901 *s |= PHY_STAT_10HDX; 918 status |= PHY_STAT_10HDX;
902 } 919 }
903 if (mii_reg & 0x0008) 920 if (mii_reg & 0x0008)
904 *s |= PHY_STAT_FAULT; 921 status |= PHY_STAT_FAULT;
905}
906 922
907static phy_info_t phy_info_lxt971 = { 923 *s = status;
908 0x0001378e, 924}
909 "LXT971",
910 925
911 (const phy_cmd_t []) { /* config */ 926static phy_cmd_t const phy_cmd_lxt971_config[] = {
912 /* limit to 10MBit because my protorype board 927 /* limit to 10MBit because my prototype board
913 * doesn't work with 100. */ 928 * doesn't work with 100. */
914 { mk_mii_read(MII_REG_CR), mii_parse_cr }, 929 { mk_mii_read(MII_REG_CR), mii_parse_cr },
915 { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, 930 { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
916 { mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 }, 931 { mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },
917 { mk_mii_end, } 932 { mk_mii_end, }
918 }, 933 };
919 (const phy_cmd_t []) { /* startup - enable interrupts */ 934static phy_cmd_t const phy_cmd_lxt971_startup[] = { /* enable interrupts */
920 { mk_mii_write(MII_LXT971_IER, 0x00f2), NULL }, 935 { mk_mii_write(MII_LXT971_IER, 0x00f2), NULL },
921 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ 936 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
922 { mk_mii_write(MII_LXT971_LCR, 0xd422), NULL }, /* LED config */ 937 { mk_mii_write(MII_LXT971_LCR, 0xd422), NULL }, /* LED config */
@@ -925,19 +940,26 @@ static phy_info_t phy_info_lxt971 = {
925 * read here to get a valid value in ack_int */ 940 * read here to get a valid value in ack_int */
926 { mk_mii_read(MII_REG_SR), mii_parse_sr }, 941 { mk_mii_read(MII_REG_SR), mii_parse_sr },
927 { mk_mii_end, } 942 { mk_mii_end, }
928 }, 943 };
929 (const phy_cmd_t []) { /* ack_int */ 944static phy_cmd_t const phy_cmd_lxt971_ack_int[] = {
945 /* acknowledge the int before reading status ! */
946 { mk_mii_read(MII_LXT971_ISR), NULL },
930 /* find out the current status */ 947 /* find out the current status */
931 { mk_mii_read(MII_REG_SR), mii_parse_sr }, 948 { mk_mii_read(MII_REG_SR), mii_parse_sr },
932 { mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 }, 949 { mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },
933 /* we only need to read ISR to acknowledge */
934 { mk_mii_read(MII_LXT971_ISR), NULL },
935 { mk_mii_end, } 950 { mk_mii_end, }
936 }, 951 };
937 (const phy_cmd_t []) { /* shutdown - disable interrupts */ 952static phy_cmd_t const phy_cmd_lxt971_shutdown[] = { /* disable interrupts */
938 { mk_mii_write(MII_LXT971_IER, 0x0000), NULL }, 953 { mk_mii_write(MII_LXT971_IER, 0x0000), NULL },
939 { mk_mii_end, } 954 { mk_mii_end, }
940 }, 955 };
956static phy_info_t const phy_info_lxt971 = {
957 .id = 0x0001378e,
958 .name = "LXT971",
959 .config = phy_cmd_lxt971_config,
960 .startup = phy_cmd_lxt971_startup,
961 .ack_int = phy_cmd_lxt971_ack_int,
962 .shutdown = phy_cmd_lxt971_shutdown
941}; 963};
942 964
943/* ------------------------------------------------------------------------- */ 965/* ------------------------------------------------------------------------- */
@@ -956,22 +978,21 @@ static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev)
956{ 978{
957 struct fec_enet_private *fep = netdev_priv(dev); 979 struct fec_enet_private *fep = netdev_priv(dev);
958 volatile uint *s = &(fep->phy_status); 980 volatile uint *s = &(fep->phy_status);
981 uint status;
959 982
960 *s &= ~(PHY_STAT_SPMASK); 983 status = *s & ~(PHY_STAT_SPMASK);
961 984
962 switch((mii_reg >> 2) & 7) { 985 switch((mii_reg >> 2) & 7) {
963 case 1: *s |= PHY_STAT_10HDX; break; 986 case 1: status |= PHY_STAT_10HDX; break;
964 case 2: *s |= PHY_STAT_100HDX; break; 987 case 2: status |= PHY_STAT_100HDX; break;
965 case 5: *s |= PHY_STAT_10FDX; break; 988 case 5: status |= PHY_STAT_10FDX; break;
966 case 6: *s |= PHY_STAT_100FDX; break; 989 case 6: status |= PHY_STAT_100FDX; break;
967 }
968} 990}
969 991
970static phy_info_t phy_info_qs6612 = { 992 *s = status;
971 0x00181440, 993}
972 "QS6612", 994
973 995static phy_cmd_t const phy_cmd_qs6612_config[] = {
974 (const phy_cmd_t []) { /* config */
975 /* The PHY powers up isolated on the RPX, 996 /* The PHY powers up isolated on the RPX,
976 * so send a command to allow operation. 997 * so send a command to allow operation.
977 */ 998 */
@@ -981,13 +1002,13 @@ static phy_info_t phy_info_qs6612 = {
981 { mk_mii_read(MII_REG_CR), mii_parse_cr }, 1002 { mk_mii_read(MII_REG_CR), mii_parse_cr },
982 { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, 1003 { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
983 { mk_mii_end, } 1004 { mk_mii_end, }
984 }, 1005 };
985 (const phy_cmd_t []) { /* startup - enable interrupts */ 1006static phy_cmd_t const phy_cmd_qs6612_startup[] = { /* enable interrupts */
986 { mk_mii_write(MII_QS6612_IMR, 0x003a), NULL }, 1007 { mk_mii_write(MII_QS6612_IMR, 0x003a), NULL },
987 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ 1008 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
988 { mk_mii_end, } 1009 { mk_mii_end, }
989 }, 1010 };
990 (const phy_cmd_t []) { /* ack_int */ 1011static phy_cmd_t const phy_cmd_qs6612_ack_int[] = {
991 /* we need to read ISR, SR and ANER to acknowledge */ 1012 /* we need to read ISR, SR and ANER to acknowledge */
992 { mk_mii_read(MII_QS6612_ISR), NULL }, 1013 { mk_mii_read(MII_QS6612_ISR), NULL },
993 { mk_mii_read(MII_REG_SR), mii_parse_sr }, 1014 { mk_mii_read(MII_REG_SR), mii_parse_sr },
@@ -996,11 +1017,18 @@ static phy_info_t phy_info_qs6612 = {
996 /* read pcr to get info */ 1017 /* read pcr to get info */
997 { mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr }, 1018 { mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr },
998 { mk_mii_end, } 1019 { mk_mii_end, }
999 }, 1020 };
1000 (const phy_cmd_t []) { /* shutdown - disable interrupts */ 1021static phy_cmd_t const phy_cmd_qs6612_shutdown[] = { /* disable interrupts */
1001 { mk_mii_write(MII_QS6612_IMR, 0x0000), NULL }, 1022 { mk_mii_write(MII_QS6612_IMR, 0x0000), NULL },
1002 { mk_mii_end, } 1023 { mk_mii_end, }
1003 }, 1024 };
1025static phy_info_t const phy_info_qs6612 = {
1026 .id = 0x00181440,
1027 .name = "QS6612",
1028 .config = phy_cmd_qs6612_config,
1029 .startup = phy_cmd_qs6612_startup,
1030 .ack_int = phy_cmd_qs6612_ack_int,
1031 .shutdown = phy_cmd_qs6612_shutdown
1004}; 1032};
1005 1033
1006/* ------------------------------------------------------------------------- */ 1034/* ------------------------------------------------------------------------- */
@@ -1020,49 +1048,54 @@ static void mii_parse_am79c874_dr(uint mii_reg, struct net_device *dev)
1020{ 1048{
1021 struct fec_enet_private *fep = netdev_priv(dev); 1049 struct fec_enet_private *fep = netdev_priv(dev);
1022 volatile uint *s = &(fep->phy_status); 1050 volatile uint *s = &(fep->phy_status);
1051 uint status;
1023 1052
1024 *s &= ~(PHY_STAT_SPMASK | PHY_STAT_ANC); 1053 status = *s & ~(PHY_STAT_SPMASK | PHY_STAT_ANC);
1025 1054
1026 if (mii_reg & 0x0080) 1055 if (mii_reg & 0x0080)
1027 *s |= PHY_STAT_ANC; 1056 status |= PHY_STAT_ANC;
1028 if (mii_reg & 0x0400) 1057 if (mii_reg & 0x0400)
1029 *s |= ((mii_reg & 0x0800) ? PHY_STAT_100FDX : PHY_STAT_100HDX); 1058 status |= ((mii_reg & 0x0800) ? PHY_STAT_100FDX : PHY_STAT_100HDX);
1030 else 1059 else
1031 *s |= ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX); 1060 status |= ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX);
1061
1062 *s = status;
1032} 1063}
1033 1064
1034static phy_info_t phy_info_am79c874 = { 1065static phy_cmd_t const phy_cmd_am79c874_config[] = {
1035 0x00022561,
1036 "AM79C874",
1037
1038 (const phy_cmd_t []) { /* config */
1039 /* limit to 10MBit because my protorype board
1040 * doesn't work with 100. */
1041 { mk_mii_read(MII_REG_CR), mii_parse_cr }, 1066 { mk_mii_read(MII_REG_CR), mii_parse_cr },
1042 { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, 1067 { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
1043 { mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr }, 1068 { mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr },
1044 { mk_mii_end, } 1069 { mk_mii_end, }
1045 }, 1070 };
1046 (const phy_cmd_t []) { /* startup - enable interrupts */ 1071static phy_cmd_t const phy_cmd_am79c874_startup[] = { /* enable interrupts */
1047 { mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL }, 1072 { mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL },
1048 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ 1073 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
1049 { mk_mii_read(MII_REG_SR), mii_parse_sr }, 1074 { mk_mii_read(MII_REG_SR), mii_parse_sr },
1050 { mk_mii_end, } 1075 { mk_mii_end, }
1051 }, 1076 };
1052 (const phy_cmd_t []) { /* ack_int */ 1077static phy_cmd_t const phy_cmd_am79c874_ack_int[] = {
1053 /* find out the current status */ 1078 /* find out the current status */
1054 { mk_mii_read(MII_REG_SR), mii_parse_sr }, 1079 { mk_mii_read(MII_REG_SR), mii_parse_sr },
1055 { mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr }, 1080 { mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr },
1056 /* we only need to read ISR to acknowledge */ 1081 /* we only need to read ISR to acknowledge */
1057 { mk_mii_read(MII_AM79C874_ICSR), NULL }, 1082 { mk_mii_read(MII_AM79C874_ICSR), NULL },
1058 { mk_mii_end, } 1083 { mk_mii_end, }
1059 }, 1084 };
1060 (const phy_cmd_t []) { /* shutdown - disable interrupts */ 1085static phy_cmd_t const phy_cmd_am79c874_shutdown[] = { /* disable interrupts */
1061 { mk_mii_write(MII_AM79C874_ICSR, 0x0000), NULL }, 1086 { mk_mii_write(MII_AM79C874_ICSR, 0x0000), NULL },
1062 { mk_mii_end, } 1087 { mk_mii_end, }
1063 }, 1088 };
1089static phy_info_t const phy_info_am79c874 = {
1090 .id = 0x00022561,
1091 .name = "AM79C874",
1092 .config = phy_cmd_am79c874_config,
1093 .startup = phy_cmd_am79c874_startup,
1094 .ack_int = phy_cmd_am79c874_ack_int,
1095 .shutdown = phy_cmd_am79c874_shutdown
1064}; 1096};
1065 1097
1098
1066/* ------------------------------------------------------------------------- */ 1099/* ------------------------------------------------------------------------- */
1067/* Kendin KS8721BL phy */ 1100/* Kendin KS8721BL phy */
1068 1101
@@ -1072,37 +1105,40 @@ static phy_info_t phy_info_am79c874 = {
1072#define MII_KS8721BL_ICSR 22 1105#define MII_KS8721BL_ICSR 22
1073#define MII_KS8721BL_PHYCR 31 1106#define MII_KS8721BL_PHYCR 31
1074 1107
1075static phy_info_t phy_info_ks8721bl = { 1108static phy_cmd_t const phy_cmd_ks8721bl_config[] = {
1076 0x00022161,
1077 "KS8721BL",
1078
1079 (const phy_cmd_t []) { /* config */
1080 { mk_mii_read(MII_REG_CR), mii_parse_cr }, 1109 { mk_mii_read(MII_REG_CR), mii_parse_cr },
1081 { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, 1110 { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
1082 { mk_mii_end, } 1111 { mk_mii_end, }
1083 }, 1112 };
1084 (const phy_cmd_t []) { /* startup */ 1113static phy_cmd_t const phy_cmd_ks8721bl_startup[] = { /* enable interrupts */
1085 { mk_mii_write(MII_KS8721BL_ICSR, 0xff00), NULL }, 1114 { mk_mii_write(MII_KS8721BL_ICSR, 0xff00), NULL },
1086 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ 1115 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
1087 { mk_mii_read(MII_REG_SR), mii_parse_sr }, 1116 { mk_mii_read(MII_REG_SR), mii_parse_sr },
1088 { mk_mii_end, } 1117 { mk_mii_end, }
1089 }, 1118 };
1090 (const phy_cmd_t []) { /* ack_int */ 1119static phy_cmd_t const phy_cmd_ks8721bl_ack_int[] = {
1091 /* find out the current status */ 1120 /* find out the current status */
1092 { mk_mii_read(MII_REG_SR), mii_parse_sr }, 1121 { mk_mii_read(MII_REG_SR), mii_parse_sr },
1093 /* we only need to read ISR to acknowledge */ 1122 /* we only need to read ISR to acknowledge */
1094 { mk_mii_read(MII_KS8721BL_ICSR), NULL }, 1123 { mk_mii_read(MII_KS8721BL_ICSR), NULL },
1095 { mk_mii_end, } 1124 { mk_mii_end, }
1096 }, 1125 };
1097 (const phy_cmd_t []) { /* shutdown */ 1126static phy_cmd_t const phy_cmd_ks8721bl_shutdown[] = { /* disable interrupts */
1098 { mk_mii_write(MII_KS8721BL_ICSR, 0x0000), NULL }, 1127 { mk_mii_write(MII_KS8721BL_ICSR, 0x0000), NULL },
1099 { mk_mii_end, } 1128 { mk_mii_end, }
1100 }, 1129 };
1130static phy_info_t const phy_info_ks8721bl = {
1131 .id = 0x00022161,
1132 .name = "KS8721BL",
1133 .config = phy_cmd_ks8721bl_config,
1134 .startup = phy_cmd_ks8721bl_startup,
1135 .ack_int = phy_cmd_ks8721bl_ack_int,
1136 .shutdown = phy_cmd_ks8721bl_shutdown
1101}; 1137};
1102 1138
1103/* ------------------------------------------------------------------------- */ 1139/* ------------------------------------------------------------------------- */
1104 1140
1105static phy_info_t *phy_info[] = { 1141static phy_info_t const * const phy_info[] = {
1106 &phy_info_lxt970, 1142 &phy_info_lxt970,
1107 &phy_info_lxt971, 1143 &phy_info_lxt971,
1108 &phy_info_qs6612, 1144 &phy_info_qs6612,
@@ -1129,16 +1165,23 @@ mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs);
1129static void __inline__ fec_request_intrs(struct net_device *dev) 1165static void __inline__ fec_request_intrs(struct net_device *dev)
1130{ 1166{
1131 volatile unsigned long *icrp; 1167 volatile unsigned long *icrp;
1168 static const struct idesc {
1169 char *name;
1170 unsigned short irq;
1171 irqreturn_t (*handler)(int, void *, struct pt_regs *);
1172 } *idp, id[] = {
1173 { "fec(RX)", 86, fec_enet_interrupt },
1174 { "fec(TX)", 87, fec_enet_interrupt },
1175 { "fec(OTHER)", 88, fec_enet_interrupt },
1176 { "fec(MII)", 66, mii_link_interrupt },
1177 { NULL },
1178 };
1132 1179
1133 /* Setup interrupt handlers. */ 1180 /* Setup interrupt handlers. */
1134 if (request_irq(86, fec_enet_interrupt, 0, "fec(RX)", dev) != 0) 1181 for (idp = id; idp->name; idp++) {
1135 printk("FEC: Could not allocate FEC(RC) IRQ(86)!\n"); 1182 if (request_irq(idp->irq, idp->handler, 0, idp->name, dev) != 0)
1136 if (request_irq(87, fec_enet_interrupt, 0, "fec(TX)", dev) != 0) 1183 printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, idp->irq);
1137 printk("FEC: Could not allocate FEC(RC) IRQ(87)!\n"); 1184 }
1138 if (request_irq(88, fec_enet_interrupt, 0, "fec(OTHER)", dev) != 0)
1139 printk("FEC: Could not allocate FEC(OTHER) IRQ(88)!\n");
1140 if (request_irq(66, mii_link_interrupt, 0, "fec(MII)", dev) != 0)
1141 printk("FEC: Could not allocate MII IRQ(66)!\n");
1142 1185
1143 /* Unmask interrupt at ColdFire 5272 SIM */ 1186 /* Unmask interrupt at ColdFire 5272 SIM */
1144 icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3); 1187 icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3);
@@ -1169,17 +1212,16 @@ static void __inline__ fec_get_mac(struct net_device *dev)
1169{ 1212{
1170 struct fec_enet_private *fep = netdev_priv(dev); 1213 struct fec_enet_private *fep = netdev_priv(dev);
1171 volatile fec_t *fecp; 1214 volatile fec_t *fecp;
1172 unsigned char *iap, tmpaddr[6]; 1215 unsigned char *iap, tmpaddr[ETH_ALEN];
1173 int i;
1174 1216
1175 fecp = fep->hwp; 1217 fecp = fep->hwp;
1176 1218
1177 if (fec_flashmac) { 1219 if (FEC_FLASHMAC) {
1178 /* 1220 /*
1179 * Get MAC address from FLASH. 1221 * Get MAC address from FLASH.
1180 * If it is all 1's or 0's, use the default. 1222 * If it is all 1's or 0's, use the default.
1181 */ 1223 */
1182 iap = fec_flashmac; 1224 iap = (unsigned char *)FEC_FLASHMAC;
1183 if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && 1225 if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
1184 (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) 1226 (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
1185 iap = fec_mac_default; 1227 iap = fec_mac_default;
@@ -1192,14 +1234,11 @@ static void __inline__ fec_get_mac(struct net_device *dev)
1192 iap = &tmpaddr[0]; 1234 iap = &tmpaddr[0];
1193 } 1235 }
1194 1236
1195 for (i=0; i<ETH_ALEN; i++) 1237 memcpy(dev->dev_addr, iap, ETH_ALEN);
1196 dev->dev_addr[i] = fep->mac_addr[i] = *iap++;
1197 1238
1198 /* Adjust MAC if using default MAC address */ 1239 /* Adjust MAC if using default MAC address */
1199 if (iap == fec_mac_default) { 1240 if (iap == fec_mac_default)
1200 dev->dev_addr[ETH_ALEN-1] = fep->mac_addr[ETH_ALEN-1] = 1241 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
1201 iap[ETH_ALEN-1] + fep->index;
1202 }
1203} 1242}
1204 1243
1205static void __inline__ fec_enable_phy_intr(void) 1244static void __inline__ fec_enable_phy_intr(void)
@@ -1234,48 +1273,44 @@ static void __inline__ fec_uncache(unsigned long addr)
1234 1273
1235/* ------------------------------------------------------------------------- */ 1274/* ------------------------------------------------------------------------- */
1236 1275
1237#elif defined(CONFIG_M527x) || defined(CONFIG_M528x) 1276#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
1238 1277
1239/* 1278/*
1240 * Code specific to Coldfire 5270/5271/5274/5275 and 5280/5282 setups. 1279 * Code specific to Coldfire 5230/5231/5232/5234/5235,
1280 * the 5270/5271/5274/5275 and 5280/5282 setups.
1241 */ 1281 */
1242static void __inline__ fec_request_intrs(struct net_device *dev) 1282static void __inline__ fec_request_intrs(struct net_device *dev)
1243{ 1283{
1244 struct fec_enet_private *fep; 1284 struct fec_enet_private *fep;
1245 int b; 1285 int b;
1286 static const struct idesc {
1287 char *name;
1288 unsigned short irq;
1289 } *idp, id[] = {
1290 { "fec(TXF)", 23 },
1291 { "fec(TXB)", 24 },
1292 { "fec(TXFIFO)", 25 },
1293 { "fec(TXCR)", 26 },
1294 { "fec(RXF)", 27 },
1295 { "fec(RXB)", 28 },
1296 { "fec(MII)", 29 },
1297 { "fec(LC)", 30 },
1298 { "fec(HBERR)", 31 },
1299 { "fec(GRA)", 32 },
1300 { "fec(EBERR)", 33 },
1301 { "fec(BABT)", 34 },
1302 { "fec(BABR)", 35 },
1303 { NULL },
1304 };
1246 1305
1247 fep = netdev_priv(dev); 1306 fep = netdev_priv(dev);
1248 b = (fep->index) ? 128 : 64; 1307 b = (fep->index) ? 128 : 64;
1249 1308
1250 /* Setup interrupt handlers. */ 1309 /* Setup interrupt handlers. */
1251 if (request_irq(b+23, fec_enet_interrupt, 0, "fec(TXF)", dev) != 0) 1310 for (idp = id; idp->name; idp++) {
1252 printk("FEC: Could not allocate FEC(TXF) IRQ(%d+23)!\n", b); 1311 if (request_irq(b+idp->irq, fec_enet_interrupt, 0, idp->name, dev) != 0)
1253 if (request_irq(b+24, fec_enet_interrupt, 0, "fec(TXB)", dev) != 0) 1312 printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
1254 printk("FEC: Could not allocate FEC(TXB) IRQ(%d+24)!\n", b); 1313 }
1255 if (request_irq(b+25, fec_enet_interrupt, 0, "fec(TXFIFO)", dev) != 0)
1256 printk("FEC: Could not allocate FEC(TXFIFO) IRQ(%d+25)!\n", b);
1257 if (request_irq(b+26, fec_enet_interrupt, 0, "fec(TXCR)", dev) != 0)
1258 printk("FEC: Could not allocate FEC(TXCR) IRQ(%d+26)!\n", b);
1259
1260 if (request_irq(b+27, fec_enet_interrupt, 0, "fec(RXF)", dev) != 0)
1261 printk("FEC: Could not allocate FEC(RXF) IRQ(%d+27)!\n", b);
1262 if (request_irq(b+28, fec_enet_interrupt, 0, "fec(RXB)", dev) != 0)
1263 printk("FEC: Could not allocate FEC(RXB) IRQ(%d+28)!\n", b);
1264
1265 if (request_irq(b+29, fec_enet_interrupt, 0, "fec(MII)", dev) != 0)
1266 printk("FEC: Could not allocate FEC(MII) IRQ(%d+29)!\n", b);
1267 if (request_irq(b+30, fec_enet_interrupt, 0, "fec(LC)", dev) != 0)
1268 printk("FEC: Could not allocate FEC(LC) IRQ(%d+30)!\n", b);
1269 if (request_irq(b+31, fec_enet_interrupt, 0, "fec(HBERR)", dev) != 0)
1270 printk("FEC: Could not allocate FEC(HBERR) IRQ(%d+31)!\n", b);
1271 if (request_irq(b+32, fec_enet_interrupt, 0, "fec(GRA)", dev) != 0)
1272 printk("FEC: Could not allocate FEC(GRA) IRQ(%d+32)!\n", b);
1273 if (request_irq(b+33, fec_enet_interrupt, 0, "fec(EBERR)", dev) != 0)
1274 printk("FEC: Could not allocate FEC(EBERR) IRQ(%d+33)!\n", b);
1275 if (request_irq(b+34, fec_enet_interrupt, 0, "fec(BABT)", dev) != 0)
1276 printk("FEC: Could not allocate FEC(BABT) IRQ(%d+34)!\n", b);
1277 if (request_irq(b+35, fec_enet_interrupt, 0, "fec(BABR)", dev) != 0)
1278 printk("FEC: Could not allocate FEC(BABR) IRQ(%d+35)!\n", b);
1279 1314
1280 /* Unmask interrupts at ColdFire 5280/5282 interrupt controller */ 1315 /* Unmask interrupts at ColdFire 5280/5282 interrupt controller */
1281 { 1316 {
@@ -1300,11 +1335,13 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
1300#if defined(CONFIG_M528x) 1335#if defined(CONFIG_M528x)
1301 /* Set up gpio outputs for MII lines */ 1336 /* Set up gpio outputs for MII lines */
1302 { 1337 {
1303 volatile unsigned short *gpio_paspar; 1338 volatile u16 *gpio_paspar;
1339 volatile u8 *gpio_pehlpar;
1304 1340
1305 gpio_paspar = (volatile unsigned short *) (MCF_IPSBAR + 1341 gpio_paspar = (volatile u16 *) (MCF_IPSBAR + 0x100056);
1306 0x100056); 1342 gpio_pehlpar = (volatile u16 *) (MCF_IPSBAR + 0x100058);
1307 *gpio_paspar = 0x0f00; 1343 *gpio_paspar |= 0x0f00;
1344 *gpio_pehlpar = 0xc0;
1308 } 1345 }
1309#endif 1346#endif
1310} 1347}
@@ -1331,17 +1368,16 @@ static void __inline__ fec_get_mac(struct net_device *dev)
1331{ 1368{
1332 struct fec_enet_private *fep = netdev_priv(dev); 1369 struct fec_enet_private *fep = netdev_priv(dev);
1333 volatile fec_t *fecp; 1370 volatile fec_t *fecp;
1334 unsigned char *iap, tmpaddr[6]; 1371 unsigned char *iap, tmpaddr[ETH_ALEN];
1335 int i;
1336 1372
1337 fecp = fep->hwp; 1373 fecp = fep->hwp;
1338 1374
1339 if (fec_flashmac) { 1375 if (FEC_FLASHMAC) {
1340 /* 1376 /*
1341 * Get MAC address from FLASH. 1377 * Get MAC address from FLASH.
1342 * If it is all 1's or 0's, use the default. 1378 * If it is all 1's or 0's, use the default.
1343 */ 1379 */
1344 iap = fec_flashmac; 1380 iap = FEC_FLASHMAC;
1345 if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && 1381 if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
1346 (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) 1382 (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
1347 iap = fec_mac_default; 1383 iap = fec_mac_default;
@@ -1354,14 +1390,11 @@ static void __inline__ fec_get_mac(struct net_device *dev)
1354 iap = &tmpaddr[0]; 1390 iap = &tmpaddr[0];
1355 } 1391 }
1356 1392
1357 for (i=0; i<ETH_ALEN; i++) 1393 memcpy(dev->dev_addr, iap, ETH_ALEN);
1358 dev->dev_addr[i] = fep->mac_addr[i] = *iap++;
1359 1394
1360 /* Adjust MAC if using default MAC address */ 1395 /* Adjust MAC if using default MAC address */
1361 if (iap == fec_mac_default) { 1396 if (iap == fec_mac_default)
1362 dev->dev_addr[ETH_ALEN-1] = fep->mac_addr[ETH_ALEN-1] = 1397 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
1363 iap[ETH_ALEN-1] + fep->index;
1364 }
1365} 1398}
1366 1399
1367static void __inline__ fec_enable_phy_intr(void) 1400static void __inline__ fec_enable_phy_intr(void)
@@ -1392,7 +1425,7 @@ static void __inline__ fec_uncache(unsigned long addr)
1392#else 1425#else
1393 1426
1394/* 1427/*
1395 * Code sepcific to the MPC860T setup. 1428 * Code specific to the MPC860T setup.
1396 */ 1429 */
1397static void __inline__ fec_request_intrs(struct net_device *dev) 1430static void __inline__ fec_request_intrs(struct net_device *dev)
1398{ 1431{
@@ -1424,13 +1457,10 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
1424 1457
1425static void __inline__ fec_get_mac(struct net_device *dev) 1458static void __inline__ fec_get_mac(struct net_device *dev)
1426{ 1459{
1427 struct fec_enet_private *fep = netdev_priv(dev);
1428 unsigned char *iap, tmpaddr[6];
1429 bd_t *bd; 1460 bd_t *bd;
1430 int i;
1431 1461
1432 iap = bd->bi_enetaddr;
1433 bd = (bd_t *)__res; 1462 bd = (bd_t *)__res;
1463 memcpy(dev->dev_addr, bd->bi_enetaddr, ETH_ALEN);
1434 1464
1435#ifdef CONFIG_RPXCLASSIC 1465#ifdef CONFIG_RPXCLASSIC
1436 /* The Embedded Planet boards have only one MAC address in 1466 /* The Embedded Planet boards have only one MAC address in
@@ -1439,14 +1469,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
1439 * the address bits above something that would have (up to 1469 * the address bits above something that would have (up to
1440 * now) been allocated. 1470 * now) been allocated.
1441 */ 1471 */
1442 for (i=0; i<6; i++) 1472 dev->dev_adrd[3] |= 0x80;
1443 tmpaddr[i] = *iap++;
1444 tmpaddr[3] |= 0x80;
1445 iap = tmpaddr;
1446#endif 1473#endif
1447
1448 for (i=0; i<6; i++)
1449 dev->dev_addr[i] = fep->mac_addr[i] = *iap++;
1450} 1474}
1451 1475
1452static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) 1476static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
@@ -1556,7 +1580,7 @@ static void mii_display_status(struct net_device *dev)
1556static void mii_display_config(struct net_device *dev) 1580static void mii_display_config(struct net_device *dev)
1557{ 1581{
1558 struct fec_enet_private *fep = netdev_priv(dev); 1582 struct fec_enet_private *fep = netdev_priv(dev);
1559 volatile uint *s = &(fep->phy_status); 1583 uint status = fep->phy_status;
1560 1584
1561 /* 1585 /*
1562 ** When we get here, phy_task is already removed from 1586 ** When we get here, phy_task is already removed from
@@ -1565,23 +1589,23 @@ static void mii_display_config(struct net_device *dev)
1565 fep->mii_phy_task_queued = 0; 1589 fep->mii_phy_task_queued = 0;
1566 printk("%s: config: auto-negotiation ", dev->name); 1590 printk("%s: config: auto-negotiation ", dev->name);
1567 1591
1568 if (*s & PHY_CONF_ANE) 1592 if (status & PHY_CONF_ANE)
1569 printk("on"); 1593 printk("on");
1570 else 1594 else
1571 printk("off"); 1595 printk("off");
1572 1596
1573 if (*s & PHY_CONF_100FDX) 1597 if (status & PHY_CONF_100FDX)
1574 printk(", 100FDX"); 1598 printk(", 100FDX");
1575 if (*s & PHY_CONF_100HDX) 1599 if (status & PHY_CONF_100HDX)
1576 printk(", 100HDX"); 1600 printk(", 100HDX");
1577 if (*s & PHY_CONF_10FDX) 1601 if (status & PHY_CONF_10FDX)
1578 printk(", 10FDX"); 1602 printk(", 10FDX");
1579 if (*s & PHY_CONF_10HDX) 1603 if (status & PHY_CONF_10HDX)
1580 printk(", 10HDX"); 1604 printk(", 10HDX");
1581 if (!(*s & PHY_CONF_SPMASK)) 1605 if (!(status & PHY_CONF_SPMASK))
1582 printk(", No speed/duplex selected?"); 1606 printk(", No speed/duplex selected?");
1583 1607
1584 if (*s & PHY_CONF_LOOP) 1608 if (status & PHY_CONF_LOOP)
1585 printk(", loopback enabled"); 1609 printk(", loopback enabled");
1586 1610
1587 printk(".\n"); 1611 printk(".\n");
@@ -1639,7 +1663,7 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
1639 schedule_work(&fep->phy_task); 1663 schedule_work(&fep->phy_task);
1640} 1664}
1641 1665
1642/* mii_queue_config is called in user context from fec_enet_open */ 1666/* mii_queue_config is called in interrupt context from fec_enet_mii */
1643static void mii_queue_config(uint mii_reg, struct net_device *dev) 1667static void mii_queue_config(uint mii_reg, struct net_device *dev)
1644{ 1668{
1645 struct fec_enet_private *fep = netdev_priv(dev); 1669 struct fec_enet_private *fep = netdev_priv(dev);
@@ -1652,14 +1676,14 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev)
1652 schedule_work(&fep->phy_task); 1676 schedule_work(&fep->phy_task);
1653} 1677}
1654 1678
1655 1679phy_cmd_t const phy_cmd_relink[] = {
1656 1680 { mk_mii_read(MII_REG_CR), mii_queue_relink },
1657phy_cmd_t phy_cmd_relink[] = { { mk_mii_read(MII_REG_CR), mii_queue_relink }, 1681 { mk_mii_end, }
1658 { mk_mii_end, } }; 1682 };
1659phy_cmd_t phy_cmd_config[] = { { mk_mii_read(MII_REG_CR), mii_queue_config }, 1683phy_cmd_t const phy_cmd_config[] = {
1660 { mk_mii_end, } }; 1684 { mk_mii_read(MII_REG_CR), mii_queue_config },
1661 1685 { mk_mii_end, }
1662 1686 };
1663 1687
1664/* Read remainder of PHY ID. 1688/* Read remainder of PHY ID.
1665*/ 1689*/
@@ -1897,17 +1921,15 @@ static void set_multicast_list(struct net_device *dev)
1897static void 1921static void
1898fec_set_mac_address(struct net_device *dev) 1922fec_set_mac_address(struct net_device *dev)
1899{ 1923{
1900 struct fec_enet_private *fep;
1901 volatile fec_t *fecp; 1924 volatile fec_t *fecp;
1902 1925
1903 fep = netdev_priv(dev); 1926 fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp;
1904 fecp = fep->hwp;
1905 1927
1906 /* Set station address. */ 1928 /* Set station address. */
1907 fecp->fec_addr_low = fep->mac_addr[3] | (fep->mac_addr[2] << 8) | 1929 fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
1908 (fep->mac_addr[1] << 16) | (fep->mac_addr[0] << 24); 1930 (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24);
1909 fecp->fec_addr_high = (fep->mac_addr[5] << 16) | 1931 fecp->fec_addr_high = (dev->dev_addr[5] << 16) |
1910 (fep->mac_addr[4] << 24); 1932 (dev->dev_addr[4] << 24);
1911 1933
1912} 1934}
1913 1935
@@ -1943,7 +1965,7 @@ int __init fec_enet_init(struct net_device *dev)
1943 udelay(10); 1965 udelay(10);
1944 1966
1945 /* Clear and enable interrupts */ 1967 /* Clear and enable interrupts */
1946 fecp->fec_ievent = 0xffc0; 1968 fecp->fec_ievent = 0xffc00000;
1947 fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | 1969 fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
1948 FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); 1970 FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
1949 fecp->fec_hash_table_high = 0; 1971 fecp->fec_hash_table_high = 0;
@@ -2063,11 +2085,6 @@ int __init fec_enet_init(struct net_device *dev)
2063 /* setup MII interface */ 2085 /* setup MII interface */
2064 fec_set_mii(dev, fep); 2086 fec_set_mii(dev, fep);
2065 2087
2066 printk("%s: FEC ENET Version 0.2, ", dev->name);
2067 for (i=0; i<5; i++)
2068 printk("%02x:", dev->dev_addr[i]);
2069 printk("%02x\n", dev->dev_addr[5]);
2070
2071 /* Queue up command to detect the PHY and initialize the 2088 /* Queue up command to detect the PHY and initialize the
2072 * remainder of the interface. 2089 * remainder of the interface.
2073 */ 2090 */
@@ -2106,18 +2123,12 @@ fec_restart(struct net_device *dev, int duplex)
2106 2123
2107 /* Clear any outstanding interrupt. 2124 /* Clear any outstanding interrupt.
2108 */ 2125 */
2109 fecp->fec_ievent = 0xffc0; 2126 fecp->fec_ievent = 0xffc00000;
2110 fec_enable_phy_intr(); 2127 fec_enable_phy_intr();
2111 2128
2112 /* Set station address. 2129 /* Set station address.
2113 */ 2130 */
2114 fecp->fec_addr_low = fep->mac_addr[3] | (fep->mac_addr[2] << 8) | 2131 fec_set_mac_address(dev);
2115 (fep->mac_addr[1] << 16) | (fep->mac_addr[0] << 24);
2116 fecp->fec_addr_high = (fep->mac_addr[5] << 16) |
2117 (fep->mac_addr[4] << 24);
2118
2119 for (i=0; i<ETH_ALEN; i++)
2120 dev->dev_addr[i] = fep->mac_addr[i];
2121 2132
2122 /* Reset all multicast. 2133 /* Reset all multicast.
2123 */ 2134 */
@@ -2215,7 +2226,7 @@ fec_stop(struct net_device *dev)
2215 2226
2216 fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ 2227 fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */
2217 2228
2218 while(!(fecp->fec_ievent & 0x10000000)); 2229 while(!(fecp->fec_ievent & FEC_ENET_GRA));
2219 2230
2220 /* Whack a reset. We should wait for this. 2231 /* Whack a reset. We should wait for this.
2221 */ 2232 */
@@ -2234,7 +2245,9 @@ fec_stop(struct net_device *dev)
2234static int __init fec_enet_module_init(void) 2245static int __init fec_enet_module_init(void)
2235{ 2246{
2236 struct net_device *dev; 2247 struct net_device *dev;
2237 int i, err; 2248 int i, j, err;
2249
2250 printk("FEC ENET Version 0.2\n");
2238 2251
2239 for (i = 0; (i < FEC_MAX_PORTS); i++) { 2252 for (i = 0; (i < FEC_MAX_PORTS); i++) {
2240 dev = alloc_etherdev(sizeof(struct fec_enet_private)); 2253 dev = alloc_etherdev(sizeof(struct fec_enet_private));
@@ -2250,6 +2263,11 @@ static int __init fec_enet_module_init(void)
2250 free_netdev(dev); 2263 free_netdev(dev);
2251 return -EIO; 2264 return -EIO;
2252 } 2265 }
2266
2267 printk("%s: ethernet ", dev->name);
2268 for (j = 0; (j < 5); j++)
2269 printk("%02x:", dev->dev_addr[j]);
2270 printk("%02x\n", dev->dev_addr[5]);
2253 } 2271 }
2254 return 0; 2272 return 0;
2255} 2273}