[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] FEC Ethernet driver patch for Coldfires



Hi,

please find attached a patch to the Coldfire FEC ethernet driver. While the Firebee functionality is untouched, it adds a machine detection (evaluate MCH_ cookie) and initialisation of the Broadcom bcm5222 ethernet PHY (instead of the am79c874 which is the corresponding Firebee part) for the m548x eval boards if the machine found is not a Firebee (Falcon).

Goal is to make the m548x eval board a "headless MiNT machine".

The patch could not be tested much (the m548x currently still dies too soon in the MiNT boot process to really test anything but it seems to initialise the FEC correctly). I have made sure that Firebee operation is unaffected by this change.

The bcm5222.? files need to be added to the sys/sockets/xif/fec dir.

Cheers,
Markus


P.S.:The m548x boot log with current state on the m548x:


call EmuTOS
unit 18 is managed by EmuTOS internal drivers: SanDisk SDCFX-032G
hda: DOS MBR byteswapped signature detected: enabling byteswap
 MBR $06 $06 $83 $83






   __________________________________

   EmuTOS Version: (CVS 2015-02-14)
   CPU type:       ColdFire V4e
   Machine:        M5484LITE
   Free ST-RAM:    14218 kB
   Free FastRAM:   47104 kB
   Screen start:   0x00df8000
   GEMDOS drives:  CDEF
   Boot time:      2015/02/14 00:00:00
   __________________________________

   Hold <Control> to skip AUTO/ACC
   Hold <Alternate> to skip HDD boot
   Press 'C' to run an early console



ColdBoot 0.2 - 2012-02-04320x200@4 0
retrieve BaS driver interface
BaS driver table found at 0x3e003e8, BaS version is 0.87
driver "SDCARD (BaS SD Card driver)" found,
interface type is 2 (XHDI compatible hard disk driver),
version 0.1

driver "MCDDMA (BaS Multichannel DMA driver)" found,
interface type is 3 (multichannel DMA driver),
version 0.1


DMAC cookie set to 0x3e00010
driver "RADEON (BaS RADEON framebuffer driver)" found,
interface type is 4 (video/framebuffer driver),
version 0.1

driver "PCI (BaS PCI_BIOS driver)" found,
interface type is 5 (PCI interface driver),
version 0.1

driver "MMU (BaS MMU driver)" found,
interface type is 6 (MMU lock/unlock pages driver),
version 0.1

driver "PCI_N (BaS PCI native)" found,
interface type is 7 (PCI interface native driver),
version 0.1

BAS_ cookie set to 0x3e003e8
GCC FOLDRNNN: add GEMDOS folder memory

 This is FreeMiNT v1.19.0-ALPHA
compiled Feb 15 2015

FreeMiNT is a modified version of MiNT

MiNT � 1990,1991,1992 Eric R. Smith
MultiTOS kernel
     � 1992,1993,1994 Atari Corporation
All Rights Reserved.
  Use this program at your own risk!

Reading `\mint\1-19-cur\mint.ini' ... done

Hold down the SHIFT key to enter menu or wait 1 s.

Unknown clone (ColdFire V4e CPU/MMU/FPU) (_MCH 0xFFFFFFFF)

Keyboard nationality code: 0
Language preference code: 0
Entering supervisor mode ... done!
Booting from 'c'
Resident TOS version 2.06
Kbshft 0x00000800.
BIOS Bconmap() not present.
Initializing system components:
Core: 14559620 B (lost 2436 B)
Alt: 47527324 B
realloc_region: reg = 0, newsize -2147483648
realloc_region: reg is NULL
This system features XHDI level 1.30 (kerinfo rejected).

              *** WARNING! ***
 This software contains strong cryptography.
 Depending on where you live, exporting it
 or using might be illegal.
    *** Thus, do so at your own risk ***

 dynamic RAM filesystem driver version 0.72
� 2000-2010 by Frank Naumann.

 FAT/VFAT/FAT32 filesystem version 1.27
� 2000-2010 by Frank Naumann.

Installing BIOS keyboard table ... AKP 0, ISO 0.

Calibrating delay loop ... 199.88 BogoMIPS

 High quality random number generator
 courtesy of Theodore Ts'o.
 Copyright � 1994-1998 Theodore Ts'o
 All Rights Reserved.
 See the file COPYRAND for details.

Initializing built-in domain ops ... done!
Loading external modules ...

pid 0 (MiNT): FAT-FS [C]: WARNING: mounting unchecked fs, running dosfsck is recommended
 MiNT-Net TCP/IP 1.6 PL 1,
 1993-1996 by Kay Roemer.
 1997-1999 by Torsten Lang.
 2000-2010 by Frank Naumann.

Loading interfaces:
FEC Ethernet driver (m548x) v0.1  (eth0 - 00:CF:54:00:C6:0B)
IP  masquerading by Mario Becroft, 1999.
FTP masquerading support by Torsten Lang, 1999.

 xconout2 output catcher version 0.3
� Jan  1 1995 by TeSche <itschere@techfak.uni-bielefeld.de>
� 2000-2010 by Frank Naumann.

 Network file system driver version 0.57
� 1993, 1994 by Ulrich K�hn.
� 2000-2010 by Frank Naumann.
See the file COPYING for copying and using conditions.

pid   0 (MiNT): nfs (main.c): running in native UTC mode!
pid   0 (MiNT): open_connection: got socket 3DFE544
 Ext2 filesystem driver version 0.63
� 1998, 1999 by Axel Kaiser.
� 2000-2010 by Frank Naumann.
� 2013 by Alan Hourihane.

pid   0 (MiNT): ext2 (main.c): init
pid   0 (MiNT): ext2 (main.c): running in native UTC mode!
pid   0 (MiNT): ext2 (main.c): loaded and ready (k = 1076734) -> 3D9671C.

Starting up the update daemon ... done!
Starting up the idle process (pid 0) ... done!
Installing keyboard table `u:/c/mint/1-19-cur/keyboard.tbl' ... AKP 1, ISO 0.


Reading `u:/c/mint/1-19-cur/mint.cnf' ... 7926 bytes done.

KERN_SLICES=2
KERN_BIOSBUF=YES
TPA_INITIALMEM=8192
FS_NEWFATFS=A,C,E,F,G
NEWFATFS is default filesystem for all drives!
FS_VFAT=A,D,E,F,G,H,I,J
VFAT active: ADEFGHIJ
FS_WB_ENABLE=D,E,F,G,H,I,J
WB CACHE active: DEFGHIJ
setenv UNIXMODE /brUs
setenv PATH /bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
setenv HOME u:/home/mfro
include u:/c/mint/sys.cnf

Reading `u:/c/mint/sys.cnf' ... 38 bytes done.

sln u:/e/etc u:/etc
include u:/c/mint/unix.cnf

Reading `u:/c/mint/unix.cnf' ... 316 bytes done.

echo "initializing Unix-style environment"
initializing Unix-style environment
sln u:/e/bin u:/bin
sln u:/e/usr u:/usr
sln u:/e/tmp u:/tmp
sln u:/e/home u:/home
sln u:/e/var u:/var
cd u:
cd u:/home/mfro
pid 0 (MiNT): Ext2-FS [E]: WARNING: mounting unchecked fs, running e2fsck is recommended
setenv HOME /home/mfro
setenv USER mfro
setenv PATH /usr:/usr/bin:/bin:/sbin:/usr/sbin:/usr/local/bin:.
setenv UNIXMODE /brUs
include u:/c/mint/network.cnf

Reading `u:/c/mint/network.cnf' ... 477 bytes done.

echo "Starting Networking"
Starting Networking
exec /usr/sbin/ifconfig eth0 addr 192.168.1.102
pid   3 (ifconfig): PHY reset

pid   3 (ifconfig): PHY reset OK

pid   3 (ifconfig): PHY Enable Auto-Negotiation

pid   3 (ifconfig): PHY Wait for auto-negotiation to complete

pid   3 (ifconfig): PHY auto-negociation complete

pid   3 (ifconfig): PHY Mode:
pid   3 (ifconfig): 100Mbps

pid   3 (ifconfig): Full-duplex

exec /usr/sbin/route add default eth0 gw 192.168.1.1
exec /usr/sbin/mount_nfs xxxx:/home/mfro u:/nfs/mfro

/*
 * File:        bcm5222.c
 * Purpose:     Driver for the Micrel BCM5222 10/100 Ethernet PHY
 *
 * Notes:       This driver was written specifically for the M5475EVB
 *              and M5485EVB.  These boards use the MII signals from
 *              FEC0 to control the PHY.  Therefore the fec_ch parameter
 *              is ignored when doing MII reads and writes.
 */

#include "buf.h"
#include "inet4/if.h"
#include "inet4/ifeth.h"
#include "netinfo.h"
#include "mint/sockio.h"



#include "platform/board.h"
#include "fec.h"
#include "bcm5222.h"


/*
 * Initialize the BCM5222 PHY
 *
 * This function sets up the Auto-Negotiate Advertisement register
 * within the PHY and then forces the PHY to auto-negotiate for
 * it's settings.
 *
 * Params:
 *  fec_ch      FEC channel
 *  phy_addr    Address of the PHY.
 *  speed       Desired speed (10BaseT or 100BaseTX)
 *  duplex      Desired duplex (Full or Half)
 *
 * Return Value:
 *  0 if MII commands fail
 *  1 otherwise
 */
int bcm5222_init(uint8 fec_ch, uint8 phy_addr, uint8 speed, uint8 duplex)
{
	int timeout;
	uint16 settings;

	/* Initialize the MII interface */
	fec_mii_init(fec_ch, SYSTEM_CLOCK);
	KDEBUG(("PHY reset\r\n"));

	/* Reset the PHY */
	if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, BCM5222_CTRL_RESET | BCM5222_CTRL_ANE))
		return 0;

	/* Wait for the PHY to reset */
	for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++)
	{
		fec_mii_read(fec_ch, phy_addr, BCM5222_CTRL, &settings);
		if (!(settings & BCM5222_CTRL_RESET))
			break;
	}
	if(timeout >= FEC_MII_TIMEOUT)
		return 0;

	KDEBUG(("PHY reset OK\r\n"));

	settings = (BCM5222_AN_ADV_NEXT_PAGE | BCM5222_AN_ADV_PAUSE);

	if (speed == FEC_MII_10BASE_T)
		settings |= (uint16)((duplex == FEC_MII_FULL_DUPLEX)
				? (BCM5222_AN_ADV_10BT_FDX | BCM5222_AN_ADV_10BT)
				: BCM5222_AN_ADV_10BT);
	else /* (speed == FEC_MII_100BASE_TX) */
		settings = (uint16)((duplex == FEC_MII_FULL_DUPLEX)
				? (BCM5222_AN_ADV_100BTX_FDX | BCM5222_AN_ADV_100BTX
					| BCM5222_AN_ADV_10BT_FDX | BCM5222_AN_ADV_10BT)
				: (BCM5222_AN_ADV_100BTX | BCM5222_AN_ADV_10BT));

	/* Set the Auto-Negotiation Advertisement Register */
	if (!fec_mii_write(fec_ch, phy_addr, BCM5222_AN_ADV, settings))
		return 0;

	KDEBUG(("PHY Enable Auto-Negotiation\r\n"));

	/* Enable Auto-Negotiation */
	if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, (BCM5222_CTRL_ANE | BCM5222_CTRL_RESTART_AN)))
		return 0;

	KDEBUG(("PHY Wait for auto-negotiation to complete\r\n"));

	/* Wait for auto-negotiation to complete */
	for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++)
	{
		if (!fec_mii_read(fec_ch, phy_addr, BCM5222_STAT, &settings))
			return 0;
		if (settings & BCM5222_STAT_AN_COMPLETE)
			break;
	}

	if (timeout < FEC_MII_TIMEOUT)
	{
		KDEBUG(("PHY auto-negociation complete\r\n"));

		/* Read Auxiliary Control/Status Register */
		if (!fec_mii_read(fec_ch, phy_addr, BCM5222_ACSR, &settings))
			return 0;
	}
	else
	{
		KDEBUG(("auto negotiation failed, PHY Set the default mode\r\n"));

		/* Set the default mode (Full duplex, 100 Mbps) */
		if (!fec_mii_write(fec_ch, phy_addr, BCM5222_ACSR, settings = (BCM5222_ACSR_100BTX | BCM5222_ACSR_FDX)))
			return 0;
	}

	/* Set the proper duplex in the FEC now that we have auto-negotiated */
	if (settings & BCM5222_ACSR_FDX)
		fec_duplex(fec_ch, FEC_MII_FULL_DUPLEX);
	else
		fec_duplex(fec_ch, FEC_MII_HALF_DUPLEX);

	KDEBUG(("PHY Mode: "));

    if (settings & BCM5222_ACSR_100BTX)
        KDEBUG(("100Mbps\r\n"));
    else
        KDEBUG(("10Mbps\r\n"));

    if (settings & BCM5222_ACSR_FDX)
        KDEBUG(("Full-duplex\r\n"));
    else
        KDEBUG(("Half-duplex\r\n"));

    return 1;
}

void bcm5222_get_reg(uint16 *status0, uint16 *status1)
{
	fec_mii_read(0, 0x00, 0x00000000, &status0[0]);
	fec_mii_read(0, 0x00, 0x00000001, &status0[1]);
	fec_mii_read(0, 0x00, 0x00000004, &status0[4]);
	fec_mii_read(0, 0x00, 0x00000005, &status0[5]);
	fec_mii_read(0, 0x00, 0x00000006, &status0[6]);
	fec_mii_read(0, 0x00, 0x00000007, &status0[7]);
	fec_mii_read(0, 0x00, 0x00000008, &status0[8]);
	fec_mii_read(0, 0x00, 0x00000010, &status0[16]);
	fec_mii_read(0, 0x00, 0x00000011, &status0[17]);
	fec_mii_read(0, 0x00, 0x00000012, &status0[18]);
	fec_mii_read(0, 0x00, 0x00000013, &status0[19]);
	fec_mii_read(0, 0x00, 0x00000018, &status0[24]);
	fec_mii_read(0, 0x00, 0x00000019, &status0[25]);
	fec_mii_read(0, 0x00, 0x0000001B, &status0[27]);
	fec_mii_read(0, 0x00, 0x0000001C, &status0[28]);
	fec_mii_read(0, 0x00, 0x0000001E, &status0[30]);
	fec_mii_read(0, 0x01, 0x00000000, &status1[0]);
	fec_mii_read(0, 0x01, 0x00000001, &status1[1]);
	fec_mii_read(0, 0x01, 0x00000004, &status1[4]);
	fec_mii_read(0, 0x01, 0x00000005, &status1[5]);
	fec_mii_read(0, 0x01, 0x00000006, &status1[6]);
	fec_mii_read(0, 0x01, 0x00000007, &status1[7]);
	fec_mii_read(0, 0x01, 0x00000008, &status1[8]);
	fec_mii_read(0, 0x01, 0x00000010, &status1[16]);
	fec_mii_read(0, 0x01, 0x00000011, &status1[17]);
	fec_mii_read(0, 0x01, 0x00000012, &status1[18]);
	fec_mii_read(0, 0x01, 0x00000013, &status1[19]);
	fec_mii_read(0, 0x01, 0x00000018, &status1[24]);
	fec_mii_read(0, 0x01, 0x00000019, &status1[25]);
	fec_mii_read(0, 0x01, 0x0000001B, &status1[27]);
	fec_mii_read(0, 0x01, 0x0000001C, &status1[28]);
	fec_mii_read(0, 0x01, 0x0000001E, &status1[30]);
}

/*
 * File:		bcm5222.h
 * Purpose:		Driver for the BCM5222 10/100 Ethernet PHY
 *
 * Notes:
 */

#ifndef _BCM5222_H_
#define _BCM5222_H_

extern int bcm5222_init(uint8, uint8, uint8, uint8);
extern void bcm5222_get_reg(uint16*, uint16*);

/********************************************************************/

/* MII Register Addresses */
#define BCM5222_CTRL				(0x00)
#define BCM5222_STAT				(0x01)
#define BCM5222_PHY_ID1				(0x02)
#define BCM5222_PHY_ID2				(0x03)
#define BCM5222_AN_ADV				(0x04)
#define BCM5222_AN_LINK_PAR			(0x05)
#define BCM5222_AN_EXP				(0x06)
#define BCM5222_AN_NPR				(0x07)
#define BCM5222_LINK_NPA			(0x08)
#define BCM5222_ACSR    			(0x18)

/* Bit definitions and macros for BCM5222_CTRL */
#define BCM5222_CTRL_RESET			(0x8000)
#define BCM5222_CTRL_LOOP			(0x4000)
#define BCM5222_CTRL_SPEED			(0x2000)
#define BCM5222_CTRL_ANE			(0x1000)
#define BCM5222_CTRL_PD				(0x0800)
#define BCM5222_CTRL_ISOLATE		(0x0400)
#define BCM5222_CTRL_RESTART_AN		(0x0200)
#define BCM5222_CTRL_FDX			(0x0100)
#define BCM5222_CTRL_COL_TEST		(0x0080)


/* Bit definitions and macros for BCM5222_STAT */
#define BCM5222_STAT_100BT4         (0x8000)
#define BCM5222_STAT_100BTX_FDX     (0x4000)
#define BCM5222_STAT_100BTX         (0x2000)
#define BCM5222_STAT_10BT_FDX       (0x1000)
#define BCM5222_STAT_10BT           (0x0800)
#define BCM5222_STAT_NO_PREAMBLE    (0x0040)
#define BCM5222_STAT_AN_COMPLETE    (0x0020)
#define BCM5222_STAT_REMOTE_FAULT   (0x0010)
#define BCM5222_STAT_AN_ABILITY     (0x0008)
#define BCM5222_STAT_LINK           (0x0004)
#define BCM5222_STAT_JABBER         (0x0002)
#define BCM5222_STAT_EXTENDED       (0x0001)

/* Bit definitions and macros for BCM5222_AN_ADV */
#define BCM5222_AN_ADV_NEXT_PAGE    (0x8001)
#define BCM5222_AN_ADV_REM_FAULT	(0x2001)
#define BCM5222_AN_ADV_PAUSE		(0x0401)
#define BCM5222_AN_ADV_100BT4		(0x0201)
#define BCM5222_AN_ADV_100BTX_FDX	(0x0101)
#define BCM5222_AN_ADV_100BTX		(0x0081)
#define BCM5222_AN_ADV_10BT_FDX		(0x0041)
#define BCM5222_AN_ADV_10BT		    (0x0021)
#define BCM5222_AN_ADV_802_3		(0x0001)

/* Bit definitions and macros for BCM5222_ACSR */
#define BCM5222_ACSR_100BTX         (0x0002)
#define BCM5222_ACSR_FDX            (0x0001)

/********************************************************************/

#endif /* _BCM5222_H_ */
? bcm5222.c
? bcm5222.h
? fec.patch
Index: SRCFILES
===================================================================
RCS file: /mint/freemint/sys/sockets/xif/fec/SRCFILES,v
retrieving revision 1.1
diff -c -r1.1 SRCFILES
*** SRCFILES	11 Nov 2011 00:15:37 -0000	1.1
--- SRCFILES	15 Feb 2015 08:54:23 -0000
***************
*** 4,9 ****
--- 4,10 ----
  FECDMA_SRCS = \
      dma.c \
      am79c874.c \
+     bcm5222.c \
      fec.c
  
  COMMON_SRCS = \
Index: fec.c
===================================================================
RCS file: /mint/freemint/sys/sockets/xif/fec/fec.c,v
retrieving revision 1.4
diff -c -r1.4 fec.c
*** fec.c	5 Sep 2014 09:28:02 -0000	1.4
--- fec.c	15 Feb 2015 08:54:24 -0000
***************
*** 19,31 ****
  #include "ssystem.h"
  #include "arch/cpu.h"					// for cpushi (cache control)
  #include "util.h"
  
  #include "platform/board.h"
  #include "platform/dma.h"
  
  #include "fec.h"
  #include "am79c874.h"
! 
  
  #ifndef MAX
  #define MAX(a,b) ((a)>(b)?(a):(b))
--- 19,32 ----
  #include "ssystem.h"
  #include "arch/cpu.h"					// for cpushi (cache control)
  #include "util.h"
+ #include "cookie.h"
  
  #include "platform/board.h"
  #include "platform/dma.h"
  
  #include "fec.h"
  #include "am79c874.h"
! #include "bcm5222.h"
  
  #ifndef MAX
  #define MAX(a,b) ((a)>(b)?(a):(b))
***************
*** 48,54 ****
  
  /* macro to read FireTOS parameters (named ct60_rw_parameter within FireTOS): */
  #define firetos_read_parameter(type_param, value )\
! 	(long)trap_14_wwll( 0xc60b, CT60_MODE_READ, type_param, 0 )
  
  /* ------------------------ Type definitions ------------------------------ */
  typedef struct s_fec_if_priv
--- 49,55 ----
  
  /* macro to read FireTOS parameters (named ct60_rw_parameter within FireTOS): */
  #define firetos_read_parameter(type_param, value )\
!     (long)trap_14_wwll( 0xc60b, CT60_MODE_READ, type_param, 0 )
  
  /* ------------------------ Type definitions ------------------------------ */
  typedef struct s_fec_if_priv
***************
*** 76,81 ****
--- 77,83 ----
  static struct netif if_fec[1];
  static fec_if_t fecif_g[1];
  MCD_bufDescFec *sram_unaligned_bds = (MCD_bufDescFec*)(__MBAR+0x13000);
+ static enum machine { MACHINE_FIREBEE, MACHINE_M548X, MACHINE_M5455 } mach;
  
  /* ------------------------ Function declarations ------------------------- */
  long driver_init (void);
***************
*** 108,113 ****
--- 110,139 ----
  static long	fec_ioctl	(struct netif *, short, long);
  static long	fec_config	(struct netif *, struct ifopt *);
  
+ extern uint32 mch_cookie( void );
+ 
+ #define CJAR ((struct cookie **) 0x5a0)
+ /*
+  * machine type detection
+  */
+ uint32 mch_cookie( void )
+ {
+     struct cookie *cookie = *CJAR;
+     uint32 mch = 0;
+ 
+     if (cookie)
+     {
+         while (cookie->tag)
+         {
+             if (cookie->tag == COOKIE__MCH ){
+                 mch = cookie->value;
+             }
+             cookie++;
+         }
+     }
+     return mch;
+ }
+ 
  static unsigned char *board_get_ethaddr(unsigned char *ethaddr);
  
  unsigned char *board_get_ethaddr(unsigned char * ethaddr)
***************
*** 563,569 ****
   */
  static void fec_init( fec_if_t *fec, uint8 mode, uint8 duplex, const uint8 *pa)
  {
! 	uint8 ch = fec->ch;
      /* Enable all the external interface signals */
      if(mode == FEC_MODE_7WIRE)
      {
--- 589,595 ----
   */
  static void fec_init( fec_if_t *fec, uint8 mode, uint8 duplex, const uint8 *pa)
  {
!     uint8 ch = fec->ch;
      /* Enable all the external interface signals */
      if(mode == FEC_MODE_7WIRE)
      {
***************
*** 1139,1165 ****
      {
          if( !strcmp("FEC10.XIF", NETINFO->fname) )
          {
! 			fi->mode |= FEC_IMODE_10MBIT;
          }
  
          if( !strcmp("FECP.XIF", NETINFO->fname) )
          {
! 			fi->mode |= FEC_IMODE_PROMISCUOUS;
          }
  
          if( !strcmp("FECP10.XIF", NETINFO->fname) )
          {
! 			fi->mode |= FEC_IMODE_PROMISCUOUS | FEC_IMODE_10MBIT;
          }
      }
  
      /*
       * Register the interface.
       */
      if_register (&if_fec[0]);
  
!     ksprintf (message, "%s v%d.%d  (%s%d - %02x:%02x:%02x:%02x:%02x:%02x)\r\n",
                FEC_DRIVER_DESC,
                FEC_DRIVER_MAJOR_VERSION,
                FEC_DRIVER_MINOR_VERSION,
                FEC_DEVICE_NAME,
--- 1165,1201 ----
      {
          if( !strcmp("FEC10.XIF", NETINFO->fname) )
          {
!             fi->mode |= FEC_IMODE_10MBIT;
          }
  
          if( !strcmp("FECP.XIF", NETINFO->fname) )
          {
!             fi->mode |= FEC_IMODE_PROMISCUOUS;
          }
  
          if( !strcmp("FECP10.XIF", NETINFO->fname) )
          {
!             fi->mode |= FEC_IMODE_PROMISCUOUS | FEC_IMODE_10MBIT;
          }
      }
  
+ 	if (mch_cookie() == 0x00030000L)	/* Falcon = FireBee */
+ 	{
+ 		mach = MACHINE_FIREBEE;
+ 	}
+ 	else
+ 	{
+ 		mach = MACHINE_M548X;
+ 	}
+ 
      /*
       * Register the interface.
       */
      if_register (&if_fec[0]);
  
!     ksprintf (message, "%s (%s) v%d.%d  (%s%d - %02x:%02x:%02x:%02x:%02x:%02x)\r\n",
                FEC_DRIVER_DESC,
+               mach == MACHINE_FIREBEE ? "Firebee" : "m548x",
                FEC_DRIVER_MAJOR_VERSION,
                FEC_DRIVER_MINOR_VERSION,
                FEC_DEVICE_NAME,
***************
*** 1186,1192 ****
      uint8 duplex = FEC_MII_FULL_DUPLEX;
      uint8 mode = FEC_MODE_MII;
  
!     if( fi->mode & FEC_IMODE_10MBIT )
  	{
  		speed = FEC_MII_10BASE_T;
  		duplex = FEC_MII_HALF_DUPLEX;
--- 1222,1228 ----
      uint8 duplex = FEC_MII_FULL_DUPLEX;
      uint8 mode = FEC_MODE_MII;
  
! 	if( fi->mode & FEC_IMODE_10MBIT )
  	{
  		speed = FEC_MII_10BASE_T;
  		duplex = FEC_MII_HALF_DUPLEX;
***************
*** 1204,1210 ****
          fec_init(fi, mode, duplex, (const uint8 *)nif->hwlocal.adr.bytes);
  
          /* Initialize the PHY interface */
!         if( (mode == FEC_MODE_MII) && (am79c874_init(fi->ch, FEC_PHY(fi->ch), speed, duplex) == 0) )
          {
              /* Flush the network buffers */
              c_conws("am79c874_init failed!\r\n");
--- 1240,1247 ----
          fec_init(fi, mode, duplex, (const uint8 *)nif->hwlocal.adr.bytes);
  
          /* Initialize the PHY interface */
!         if( (mode == FEC_MODE_MII) && mach == MACHINE_FIREBEE ? (am79c874_init(fi->ch, FEC_PHY(fi->ch), speed, duplex) == 0)  :
!                                                                (bcm5222_init(fi->ch, FEC_PHY(fi->ch), speed, duplex) == 0))
          {
              /* Flush the network buffers */
              c_conws("am79c874_init failed!\r\n");